This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GAS/ARM Fix regression of handling "ldr, =" -> mvn



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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]