summaryrefslogtreecommitdiff
path: root/parser.c
diff options
context:
space:
mode:
authorCyrill Gorcunov <gorcunov@gmail.com>2009-10-31 10:34:43 +0300
committerCyrill Gorcunov <gorcunov@gmail.com>2009-10-31 10:35:11 +0300
commit41208028ff52d190044ee7532bf14c5aca0f899a (patch)
tree2418e92ba336b3ed09a11eea52adffb646321b47 /parser.c
parent4ea846623aa7633ac010504b013cc1c73a5fc09a (diff)
downloadnasm-41208028ff52d190044ee7532bf14c5aca0f899a.tar.gz
nasm-41208028ff52d190044ee7532bf14c5aca0f899a.tar.bz2
nasm-41208028ff52d190044ee7532bf14c5aca0f899a.zip
BR 2887108: Use overflow_ helper to catch inappropriate imm optimization
We should use overflow_ helpers before check if an immediate operand fit a type range, otherwise we may loose high bits. For example when we assemble the following instruction imul eax,eax,0x10000 with -Ox passed we optimze it up to imm8 though it must be imm32. Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/parser.c b/parser.c
index d0d660b..34fcf47 100644
--- a/parser.c
+++ b/parser.c
@@ -855,11 +855,10 @@ restart_parse:
result->oprs[operand].segment = NO_SEG; /* don't care again */
result->oprs[operand].wrt = NO_SEG; /* still don't care */
+ /* Be optimistic */
if(optimizing >= 0 && !(result->oprs[operand].type & STRICT))
- {
- /* Be optimistic */
result->oprs[operand].type |= SBYTE16 | SBYTE32 | SBYTE64;
- }
+
} else if (is_reloc(value)) { /* it's immediate */
result->oprs[operand].type |= IMMEDIATE;
result->oprs[operand].offset = reloc_value(value);
@@ -874,12 +873,14 @@ restart_parse:
int32_t v32 = (int32_t)v64;
int16_t v16 = (int16_t)v32;
- if (v64 >= -128 && v64 <= 127)
+ if (v64 >= -128 && v64 <= 127)
result->oprs[operand].type |= SBYTE64;
- if (v32 >= -128 && v32 <= 127)
- result->oprs[operand].type |= SBYTE32;
- if (v16 >= -128 && v16 <= 127)
- result->oprs[operand].type |= SBYTE16;
+ if (!overflow_signed(v64, sizeof(v32)))
+ if (v32 >= -128 && v32 <= 127)
+ result->oprs[operand].type |= SBYTE32;
+ if (!overflow_signed(v64, sizeof(v16)))
+ if (v16 >= -128 && v16 <= 127)
+ result->oprs[operand].type |= SBYTE16;
}
}
} else { /* it's a register */