gas/
authorJulian Brown <julian@codesourcery.com>
Thu, 14 Sep 2006 13:57:36 +0000 (13:57 +0000)
committerJulian Brown <julian@codesourcery.com>
Thu, 14 Sep 2006 13:57:36 +0000 (13:57 +0000)
* 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.

ChangeLog.csl
gas/config/tc-arm.c

index 232c64c..ff56f36 100644 (file)
@@ -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/
index 82492f9..6feadfd 100644 (file)
@@ -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
 \f
 /* Shorthand macro for instruction encoding functions issuing errors.  */