diff options
author | Jiong Wang <jiong.wang@arm.com> | 2017-05-25 10:40:07 +0100 |
---|---|---|
committer | Jiong Wang <jiong.wang@arm.com> | 2017-06-06 15:02:25 +0100 |
commit | 5c8ed6a4a1d197658086e9175f820227ebffebec (patch) | |
tree | b6ef8e1ea33ff81b4974059472cb9537d999e6d8 /gas/config | |
parent | d24b756188bd63a422671a73e31af718007264ca (diff) | |
download | gdb-5c8ed6a4a1d197658086e9175f820227ebffebec.zip gdb-5c8ed6a4a1d197658086e9175f820227ebffebec.tar.gz gdb-5c8ed6a4a1d197658086e9175f820227ebffebec.tar.bz2 |
[Patch, ARM] Relax the restrictions on REG_SP under Thumb mode on ARMv8-A
For Thumb mode, since ARMv8-A, REG_SP is allowed in most of the places in
Rd/Rt/Rt2 etc while it was disallowed before ARMv8-A, and was rejected through
the "reject_bad_reg" macro and several scattered checks.
This patch only rejects REG_SP in "reject_bad_reg" and several related places
for legacy architectures before ARMv8-A. I have checked those affected instructions
, all of them qualify such relaxations.
Testcases adjusted accordingly.
* ld-sp-warn.d was written without .arch and without -march options passed.
By default it assumes all architectures, so I deleted the REG_SP warning
on ldrsb as it's supported on ARMv8-A. There are actually quite a few
seperate tests on other architectures, for example ld-sp-warn-v7.l etc.,
so there the test for ldrsb on legacy architectures are still covered.
* sp-pc-validations-bad-t has been extended to armv8-a.
* strex-bad-t.d restricted on armv7-a.
* Some new tests for REG_SP used as Rd/Rt etc added in sp-usage-thumb2-relax*.
gas/
* config/tc-arm.c (reject_bad_reg): Allow REG_SP on ARMv8-A.
(parse_operands): Allow REG_SP for OP_oRRnpcsp and OP_RRnpcsp on
ARMv8-A.
(do_co_reg): Allow REG_SP for Rd on ARMv8-A.
(do_t_add_sub): Likewise.
(do_t_mov_cmp): Likewise.
(do_t_tb): Likewise.
* testsuite/gas/arm/ld-sp-warn.l: Delete the warning on REG_SP as Rt for
ldrsb.
* testsuite/gas/arm/sp-pc-validations-bad-t-v8a.d: New test.
* testsuite/gas/arm/sp-pc-validations-bad-t-v8a.l: New test.
* testsuite/gas/arm/sp-pc-validations-bad-t.d: Specifies -march=armv7-a.
* testsuite/gas/arm/sp-pc-validations-bad-t.s: Remove ".arch armv7-a".
* testsuite/gas/arm/sp-usage-thumb2-relax-on-v7.d: New test.
* testsuite/gas/arm/sp-usage-thumb2-relax-on-v7.l: New test.
* testsuite/gas/arm/sp-usage-thumb2-relax-on-v8.d: New test.
* testsuite/gas/arm/sp-usage-thumb2-relax.s: New test.
* testsuite/gas/arm/strex-bad-t.d: Specifies -march=armv7-a.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-arm.c | 49 |
1 files changed, 34 insertions, 15 deletions
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 30c7a6b..8e8fea6 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -7189,8 +7189,14 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb) { if (inst.operands[i].reg == REG_PC) inst.error = BAD_PC; - else if (inst.operands[i].reg == REG_SP) - inst.error = BAD_SP; + else if (inst.operands[i].reg == REG_SP + /* The restriction on Rd/Rt/Rt2 on Thumb mode has been + relaxed since ARMv8-A. */ + && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)) + { + gas_assert (thumb); + inst.error = BAD_SP; + } } break; @@ -7288,14 +7294,23 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb) /* Reject "bad registers" for Thumb-2 instructions. Many Thumb-2 instructions are unpredictable if these registers are used. This - is the BadReg predicate in ARM's Thumb-2 documentation. */ -#define reject_bad_reg(reg) \ - do \ - if (reg == REG_SP || reg == REG_PC) \ - { \ - inst.error = (reg == REG_SP) ? BAD_SP : BAD_PC; \ - return; \ - } \ + is the BadReg predicate in ARM's Thumb-2 documentation. + + Before ARMv8-A, REG_PC and REG_SP were not allowed in quite a few + places, while the restriction on REG_SP was relaxed since ARMv8-A. */ +#define reject_bad_reg(reg) \ + do \ + if (reg == REG_PC) \ + { \ + inst.error = BAD_PC; \ + return; \ + } \ + else if (reg == REG_SP \ + && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)) \ + { \ + inst.error = BAD_SP; \ + return; \ + } \ while (0) /* If REG is R13 (the stack pointer), warn that its use is @@ -8659,7 +8674,7 @@ do_co_reg (void) || inst.instruction == 0xfe000010) /* MCR, MCR2 */ reject_bad_reg (Rd); - else + else if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)) /* MRC, MRC2 */ constraint (Rd == REG_SP, BAD_SP); } @@ -10529,7 +10544,8 @@ do_t_add_sub (void) { int add; - constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP); + if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)) + constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP); add = (inst.instruction == T_MNEM_add || inst.instruction == T_MNEM_adds); @@ -10653,7 +10669,8 @@ do_t_add_sub (void) } constraint (Rd == REG_PC, BAD_PC); - constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP); + if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)) + constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP); constraint (Rs == REG_PC, BAD_PC); reject_bad_reg (Rn); @@ -11906,7 +11923,8 @@ do_t_mov_cmp (void) /* This is mov.w. */ constraint (Rn == REG_PC, BAD_PC); constraint (Rm == REG_PC, BAD_PC); - constraint (Rn == REG_SP && Rm == REG_SP, BAD_SP); + if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)) + constraint (Rn == REG_SP && Rm == REG_SP, BAD_SP); } } else @@ -13127,7 +13145,8 @@ do_t_tb (void) Rn = inst.operands[0].reg; Rm = inst.operands[0].imm; - constraint (Rn == REG_SP, BAD_SP); + if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)) + constraint (Rn == REG_SP, BAD_SP); reject_bad_reg (Rm); constraint (!half && inst.operands[0].shifted, |