This is the mail archive of the binutils-cvs@sourceware.org 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]

[binutils-gdb] Add support for converting LDR Rx, =<imm> to MOV or MVN in Thumb2 mode.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1256987795a7f61826c0e5cc2ee023a579bb0a80

commit 1256987795a7f61826c0e5cc2ee023a579bb0a80
Author: Alessandro Marzocchi <alessandro.marzocchi@gmail.com>
Date:   Wed Jun 17 13:50:52 2015 +0100

    Add support for converting LDR Rx,=<imm> to MOV or MVN in Thumb2 mode.
    
    	PR gas/18499
    gas	* config/tc-arm.c (move_or_literal_pool): Add support for LDR Rx,=
    	to MOV.w or MVN.w for Thumb2.
    
    tests	* gas/arm/thumb2_ldr_immediate_armv6.s: New test case.
    	* gas/arm/thumb2_ldr_immediate_armv6.d: Expected disassembly.
    	* gas/arm/thumb2_ldr_immediate_armv6t2.s: New test case.
    	* gas/arm/thumb2_ldr_immediate_armv6t2.d: Expected disassembly.

Diff:
---
 gas/ChangeLog                                      |  6 ++-
 gas/config/tc-arm.c                                | 58 ++++++++++++++++++++--
 gas/testsuite/ChangeLog                            |  6 +++
 gas/testsuite/gas/arm/thumb2_ldr_immediate_armv6.d | 21 ++++++++
 gas/testsuite/gas/arm/thumb2_ldr_immediate_armv6.s | 12 +++++
 .../gas/arm/thumb2_ldr_immediate_armv6t2.d         | 15 ++++++
 .../gas/arm/thumb2_ldr_immediate_armv6t2.s         | 12 +++++
 7 files changed, 126 insertions(+), 4 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index b751117..b4e7d5f 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -3,7 +3,11 @@
 	PR gas/18500
 	* config/tc-arm.c (is_double_a_single): New function.
 	(double_to_single): New function.
-	(move_or_literal_pool): Add support for	converting VLDR to VMOV.
+	(move_or_literal_pool): Add support for converting VLDR to VMOV.
+
+	PR gas/18499
+	* config/tc-arm.c (move_or_literal_pool): Add support for LDR Rx,=
+	to MOV.w or MVN.w for Thumb2.
 
 2015-06-17  Nicolas Pitre <nico@linaro.org>
 
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 84e95d4..d6cd3ac 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -7869,19 +7869,71 @@ move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
 
       if (!inst.operands[i].issingle)
 	{
-	  if (thumb_p && inst.reloc.exp.X_op == O_constant)
+	  if (thumb_p)
 	    {
-	      if (!unified_syntax && (v & ~0xFF) == 0)
+	      if ((v & ~0xFF) == 0)
 		{
 		  /* This can be done with a mov(1) instruction.  */
 		  inst.instruction = T_OPCODE_MOV_I8 | (inst.operands[i].reg << 8);
 		  inst.instruction |= v;
 		  return TRUE;
 		}
+
+	      if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_arch_t2)
+		  && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
+		{
+		  /* Check if on thumb2 it can be done with a mov.w or mvn.w instruction.  */
+		  unsigned int newimm;
+		  bfd_boolean isNegated;
+
+		  newimm = encode_thumb32_immediate (v);
+		  if (newimm != (unsigned int) FAIL)
+		    isNegated = FALSE;
+		  else
+		    {
+		      newimm = encode_thumb32_immediate (~ v);
+		      if (newimm != (unsigned int) FAIL)
+			isNegated = TRUE;
+		    }
+
+		  if (newimm != (unsigned int) FAIL)
+		    {
+		      inst.instruction = 0xf04f0000 | (inst.operands[i].reg << 8);
+		      inst.instruction |= (isNegated?0x200000:0);
+		      inst.instruction |= (newimm & 0x800) << 15;
+		      inst.instruction |= (newimm & 0x700) << 4;
+		      inst.instruction |= (newimm & 0x0ff);
+		      return TRUE;
+		    }
+		  else if ((v & ~0xFFFF) == 0 || (v & ~0xFFFF0000) == 0)
+		    { 
+		      /* The number may be loaded with a movw/movt instruction.  */
+		      int imm;
+
+		      if ((inst.reloc.exp.X_add_number & ~0xFFFF) == 0)
+			{
+			  inst.instruction= 0xf2400000;
+			  imm = v;
+			}
+		      else
+			{
+			  inst.instruction = 0xf2c00000;
+			  imm = v >> 16;
+			}
+
+		      inst.instruction |= (inst.operands[i].reg << 8);
+		      inst.instruction |= (imm & 0xf000) << 4;
+		      inst.instruction |= (imm & 0x0800) << 15;
+		      inst.instruction |= (imm & 0x0700) << 4;
+		      inst.instruction |= (imm & 0x00ff);
+		      return TRUE;
+		    }
+		}
 	    }
-	  else if (arm_p && inst.reloc.exp.X_op == O_constant)
+	  else if (arm_p)
 	    {
 	      int value = encode_arm_immediate (v);
+
 	      if (value != FAIL)
 		{
 		  /* This can be done with a mov instruction.  */
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index fae6e95..aa03f44 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -8,6 +8,12 @@
 	* gas/arm/vfpv3xd-ldr_immediate.s: New test case.
 	* gas/arm/vfpv3xd-ldr_immediate.d: Expected disassembly.
 
+	PR gas/18499
+	* gas/arm/thumb2_ldr_immediate_armv6.s: New test case.
+	* gas/arm/thumb2_ldr_immediate_armv6.d: Expected disassembly.
+	* gas/arm/thumb2_ldr_immediate_armv6t2.s: New test case.
+	* gas/arm/thumb2_ldr_immediate_armv6t2.d: Expected disassembly.
+
 2015-06-16  Matthew Wahab  <matthew.wahab@arm.com>
 
 	* sysreg.d: Add id_mmfr4_el1, update expected output.
diff --git a/gas/testsuite/gas/arm/thumb2_ldr_immediate_armv6.d b/gas/testsuite/gas/arm/thumb2_ldr_immediate_armv6.d
new file mode 100644
index 0000000..5291077
--- /dev/null
+++ b/gas/testsuite/gas/arm/thumb2_ldr_immediate_armv6.d
@@ -0,0 +1,21 @@
+# name: Ldr immediate on armv6
+# as: -march=armv6
+# objdump: -dr --prefix-addresses --show-raw-insn
+# not-target: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0[0-9a-f]+ <[^>]+> 4902      	ldr	r1, \[pc, #8\].*
+0[0-9a-f]+ <[^>]+> 4903      	ldr	r1, \[pc, #12\]	.*
+0[0-9a-f]+ <[^>]+> 4903      	ldr	r1, \[pc, #12\]	.*
+0[0-9a-f]+ <[^>]+> 4a04      	ldr	r2, \[pc, #16\]	.*
+0[0-9a-f]+ <[^>]+> 4a04      	ldr	r2, \[pc, #16\]	.*
+0[0-9a-f]+ <[^>]+> 4a05      	ldr	r2, \[pc, #20\]	.*
+0[0-9a-f]+ <[^>]+> 72727272 	.*
+0[0-9a-f]+ <[^>]+> 63006300 	.*
+0[0-9a-f]+ <[^>]+> 00510051 	.*
+0[0-9a-f]+ <[^>]+> 00047000 	.*
+0[0-9a-f]+ <[^>]+> ff320000 	.*
+0[0-9a-f]+ <[^>]+> 000013f1 	.*
+
diff --git a/gas/testsuite/gas/arm/thumb2_ldr_immediate_armv6.s b/gas/testsuite/gas/arm/thumb2_ldr_immediate_armv6.s
new file mode 100644
index 0000000..22a5014
--- /dev/null
+++ b/gas/testsuite/gas/arm/thumb2_ldr_immediate_armv6.s
@@ -0,0 +1,12 @@
+	.text
+	.thumb
+	.syntax unified
+	.thumb_func
+thumb2_ldr:
+	ldr r1,=0x72727272
+	ldr r1,=0x63006300
+	ldr r1,=0x00510051
+	ldr r2,=0x00047000
+	ldr r2,=0xFF320000
+	ldr r2,=0x000013F1
+	.pool
diff --git a/gas/testsuite/gas/arm/thumb2_ldr_immediate_armv6t2.d b/gas/testsuite/gas/arm/thumb2_ldr_immediate_armv6t2.d
new file mode 100644
index 0000000..698371a
--- /dev/null
+++ b/gas/testsuite/gas/arm/thumb2_ldr_immediate_armv6t2.d
@@ -0,0 +1,15 @@
+# name: Ldr immediate on armv6
+# as: -march=armv6t2
+# objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0[0-9a-f]+ <[^>]+> f04f 3172 	mov.w	r1, #1920103026	.*
+0[0-9a-f]+ <[^>]+> f04f 2163 	mov.w	r1, #1660969728	.*
+0[0-9a-f]+ <[^>]+> f04f 1151 	mov.w	r1, #5308497	.*
+0[0-9a-f]+ <[^>]+> f44f 228e 	mov.w	r2, #290816	.*
+0[0-9a-f]+ <[^>]+> f6cf 7232 	movt	r2, #65330	.*
+0[0-9a-f]+ <[^>]+> f241 32f1 	movw	r2, #5105	.*
+
+
diff --git a/gas/testsuite/gas/arm/thumb2_ldr_immediate_armv6t2.s b/gas/testsuite/gas/arm/thumb2_ldr_immediate_armv6t2.s
new file mode 100644
index 0000000..22a5014
--- /dev/null
+++ b/gas/testsuite/gas/arm/thumb2_ldr_immediate_armv6t2.s
@@ -0,0 +1,12 @@
+	.text
+	.thumb
+	.syntax unified
+	.thumb_func
+thumb2_ldr:
+	ldr r1,=0x72727272
+	ldr r1,=0x63006300
+	ldr r1,=0x00510051
+	ldr r2,=0x00047000
+	ldr r2,=0xFF320000
+	ldr r2,=0x000013F1
+	.pool


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