diff options
-rw-r--r-- | gas/ChangeLog | 5 | ||||
-rw-r--r-- | gas/config/tc-arm.c | 60 | ||||
-rw-r--r-- | gas/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/arm.exp | 2 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/ldconst.d | 27 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/ldconst.s | 28 |
6 files changed, 106 insertions, 22 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 4e7a11e..e99a1dd 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -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 diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 657317c..504adfe 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -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. */ diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 6052257..4f00f3d 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -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. diff --git a/gas/testsuite/gas/arm/arm.exp b/gas/testsuite/gas/arm/arm.exp index d28048b..12d7b32 100644 --- a/gas/testsuite/gas/arm/arm.exp +++ b/gas/testsuite/gas/arm/arm.exp @@ -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 index 0000000..c7d2837 --- /dev/null +++ b/gas/testsuite/gas/arm/ldconst.d @@ -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 index 0000000..1b6aca9 --- /dev/null +++ b/gas/testsuite/gas/arm/ldconst.s @@ -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 |