aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorThomas Preud'homme <thomas.preudhomme@arm.com>2017-04-24 14:49:48 +0100
committerThomas Preud'homme <thomas.preudhomme@arm.com>2017-04-24 14:51:24 +0100
commit534455547021f3262fa60d32cabb626af01692a3 (patch)
tree56f3cfbe134996bbf893b8b65630b79705313db1 /gas/config
parent8b353c47b70568ab9f0cfd619b7a19e931c2b0c8 (diff)
downloadgdb-534455547021f3262fa60d32cabb626af01692a3.zip
gdb-534455547021f3262fa60d32cabb626af01692a3.tar.gz
gdb-534455547021f3262fa60d32cabb626af01692a3.tar.bz2
[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 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-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.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-arm.c14
1 files changed, 5 insertions, 9 deletions
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 83244b7..7e35c34 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -7959,17 +7959,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. */