This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
GAS/ARM Fix regression of handling "ldr, =" -> mvn
- From: Richard Earnshaw <rearnsha at arm dot com>
- To: binutils at sources dot redhat dot com
- Cc: Richard dot Earnshaw at arm dot com
- Date: Fri, 11 Jan 2002 11:57:07 +0000
- Subject: GAS/ARM Fix regression of handling "ldr, =" -> mvn
- Organization: ARM Ltd.
- Reply-to: Richard dot Earnshaw at arm dot com
It turns out that one of my earlier patches has caused a regression for
handling
ldr Rn, =-1
which should be translated into
mvn Rn, #0
It turns out that there were no tests for this, or similar ldr = patterns.
The patch below fixes this and adds a new regression test so that it
shouldn't happen again.
R.
* tc-arm.c (do_ldst): Fix handling an immediate expression pseudo
op that can be translated into a mvn instruction.
Testsuite:
* gas/arm/ldconst.s gas/arm/ldconst.d: New files. Test ldr with
immediate pseudo-operations.
* gas/arm/arm.exp: Run it.
Index: config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.106
diff -p -r1.106 tc-arm.c
*** tc-arm.c 2002/01/10 11:47:35 1.106
--- tc-arm.c 2002/01/11 11:47:48
*************** struct reg_entry
*** 475,480 ****
--- 475,481 ----
int number;
};
+ /* Some well known registers that we refer to directly elsewhere. */
#define REG_SP 13
#define REG_LR 14
#define REG_PC 15
*************** do_ldst (str)
*** 4888,4919 ****
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
{
! /* 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
{
--- 4889,4936 ----
return;
}
! if (inst.reloc.exp.X_op == O_constant)
{
! value = validate_immediate (inst.reloc.exp.X_add_number);
!
! if (value != 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;
}
! 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
{
*************** do_fpa_ldmstm (str)
*** 5841,5847 ****
abort ();
}
! if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ed/fd format. */
{
int reg;
int write_back;
--- 5858,5864 ----
abort ();
}
! if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format. */
{
int reg;
int write_back;
*************** md_begin ()
*** 7995,8001 ****
default:
mach = bfd_mach_arm_4;
break;
-
}
/* Catch special cases. */
--- 8012,8017 ----
Index: testsuite/gas/arm/arm.exp
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/arm.exp,v
retrieving revision 1.7
diff -p -r1.7 arm.exp
*** arm.exp 2001/10/08 18:59:16 1.7
--- arm.exp 2002/01/11 11:47:49
***************
*** 4,9 ****
--- 4,11 ----
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"
Index: testsuite/gas/arm/ldconst.d
===================================================================
RCS file: ldconst.d
diff -N ldconst.d
*** /dev/null Tue May 5 13:32:27 1998
--- ldconst.d Fri Jan 11 03:47:49 2002
***************
*** 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 ? .*
Index: testsuite/gas/arm/ldconst.s
===================================================================
RCS file: ldconst.s
diff -N ldconst.s
*** /dev/null Tue May 5 13:32:27 1998
--- ldconst.s Fri Jan 11 03:47:49 2002
***************
*** 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