GNU Binutils with patches for OS216
Révision | 534455547021f3262fa60d32cabb626af01692a3 (tree) |
---|---|
l'heure | 2017-04-24 22:51:24 |
Auteur | Thomas Preud'homme <thomas.preudhomme@arm....> |
Commiter | Thomas Preud'homme |
[GAS/ARM] Fix expansion of ldr pseudo instruction
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
- mov.w, movw and mvn are used for r13 (sp) and r15 (pc) but these
This patch fixes those issues and update testing accordingly.
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.
@@ -1,3 +1,13 @@ | ||
1 | +2017-04-24 Thomas Preud'homme <thomas.preudhomme@arm.com> | |
2 | + | |
3 | + * config/tc-arm.c (move_or_literal_pool): Remove code generating MOVS. | |
4 | + Forbid MOV.W and MOVW if destination is SP or PC. | |
5 | + * testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.s: Explain | |
6 | + expectation of LDR not generating a MOVS for low registers and small | |
7 | + constants. Add tests of MOVW generation. | |
8 | + * testsuite/gas/arm/thumb2_ldr_immediate_highregs_armv6t2.d: Update | |
9 | + expected disassembly. | |
10 | + | |
1 | 11 | 2017-04-22 Alan Modra <amodra@gmail.com> |
2 | 12 | |
3 | 13 | * testsuite/gas/ppc/vle.s: Format. Add se_rfgi and e_sc. |
@@ -7959,17 +7959,13 @@ move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3) | ||
7959 | 7959 | { |
7960 | 7960 | if (thumb_p) |
7961 | 7961 | { |
7962 | - /* This can be encoded only for a low register. */ | |
7963 | - if ((v & ~0xFF) == 0 && (inst.operands[i].reg < 8)) | |
7964 | - { | |
7965 | - /* This can be done with a mov(1) instruction. */ | |
7966 | - inst.instruction = T_OPCODE_MOV_I8 | (inst.operands[i].reg << 8); | |
7967 | - inst.instruction |= v; | |
7968 | - return TRUE; | |
7969 | - } | |
7962 | + /* LDR should not use lead in a flag-setting instruction being | |
7963 | + chosen so we do not check whether movs can be used. */ | |
7970 | 7964 | |
7971 | - if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2) | |
7965 | + if ((ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2) | |
7972 | 7966 | || ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m)) |
7967 | + && inst.operands[i].reg != 13 | |
7968 | + && inst.operands[i].reg != 15) | |
7973 | 7969 | { |
7974 | 7970 | /* Check if on thumb2 it can be done with a mov.w, mvn or |
7975 | 7971 | movw instruction. */ |
@@ -6,19 +6,23 @@ | ||
6 | 6 | .*: +file format .*arm.* |
7 | 7 | |
8 | 8 | Disassembly of section \.text: |
9 | -0[0-9a-f]+ <[^>]+> 2000[[:space:]]+movs[[:space:]]+r0, #0.* | |
10 | -0[0-9a-f]+ <[^>]+> 2108[[:space:]]+movs[[:space:]]+r1, #8.* | |
11 | -0[0-9a-f]+ <[^>]+> 2251[[:space:]]+movs[[:space:]]+r2, #81.* | |
12 | -0[0-9a-f]+ <[^>]+> 231f[[:space:]]+movs[[:space:]]+r3, #31.* | |
13 | -0[0-9a-f]+ <[^>]+> 242f[[:space:]]+movs[[:space:]]+r4, #47.* | |
14 | -0[0-9a-f]+ <[^>]+> 253f[[:space:]]+movs[[:space:]]+r5, #63.* | |
15 | -0[0-9a-f]+ <[^>]+> 2680[[:space:]]+movs[[:space:]]+r6, #128.* | |
16 | -0[0-9a-f]+ <[^>]+> 27ff[[:space:]]+movs[[:space:]]+r7, #255.* | |
9 | +0[0-9a-f]+ <[^>]+> f04f 0000[[:space:]]+mov\.w[[:space:]]+r0, #0.* | |
10 | +0[0-9a-f]+ <[^>]+> f04f 0108[[:space:]]+mov\.w[[:space:]]+r1, #8.* | |
11 | +0[0-9a-f]+ <[^>]+> f04f 0251[[:space:]]+mov\.w[[:space:]]+r2, #81.* | |
12 | +0[0-9a-f]+ <[^>]+> f04f 031f[[:space:]]+mov\.w[[:space:]]+r3, #31.* | |
13 | +0[0-9a-f]+ <[^>]+> f04f 042f[[:space:]]+mov\.w[[:space:]]+r4, #47.* | |
14 | +0[0-9a-f]+ <[^>]+> f04f 053f[[:space:]]+mov\.w[[:space:]]+r5, #63.* | |
15 | +0[0-9a-f]+ <[^>]+> f04f 0680[[:space:]]+mov\.w[[:space:]]+r6, #128.* | |
16 | +0[0-9a-f]+ <[^>]+> f04f 07ff[[:space:]]+mov\.w[[:space:]]+r7, #255.* | |
17 | 17 | 0[0-9a-f]+ <[^>]+> f04f 0800[[:space:]]+mov\.w[[:space:]]+r8, #0.* |
18 | 18 | 0[0-9a-f]+ <[^>]+> f04f 0908[[:space:]]+mov\.w[[:space:]]+r9, #8.* |
19 | 19 | 0[0-9a-f]+ <[^>]+> f04f 0a51[[:space:]]+mov\.w[[:space:]]+sl, #81.* |
20 | 20 | 0[0-9a-f]+ <[^>]+> f04f 0b1f[[:space:]]+mov\.w[[:space:]]+fp, #31.* |
21 | 21 | 0[0-9a-f]+ <[^>]+> f04f 0c2f[[:space:]]+mov\.w[[:space:]]+ip, #47.* |
22 | -0[0-9a-f]+ <[^>]+> f04f 0d3f[[:space:]]+mov\.w[[:space:]]+sp, #63.* | |
23 | 22 | 0[0-9a-f]+ <[^>]+> f04f 0e80[[:space:]]+mov\.w[[:space:]]+lr, #128.* |
24 | -0[0-9a-f]+ <[^>]+> f04f 0fff[[:space:]]+mov\.w[[:space:]]+pc, #255.* | |
23 | +0[0-9a-f]+ <[^>]+> f64f 78ff[[:space:]]+movw[[:space:]]+r8, #65535.* | |
24 | +0[0-9a-f]+ <[^>]+> f24f 09f0[[:space:]]+movw[[:space:]]+r9, #61680.* | |
25 | +0[0-9a-f]+ <[^>]+> f8df d004[[:space:]]+ldr\.w[[:space:]]+sp, \[pc, #4\].* | |
26 | +0[0-9a-f]+ <[^>]+> f8df f004[[:space:]]+ldr\.w[[:space:]]+pc, \[pc, #4\].* | |
27 | +0[0-9a-f]+ <[^>]+> 0000003f[[:space:]]+.word[[:space:]]+0x0000003f.* | |
28 | +0[0-9a-f]+ <[^>]+> 000000ff[[:space:]]+.word[[:space:]]+0x000000ff.* |
@@ -2,8 +2,8 @@ | ||
2 | 2 | .syntax unified |
3 | 3 | .thumb_func |
4 | 4 | thumb2_ldr: |
5 | - # These can be encoded into movs since constant is small | |
6 | - # And register can be encoded in 3 bits | |
5 | + # These must be encoded into mov.w despite constant and register being | |
6 | + # small enough as ldr should not generate a flag-setting instruction. | |
7 | 7 | ldr r0,=0x00 |
8 | 8 | ldr r1,=0x08 |
9 | 9 | ldr r2,=0x51 |
@@ -12,13 +12,19 @@ thumb2_ldr: | ||
12 | 12 | ldr r5,=0x3F |
13 | 13 | ldr r6,=0x80 |
14 | 14 | ldr r7,=0xFF |
15 | - # These shall be encoded into mov.w | |
16 | - # Since register cannot be encoded in 3 bits | |
15 | + # These shall be encoded into mov.w since register cannot be encoded in | |
16 | + # 3 bits | |
17 | 17 | ldr r8,=0x00 |
18 | 18 | ldr r9,=0x08 |
19 | 19 | ldr r10,=0x51 |
20 | 20 | ldr r11,=0x1F |
21 | 21 | ldr r12,=0x2F |
22 | - ldr r13,=0x3F | |
23 | 22 | ldr r14,=0x80 |
23 | + # These shall be encoded into movw since immediate cannot be encoded | |
24 | + # with mov.w | |
25 | + ldr r8,=0xFFFF | |
26 | + ldr r9,=0xF0F0 | |
27 | + # These should be encoded as ldr since mov immediate is unpredictable | |
28 | + # for sp and pc | |
29 | + ldr r13,=0x3F | |
24 | 30 | ldr r15,=0xFF |