aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorAlessandro Marzocchi <alessandro.marzocchi@gmail.com>2015-06-17 13:50:52 +0100
committerNick Clifton <nickc@redhat.com>2015-06-17 13:50:52 +0100
commit1256987795a7f61826c0e5cc2ee023a579bb0a80 (patch)
tree77ca039d2d559d8038ed89ca4335e11f3e833adc /gas
parentba592044bc04610d6fa14d0a95931bac303ace37 (diff)
downloadgdb-1256987795a7f61826c0e5cc2ee023a579bb0a80.zip
gdb-1256987795a7f61826c0e5cc2ee023a579bb0a80.tar.gz
gdb-1256987795a7f61826c0e5cc2ee023a579bb0a80.tar.bz2
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.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog6
-rw-r--r--gas/config/tc-arm.c58
-rw-r--r--gas/testsuite/ChangeLog6
-rw-r--r--gas/testsuite/gas/arm/thumb2_ldr_immediate_armv6.d21
-rw-r--r--gas/testsuite/gas/arm/thumb2_ldr_immediate_armv6.s12
-rw-r--r--gas/testsuite/gas/arm/thumb2_ldr_immediate_armv6t2.d15
-rw-r--r--gas/testsuite/gas/arm/thumb2_ldr_immediate_armv6t2.s12
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