diff options
author | Thomas Preud'homme <thomas.preudhomme@arm.com> | 2017-06-20 11:28:15 +0100 |
---|---|---|
committer | Thomas Preud'homme <thomas.preudhomme@arm.com> | 2017-06-20 11:29:11 +0100 |
commit | c0a558756bcf42dc2554aa778b84bf6e13232819 (patch) | |
tree | 4cfe9440b5c4a6ecbee48dbf9322de2257a55393 | |
parent | 01106f569a3acb935447a2a7b3ee7f6866c7ea6c (diff) | |
download | gdb-c0a558756bcf42dc2554aa778b84bf6e13232819.zip gdb-c0a558756bcf42dc2554aa778b84bf6e13232819.tar.gz gdb-c0a558756bcf42dc2554aa778b84bf6e13232819.tar.bz2 |
[ARM] Fix expansion of ldr pseudo instructionusers/ARM/embedded-binutils-2_28-branch-2017q2
The LDR rX, =cst pseudo-instruction suffers from two issues for loading
integer constants in Thumb mode:
- movs is used if the constant and register can be encoded using that
instruction which leads to unexpected behavior due to its flag-setting
behavior
- mov.w, movw and mvn are used for r13 (sp) and r15 (pc) but these
encoding are marked as UNPREDICTABLE
This patch fixes those issues and update testing accordingly.
2017-06-20 Thomas Preud'homme <thomas.preudhomme@arm.com>
Backport from mainline
2017-04-24 Thomas Preud'homme <thomas.preudhomme@arm.com>
gas/
* config/tc-arm.c (move_or_literal_pool): Remove code generating MOVS.
Forbid MOV.W and MOVW if destination is SP or PC.
* testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.s: Explain
expectation of LDR not generating a MOVS for low registers and small
constants. Add tests of MOVW generation.
* testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.d: Update
expected disassembly.
-rw-r--r-- | gas/ChangeLog | 13 | ||||
-rw-r--r-- | gas/config/tc-arm.c | 14 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.d | 24 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.s | 16 |
4 files changed, 43 insertions, 24 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index e752375..93f7c63 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,6 +1,19 @@ 2017-06-20 Thomas Preud'homme <thomas.preudhomme@arm.com> Backport from mainline + 2017-04-24 Thomas Preud'homme <thomas.preudhomme@arm.com> + + * config/tc-arm.c (move_or_literal_pool): Remove code generating MOVS. + Forbid MOV.W and MOVW if destination is SP or PC. + * testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.s: Explain + expectation of LDR not generating a MOVS for low registers and small + constants. Add tests of MOVW generation. + * testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.d: Update + expected disassembly. + +2017-06-20 Thomas Preud'homme <thomas.preudhomme@arm.com> + + Backport from mainline 2017-05-08 Thomas Preud'homme <thomas.preudhomme@arm.com> * testsuite/ld-arm/arm-elf.exp diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 60bda51..0820b96 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -7955,17 +7955,13 @@ move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3) { if (thumb_p) { - /* This can be encoded only for a low register. */ - if ((v & ~0xFF) == 0 && (inst.operands[i].reg < 8)) - { - /* 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; - } + /* LDR should not use lead in a flag-setting instruction being + chosen so we do not check whether movs can be used. */ - if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2) + if ((ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2) || ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m)) + && inst.operands[i].reg != 13 + && inst.operands[i].reg != 15) { /* Check if on thumb2 it can be done with a mov.w, mvn or movw instruction. */ diff --git a/gas/testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.d b/gas/testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.d index 55b5f17..7afc135 100644 --- a/gas/testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.d +++ b/gas/testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.d @@ -6,19 +6,23 @@ .*: +file format .*arm.* Disassembly of section \.text: -0[0-9a-f]+ <[^>]+> 2000[[:space:]]+movs[[:space:]]+r0, #0.* -0[0-9a-f]+ <[^>]+> 2108[[:space:]]+movs[[:space:]]+r1, #8.* -0[0-9a-f]+ <[^>]+> 2251[[:space:]]+movs[[:space:]]+r2, #81.* -0[0-9a-f]+ <[^>]+> 231f[[:space:]]+movs[[:space:]]+r3, #31.* -0[0-9a-f]+ <[^>]+> 242f[[:space:]]+movs[[:space:]]+r4, #47.* -0[0-9a-f]+ <[^>]+> 253f[[:space:]]+movs[[:space:]]+r5, #63.* -0[0-9a-f]+ <[^>]+> 2680[[:space:]]+movs[[:space:]]+r6, #128.* -0[0-9a-f]+ <[^>]+> 27ff[[:space:]]+movs[[:space:]]+r7, #255.* +0[0-9a-f]+ <[^>]+> f04f 0000[[:space:]]+mov\.w[[:space:]]+r0, #0.* +0[0-9a-f]+ <[^>]+> f04f 0108[[:space:]]+mov\.w[[:space:]]+r1, #8.* +0[0-9a-f]+ <[^>]+> f04f 0251[[:space:]]+mov\.w[[:space:]]+r2, #81.* +0[0-9a-f]+ <[^>]+> f04f 031f[[:space:]]+mov\.w[[:space:]]+r3, #31.* +0[0-9a-f]+ <[^>]+> f04f 042f[[:space:]]+mov\.w[[:space:]]+r4, #47.* +0[0-9a-f]+ <[^>]+> f04f 053f[[:space:]]+mov\.w[[:space:]]+r5, #63.* +0[0-9a-f]+ <[^>]+> f04f 0680[[:space:]]+mov\.w[[:space:]]+r6, #128.* +0[0-9a-f]+ <[^>]+> f04f 07ff[[:space:]]+mov\.w[[:space:]]+r7, #255.* 0[0-9a-f]+ <[^>]+> f04f 0800[[:space:]]+mov\.w[[:space:]]+r8, #0.* 0[0-9a-f]+ <[^>]+> f04f 0908[[:space:]]+mov\.w[[:space:]]+r9, #8.* 0[0-9a-f]+ <[^>]+> f04f 0a51[[:space:]]+mov\.w[[:space:]]+sl, #81.* 0[0-9a-f]+ <[^>]+> f04f 0b1f[[:space:]]+mov\.w[[:space:]]+fp, #31.* 0[0-9a-f]+ <[^>]+> f04f 0c2f[[:space:]]+mov\.w[[:space:]]+ip, #47.* -0[0-9a-f]+ <[^>]+> f04f 0d3f[[:space:]]+mov\.w[[:space:]]+sp, #63.* 0[0-9a-f]+ <[^>]+> f04f 0e80[[:space:]]+mov\.w[[:space:]]+lr, #128.* -0[0-9a-f]+ <[^>]+> f04f 0fff[[:space:]]+mov\.w[[:space:]]+pc, #255.* +0[0-9a-f]+ <[^>]+> f64f 78ff[[:space:]]+movw[[:space:]]+r8, #65535.* +0[0-9a-f]+ <[^>]+> f24f 09f0[[:space:]]+movw[[:space:]]+r9, #61680.* +0[0-9a-f]+ <[^>]+> f8df d004[[:space:]]+ldr\.w[[:space:]]+sp, \[pc, #4\].* +0[0-9a-f]+ <[^>]+> f8df f004[[:space:]]+ldr\.w[[:space:]]+pc, \[pc, #4\].* +0[0-9a-f]+ <[^>]+> 0000003f[[:space:]]+.word[[:space:]]+0x0000003f.* +0[0-9a-f]+ <[^>]+> 000000ff[[:space:]]+.word[[:space:]]+0x000000ff.* diff --git a/gas/testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.s b/gas/testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.s index d225410..b473857 100644 --- a/gas/testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.s +++ b/gas/testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.s @@ -2,8 +2,8 @@ .syntax unified .thumb_func thumb2_ldr: - # These can be encoded into movs since constant is small - # And register can be encoded in 3 bits + # These must be encoded into mov.w despite constant and register being + # small enough as ldr should not generate a flag-setting instruction. ldr r0,=0x00 ldr r1,=0x08 ldr r2,=0x51 @@ -12,13 +12,19 @@ thumb2_ldr: ldr r5,=0x3F ldr r6,=0x80 ldr r7,=0xFF - # These shall be encoded into mov.w - # Since register cannot be encoded in 3 bits + # These shall be encoded into mov.w since register cannot be encoded in + # 3 bits ldr r8,=0x00 ldr r9,=0x08 ldr r10,=0x51 ldr r11,=0x1F ldr r12,=0x2F - ldr r13,=0x3F ldr r14,=0x80 + # These shall be encoded into movw since immediate cannot be encoded + # with mov.w + ldr r8,=0xFFFF + ldr r9,=0xF0F0 + # These should be encoded as ldr since mov immediate is unpredictable + # for sp and pc + ldr r13,=0x3F ldr r15,=0xFF |