* tc-arm.c ((do_ldst): Fix handling an immediate expression pseudo
authorRichard Earnshaw <richard.earnshaw@arm.com>
Fri, 11 Jan 2002 18:00:17 +0000 (18:00 +0000)
committerRichard Earnshaw <richard.earnshaw@arm.com>
Fri, 11 Jan 2002 18:00:17 +0000 (18:00 +0000)
op that can be translated into a mvn instruction.

* gas/arm/ldconst.s gas/arm/ldconst.d: New files.  Test ldr with
immediate pseudo-operations.
* gas/arm/arm.exp: Run it.

gas/ChangeLog
gas/config/tc-arm.c
gas/testsuite/ChangeLog
gas/testsuite/gas/arm/arm.exp
gas/testsuite/gas/arm/ldconst.d [new file with mode: 0644]
gas/testsuite/gas/arm/ldconst.s [new file with mode: 0644]

index 4e7a11e74aa5b7ded65a81f86b72a05f1bb34fe7..e99a1dd6ffbeca114115302fc381ba2eb1db894a 100644 (file)
@@ -1,3 +1,8 @@
+2002-01-11  Richard Earnshaw  <rearnsha@arm.com>
+
+       * tc-arm.c ((do_ldst): Fix handling an immediate expression pseudo
+       op that can be translated into a mvn instruction.
+
 2002-01-11  Steve Ellcey  <sje@cup.hp.com>
 
        * gas/config/tc-ia64.h (MD_FLAGS_DEFAULT): New Macro for
index 657317c2aa058a4314dc4356b5643ace44edf527..504adfe48eedd1eaccae798d6d00b1e9abd59952 100644 (file)
@@ -475,6 +475,7 @@ struct reg_entry
   int          number;
 };
 
+/* Some well known registers that we refer to directly elsewhere.  */
 #define REG_SP  13
 #define REG_LR  14
 #define REG_PC 15
@@ -4888,32 +4889,48 @@ do_ldst (str)
          return;
        }
 
-      if (inst.reloc.exp.X_op == O_constant
-         && (value = validate_immediate (inst.reloc.exp.X_add_number)) != FAIL)
-       {
-         /* This can be done with a mov instruction.  */
-         inst.instruction &= LITERAL_MASK;
-         inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
-         inst.instruction |= (value & 0xfff);
-         end_of_line (str);
-         return;
-       }
-      else
+      if (inst.reloc.exp.X_op == O_constant)
        {
-         /* Insert into literal pool.  */
-         if (add_to_lit_pool () == FAIL)
+         value = validate_immediate (inst.reloc.exp.X_add_number);
+
+         if (value != FAIL)
            {
-             if (!inst.error)
-               inst.error = _("literal pool insertion failed");
+             /* This can be done with a mov instruction.  */
+             inst.instruction &= LITERAL_MASK;
+             inst.instruction |= (INST_IMMEDIATE
+                                  | (OPCODE_MOV << DATA_OP_SHIFT));
+             inst.instruction |= value & 0xfff;
+             end_of_line (str);
              return;
            }
 
-         /* Change the instruction exp to point to the pool.  */
-         inst.reloc.type = BFD_RELOC_ARM_LITERAL;
-         inst.reloc.pc_rel = 1;
-         inst.instruction |= (REG_PC << 16);
-         pre_inc = 1;
+         value = validate_immediate (~inst.reloc.exp.X_add_number);
+
+         if (value != FAIL)
+           {
+             /* This can be done with a mvn instruction.  */
+             inst.instruction &= LITERAL_MASK;
+             inst.instruction |= (INST_IMMEDIATE
+                                  | (OPCODE_MVN << DATA_OP_SHIFT));
+             inst.instruction |= value & 0xfff;
+             end_of_line (str);
+             return;
+           }
        }
+
+      /* Insert into literal pool.  */
+      if (add_to_lit_pool () == FAIL)
+       {
+         if (!inst.error)
+           inst.error = _("literal pool insertion failed");
+         return;
+       }
+
+      /* Change the instruction exp to point to the pool.  */
+      inst.reloc.type = BFD_RELOC_ARM_LITERAL;
+      inst.reloc.pc_rel = 1;
+      inst.instruction |= (REG_PC << 16);
+      pre_inc = 1;
     }
   else
     {
@@ -5841,7 +5858,7 @@ do_fpa_ldmstm (str)
       abort ();
     }
 
-  if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ed/fd format.  */
+  if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format.  */
     {
       int reg;
       int write_back;
@@ -7995,7 +8012,6 @@ md_begin ()
     default:
       mach = bfd_mach_arm_4;
       break;
-
     }
 
   /* Catch special cases.  */
index 605225796d4ef03207693dd754fc7e4d3da2d5e9..4f00f3d5b80ee416c6b7d4939b3890760ad1e9d3 100644 (file)
@@ -1,3 +1,9 @@
+2002-01-11   Richard Earnshaw  <rearnsha@arm.com>
+
+       * gas/arm/ldconst.s gas/arm/ldconst.d: New files.  Test ldr with
+       immediate pseudo-operations.
+       * gas/arm/arm.exp: Run it.
+
 2002-01-10  matthew green  <mrg@redhat.com>
 
        * gas/xstormy16/allinsn.sh (movf, jmp, call, icall): Update.
index d28048bb87c56bd3214bd7c2041153c1139fd4b9..12d7b3290f95a1cd219f2f58068b6fe6caa7319b 100644 (file)
@@ -4,6 +4,8 @@
 if {[istarget *arm*-*-*] || [istarget "xscale-*-*"]} then {
     run_dump_test "inst"
 
+    run_dump_test "ldconst"
+
     gas_test "arm3.s" "-marm3" $stdoptlist "Arm 3 instructions"
 
     gas_test "arm6.s" "-marm6" $stdoptlist "Arm 6 instructions"
diff --git a/gas/testsuite/gas/arm/ldconst.d b/gas/testsuite/gas/arm/ldconst.d
new file mode 100644 (file)
index 0000000..c7d2837
--- /dev/null
@@ -0,0 +1,27 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: ARM ldr with immediate constant
+#as: -marm2 -EL
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0+00 <[^>]*> e3a00000 ?        mov     r0, #0  ; 0x0
+0+04 <[^>]*> e3a004ff ?        mov     r0, #-16777216  ; 0xff000000
+0+08 <[^>]*> e3e00000 ?        mvn     r0, #0  ; 0x0
+0+0c <[^>]*> e51f0004 ?        ldr     r0, \[pc, #-4\] ; 0+10 <[^>]*>
+0+10 <[^>]*> 0fff0000 ?        .*
+0+14 <[^>]*> e3a0e000 ?        mov     lr, #0  ; 0x0
+0+18 <[^>]*> e3a0e8ff ?        mov     lr, #16711680   ; 0xff0000
+0+1c <[^>]*> e3e0e8ff ?        mvn     lr, #16711680   ; 0xff0000
+0+20 <[^>]*> e51fe004 ?        ldr     lr, \[pc, #-4\] ; 0+24 <[^>]*>
+0+24 <[^>]*> 00fff000 ?        .*
+0+28 <[^>]*> 03a00000 ?        moveq   r0, #0  ; 0x0
+0+2c <[^>]*> 03a00cff ?        moveq   r0, #65280      ; 0xff00
+0+30 <[^>]*> 03e00cff ?        mvneq   r0, #65280      ; 0xff00
+0+34 <[^>]*> 051f0004 ?        ldreq   r0, \[pc, #-4\] ; 0+38 <[^>]*>
+0+38 <[^>]*> 000fff00 ?        .*
+0+3c <[^>]*> 43a0b000 ?        movmi   fp, #0  ; 0x0
+0+40 <[^>]*> 43a0b0ff ?        movmi   fp, #255        ; 0xff
+0+44 <[^>]*> 43e0b0ff ?        mvnmi   fp, #255        ; 0xff
+0+48 <[^>]*> 451fb004 ?        ldrmi   fp, \[pc, #-4\] ; 0+4c <[^>]*>
+0+4c <[^>]*> 0000fff0 ?        .*
diff --git a/gas/testsuite/gas/arm/ldconst.s b/gas/testsuite/gas/arm/ldconst.s
new file mode 100644 (file)
index 0000000..1b6aca9
--- /dev/null
@@ -0,0 +1,28 @@
+@       Test file for ARM/GAS -- ldr reg, =... expressions.
+
+.text
+.align
+foo:
+       ldr     r0, =0
+       ldr     r0, =0xff000000
+       ldr     r0, =-1
+       ldr     r0, =0x0fff0000
+       .pool
+
+       ldr     r14, =0
+       ldr     r14, =0x00ff0000
+       ldr     r14, =0xff00ffff
+       ldr     r14, =0x00fff000
+       .pool
+
+       ldreq   r0, =0
+       ldreq   r0, =0x0000ff00
+       ldreq   r0, =0xffff00ff
+       ldreq   r0, =0x000fff00
+       .pool
+
+       ldrmi   r11, =0
+       ldrmi   r11, =0x000000ff
+       ldrmi   r11, =0xffffff00
+       ldrmi   r11, =0x0000fff0
+       .pool