* config/tc-arm.c (BAD_ADDR_MODE): Define.
authorNick Clifton <nickc@redhat.com>
Thu, 10 Nov 2005 09:41:14 +0000 (09:41 +0000)
committerNick Clifton <nickc@redhat.com>
Thu, 10 Nov 2005 09:41:14 +0000 (09:41 +0000)
  (arm_reg_parse_multi): Return NULL rather than FAIL.
  (arm_reg_parse): Fix comment, the function returns FAIL rather than NULL if
    it is unable to parse the register name.
  (do_ldrex): Use BAD_ADDR_MODE.
    Change error message for PC-relative addressing.
  (do_strex): Likewise.
  (do_t_ldrex): Use BAD_ADDR_MODE.
  (do_t_strex): Likewise.
* gas/arm/archv6t2-bad.s: Add tests of badly composed ldrex and strex
    instructions.
* gas/arm/archv6t2-bad.l: Add expected error messages.
* gas/arm/r15-bad.l: Adjust error messages for r15 usage in ldrex and strex
    instructions.

gas/ChangeLog
gas/config/tc-arm.c
gas/testsuite/ChangeLog
gas/testsuite/gas/arm/archv6t2-bad.l
gas/testsuite/gas/arm/archv6t2-bad.s
gas/testsuite/gas/arm/r15-bad.l

index 0e3e699..9103916 100644 (file)
@@ -1,3 +1,15 @@
+2005-11-10  Nick Clifton  <nickc@redhat.com>
+
+       * config/tc-arm.c (BAD_ADDR_MODE): Define.
+       (arm_reg_parse_multi): Return NULL rather than FAIL.
+       (arm_reg_parse): Fix comment, the function returns FAIL rather
+       than NULL if it is unable to parse the register name.
+       (do_ldrex): Use BAD_ADDR_MODE.
+       Change error message for PC-relative addressing.
+       (do_strex): Likewise.
+       (do_t_ldrex): Use BAD_ADDR_MODE.
+       (do_t_strex): Likewise.
+
 2005-11-08   Jean-Jacques Metayer  <jean-jacques.metayer@thomson.net>
 
        * config/tc-sparc.c (isoctal): Fix thinko.
index 9df9e0e..62ebd50 100644 (file)
@@ -502,6 +502,7 @@ struct asm_opcode
 #define BAD_OVERLAP    _("registers may not be the same")
 #define BAD_HIREG      _("lo register required")
 #define BAD_THUMB32    _("instruction not supported in Thumb16 mode")
+#define BAD_ADDR_MODE   _("instruction does not accept this addressing mode");
 
 static struct hash_control *arm_ops_hsh;
 static struct hash_control *arm_cond_hsh;
@@ -843,7 +844,7 @@ arm_reg_parse_multi (char **ccp)
 
 #ifdef REGISTER_PREFIX
   if (*start != REGISTER_PREFIX)
-    return FAIL;
+    return NULL;
   start++;
 #endif
 #ifdef OPTIONAL_REGISTER_PREFIX
@@ -869,7 +870,7 @@ arm_reg_parse_multi (char **ccp)
 }
 
 /* As above, but the register must be of type TYPE, and the return
-   value is the register number or NULL.  */
+   value is the register number or FAIL.  */
 
 static int
 arm_reg_parse (char **ccp, enum arm_reg_type type)
@@ -4825,10 +4826,20 @@ do_ldrex (void)
   constraint (!inst.operands[1].isreg || !inst.operands[1].preind
              || inst.operands[1].postind || inst.operands[1].writeback
              || inst.operands[1].immisreg || inst.operands[1].shifted
-             || inst.operands[1].negative,
-             _("instruction does not accept this addressing mode"));
-
-  constraint (inst.operands[1].reg == REG_PC, BAD_PC);
+             || inst.operands[1].negative
+             /* This can arise if the programmer has written
+                  strex rN, rM, foo
+                or if they have mistakenly used a register name as the last
+                operand,  eg:
+                  strex rN, rM, rX
+                It is very difficult to distinguish between these two cases
+                because "rX" might actually be a label. ie the register
+                name has been occluded by a symbol of the same name. So we
+                just generate a general 'bad addressing mode' type error
+                message and leave it up to the programmer to discover the
+                true cause and fix their mistake.  */
+             || (inst.operands[1].reg == REG_PC),
+             BAD_ADDR_MODE);
 
   constraint (inst.reloc.exp.X_op != O_constant
              || inst.reloc.exp.X_add_number != 0,
@@ -5268,10 +5279,10 @@ do_strex (void)
   constraint (!inst.operands[2].isreg || !inst.operands[2].preind
              || inst.operands[2].postind || inst.operands[2].writeback
              || inst.operands[2].immisreg || inst.operands[2].shifted
-             || inst.operands[2].negative,
-             _("instruction does not accept this addressing mode"));
-
-  constraint (inst.operands[2].reg == REG_PC, BAD_PC);
+             || inst.operands[2].negative
+             /* See comment in do_ldrex().  */
+             || (inst.operands[2].reg == REG_PC),
+             BAD_ADDR_MODE);
 
   constraint (inst.operands[0].reg == inst.operands[1].reg
              || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
@@ -6703,7 +6714,7 @@ do_t_ldrex (void)
              || inst.operands[1].postind || inst.operands[1].writeback
              || inst.operands[1].immisreg || inst.operands[1].shifted
              || inst.operands[1].negative,
-             _("instruction does not accept this addressing mode"));
+             BAD_ADDR_MODE);
 
   inst.instruction |= inst.operands[0].reg << 12;
   inst.instruction |= inst.operands[1].reg << 16;
@@ -7578,7 +7589,7 @@ do_t_strex (void)
              || inst.operands[2].postind || inst.operands[2].writeback
              || inst.operands[2].immisreg || inst.operands[2].shifted
              || inst.operands[2].negative,
-             _("instruction does not accept this addressing mode"));
+             BAD_ADDR_MODE);
 
   inst.instruction |= inst.operands[0].reg << 8;
   inst.instruction |= inst.operands[1].reg << 12;
index 5dfe8b6..d896190 100644 (file)
@@ -1,3 +1,11 @@
+2005-11-10  Nick Clifton  <nickc@redhat.com>
+
+       * gas/arm/archv6t2-bad.s: Add tests of badly composed ldrex and
+       strex instructions.
+       * gas/arm/archv6t2-bad.l: Add expected error messages.
+       * gas/arm/r15-bad.l: Adjust error messages for r15 usage in ldrex
+       and strex instructions.
+
 2005-11-08  Arnold Metselaar  <arnold.metselaar@planet.nl>
 
        * gas/all/cofftag.s: Convert numbers in .type 
index e8da4b8..0f00db3 100644 (file)
@@ -36,3 +36,5 @@
 [^:]*:51: Warning: destination register same as write-back base
 [^:]*:52: Warning: destination register same as write-back base
 [^:]*:53: Warning: source register same as write-back base
+[^:]*:59: Error: instruction does not accept this addressing mode -- `ldrex r0,r2'
+[^:]*:60: Error: instruction does not accept this addressing mode -- `strex r1,r0,r2'
index e568869..af13972 100644 (file)
@@ -51,3 +51,11 @@ x:
        ldrsbt  r0,[r0]
        ldrsht  r0,[r0]
        strht   r0,[r0]
+
+       @ Bug reported by user.  GAS used to issue an error message
+       @ "r15 not allowed here" for these two instructions because
+       @ it thought that the "r2" operand was a PC-relative branch
+       @ to a label called "r2".
+       ldrex   r0, r2
+       strex   r1, r0, r2
+       
\ No newline at end of file
index 0230636..a172e9e 100644 (file)
@@ -30,7 +30,7 @@
 [^:]*:33: Error: r15 not allowed here -- `umaal r1,r2,r3,r15'
 [^:]*:34: Error: r15 not allowed here -- `strex r15,r2,[[]r3[]]'
 [^:]*:35: Error: r15 not allowed here -- `strex r1,r15,[[]r3[]]'
-[^:]*:36: Error: r15 not allowed here -- `strex r1,r2,[[]r15[]]'
+[^:]*:36: Error: instruction does not accept this addressing mode -- `strex r1,r2,[[]r15[]]'
 [^:]*:37: Error: r15 not allowed here -- `ssat r15,#1,r2'
 [^:]*:38: Error: r15 not allowed here -- `ssat r1,#1,r15'
 [^:]*:39: Error: r15 not allowed here -- `ssat16 r15,#1,r2'
@@ -58,7 +58,7 @@
 [^:]*:61: Error: r15 not allowed here -- `pkhtb r1,r15,r3'
 [^:]*:62: Error: r15 not allowed here -- `pkhtb r1,r2,r15'
 [^:]*:63: Error: r15 not allowed here -- `ldrex r15,[[]r2[]]'
-[^:]*:64: Error: r15 not allowed here -- `ldrex r1,[[]r15[]]'
+[^:]*:64: Error: instruction does not accept this addressing mode -- `ldrex r1,[[]r15[]]'
 [^:]*:65: Error: r15 not allowed here -- `swp r15,r2,[[]r3[]]'
 [^:]*:66: Error: r15 not allowed here -- `swp r1,r15,[[]r3[]]'
 [^:]*:67: Error: r15 not allowed here -- `swp r1,r2,[[]r15[]]'