summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Brown <julian@codesourcery.com>2006-09-14 13:57:36 +0000
committerJulian Brown <julian@codesourcery.com>2006-09-14 13:57:36 +0000
commit956e7e505afe08771f60299e7a362da1465914e9 (patch)
tree60926b3221fc279f2aa5d78bb7c7010867de8b86
parentbf4fc51e3341e2c77e1d3264b06e326a57fd6ead (diff)
downloadbinutils-gdb-956e7e505afe08771f60299e7a362da1465914e9.tar.gz
gas/
* config/tc-arm.c (parse_immediate): Add BOUNDED parameter, rename to... (parse_immediate_maybe_bounded): This. Only bounds-check if BOUNDED is true. (parse_immediate_bounded): New function, with same arguments and semantics as previous parse_immediate. (parse_immediate_unbounded): New function. Parse an unbounded integer (with sizeof (exp.X_add_number)). (parse_big_immediate): Allow for 64-bit exp.X_add_number when parsing 64-bit immediates. (parse_address_main): Use parse_immediate_bounded not parse_immediate. (parse_ror): Likewise. (parse_operands): Likewise. For Neon immediates, use parse_immediate_unbounded. Add new local po_imm_unb_or_fail macro.
-rw-r--r--ChangeLog.csl19
-rw-r--r--gas/config/tc-arm.c53
2 files changed, 61 insertions, 11 deletions
diff --git a/ChangeLog.csl b/ChangeLog.csl
index 232c64cedec..ff56f361bf1 100644
--- a/ChangeLog.csl
+++ b/ChangeLog.csl
@@ -1,3 +1,22 @@
+2006-09-14 Julian Brown <julian@codesourcery.com>
+
+ gas/
+ * config/tc-arm.c (parse_immediate): Add BOUNDED parameter, rename
+ to...
+ (parse_immediate_maybe_bounded): This. Only bounds-check if BOUNDED
+ is true.
+ (parse_immediate_bounded): New function, with same arguments and
+ semantics as previous parse_immediate.
+ (parse_immediate_unbounded): New function. Parse an unbounded
+ integer (with sizeof (exp.X_add_number)).
+ (parse_big_immediate): Allow for 64-bit exp.X_add_number when
+ parsing 64-bit immediates.
+ (parse_address_main): Use parse_immediate_bounded not
+ parse_immediate.
+ (parse_ror): Likewise.
+ (parse_operands): Likewise. For Neon immediates, use
+ parse_immediate_unbounded. Add new local po_imm_unb_or_fail macro.
+
2006-09-14 Paul Brook <paul@codesourcery.com>
ld/
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 82492f9d36b..6feadfd08f7 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -3946,13 +3946,13 @@ const pseudo_typeS md_pseudo_table[] =
/* Generic immediate-value read function for use in insn parsing.
STR points to the beginning of the immediate (the leading #);
- VAL receives the value; if the value is outside [MIN, MAX]
- issue an error. PREFIX_OPT is true if the immediate prefix is
+ VAL receives the value; if the value is outside [MIN, MAX] and BOUNDED is
+ true, it issue an error. PREFIX_OPT is true if the immediate prefix is
optional. */
static int
-parse_immediate (char **str, int *val, int min, int max,
- bfd_boolean prefix_opt)
+parse_immediate_maybe_bounded (char **str, int *val, bfd_boolean bounded,
+ int min, int max, bfd_boolean prefix_opt)
{
expressionS exp;
my_get_expression (&exp, str, prefix_opt ? GE_OPT_PREFIX : GE_IMM_PREFIX);
@@ -3962,7 +3962,7 @@ parse_immediate (char **str, int *val, int min, int max,
return FAIL;
}
- if (exp.X_add_number < min || exp.X_add_number > max)
+ if (bounded && (exp.X_add_number < min || exp.X_add_number > max))
{
inst.error = _("immediate value out of range");
return FAIL;
@@ -3972,6 +3972,19 @@ parse_immediate (char **str, int *val, int min, int max,
return SUCCESS;
}
+static int
+parse_immediate_bounded (char **str, int *val, int min, int max,
+ bfd_boolean prefix_opt)
+{
+ return parse_immediate_maybe_bounded (str, val, TRUE, min, max, prefix_opt);
+}
+
+static int
+parse_immediate_unbounded (char **str, int *val, bfd_boolean prefix_opt)
+{
+ return parse_immediate_maybe_bounded (str, val, FALSE, 0, 0, prefix_opt);
+}
+
/* Less-generic immediate-value read function with the possibility of loading a
big (64-bit) immediate, as required by Neon VMOV and VMVN immediate
instructions. Puts the result directly in inst.operands[i]. */
@@ -3985,7 +3998,18 @@ parse_big_immediate (char **str, int i)
my_get_expression (&exp, &ptr, GE_OPT_PREFIX_BIG);
if (exp.X_op == O_constant)
- inst.operands[i].imm = exp.X_add_number;
+ {
+ inst.operands[i].imm = exp.X_add_number & 0xffffffff;
+ /* If we're on a 64-bit host, then a 64-bit number can be returned using
+ O_constant. We have to be careful not to break compilation for
+ 32-bit X_add_number, though. */
+ if ((exp.X_add_number & ~0xffffffffl) != 0)
+ {
+ /* X >> 32 is illegal if sizeof (exp.X_add_number) == 4. */
+ inst.operands[i].reg = ((exp.X_add_number >> 16) >> 16) & 0xffffffff;
+ inst.operands[i].regisimm = 1;
+ }
+ }
else if (exp.X_op == O_big
&& LITTLENUM_NUMBER_OF_BITS * exp.X_add_number > 32
&& LITTLENUM_NUMBER_OF_BITS * exp.X_add_number <= 64)
@@ -4703,8 +4727,8 @@ parse_address_main (char **str, int i, int group_relocations,
if (skip_past_char (&p, '{') == SUCCESS)
{
/* [Rn], {expr} - unindexed, with option */
- if (parse_immediate (&p, &inst.operands[i].imm,
- 0, 255, TRUE) == FAIL)
+ if (parse_immediate_bounded (&p, &inst.operands[i].imm,
+ 0, 255, TRUE) == FAIL)
return PARSE_OPERAND_FAIL;
if (skip_past_char (&p, '}') == FAIL)
@@ -4975,7 +4999,7 @@ parse_ror (char **str)
return FAIL;
}
- if (parse_immediate (&s, &rot, 0, 24, FALSE) == FAIL)
+ if (parse_immediate_bounded (&s, &rot, 0, 24, FALSE) == FAIL)
return FAIL;
switch (rot)
@@ -5482,7 +5506,13 @@ parse_operands (char *str, const unsigned char *pattern)
} while (0)
#define po_imm_or_fail(min, max, popt) do { \
- if (parse_immediate (&str, &val, min, max, popt) == FAIL) \
+ if (parse_immediate_bounded (&str, &val, min, max, popt) == FAIL) \
+ goto failure; \
+ inst.operands[i].imm = val; \
+} while (0)
+
+#define po_imm_unb_or_fail(popt) do { \
+ if (parse_immediate_unbounded (&str, &val, popt) == FAIL) \
goto failure; \
inst.operands[i].imm = val; \
} while (0)
@@ -5582,7 +5612,7 @@ parse_operands (char *str, const unsigned char *pattern)
break;
try_imm:
/* Immediate gets verified properly later, so accept any now. */
- po_imm_or_fail (INT_MIN, INT_MAX, TRUE);
+ po_imm_unb_or_fail (TRUE);
}
break;
@@ -6031,6 +6061,7 @@ parse_operands (char *str, const unsigned char *pattern)
#undef po_reg_or_fail
#undef po_reg_or_goto
#undef po_imm_or_fail
+#undef po_imm_unb_or_fail
#undef po_scalar_or_fail
/* Shorthand macro for instruction encoding functions issuing errors. */