This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[Patch, ARM] Relax the restrictions on REG_SP under Thumb mode on ARMv8-A
- From: Jiong Wang <jiong dot wang at foss dot arm dot com>
- To: Binutils <binutils at sourceware dot org>
- Date: Fri, 26 May 2017 14:34:34 +0100
- Subject: [Patch, ARM] Relax the restrictions on REG_SP under Thumb mode on ARMv8-A
- Authentication-results: sourceware.org; auth=none
Hi,
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*.
OK for master?
Thanks.
gas/
2017-05-25 Jiong Wang <jiong.wang@arm.com>
* 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.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 08824b4c9b23f66292b4b8768da5ed23030c8252..e7ebed9e3ee3a12186584a77e5953ac9ec9490af 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,
diff --git a/gas/testsuite/gas/arm/ld-sp-warn.l b/gas/testsuite/gas/arm/ld-sp-warn.l
index 48ac57fa6e751282a3e400a8ecdceabd11f2cc7d..6093f3092c16715221a6150e497c1aee2d9232dc 100644
--- a/gas/testsuite/gas/arm/ld-sp-warn.l
+++ b/gas/testsuite/gas/arm/ld-sp-warn.l
@@ -2,4 +2,3 @@
[^:]*:3: Warning: This instruction may be unpredictable if executed on M-profile cores with interrupts enabled.
[^:]*:4: Warning: This instruction may be unpredictable if executed on M-profile cores with interrupts enabled.
[^:]*:7: Error: Thumb does not support register indexing with writeback -- `ldr r1,\[r0,r1\]!'
-[^:]*:8: Error: r13 not allowed here -- `ldrsb sp,\[r2,#16\]!'
diff --git a/gas/testsuite/gas/arm/sp-pc-validations-bad-t-v8a.d b/gas/testsuite/gas/arm/sp-pc-validations-bad-t-v8a.d
new file mode 100644
index 0000000000000000000000000000000000000000..c5996fbee2b3274253ecab248d32c54311428ed0
--- /dev/null
+++ b/gas/testsuite/gas/arm/sp-pc-validations-bad-t-v8a.d
@@ -0,0 +1,4 @@
+# as: -march=armv8-a
+# name: Invalid SP and PC operands test - THUMB (v8a)
+# source: sp-pc-validations-bad-t.s
+# error-output: sp-pc-validations-bad-t-v8a.l
diff --git a/gas/testsuite/gas/arm/sp-pc-validations-bad-t-v8a.l b/gas/testsuite/gas/arm/sp-pc-validations-bad-t-v8a.l
new file mode 100644
index 0000000000000000000000000000000000000000..0da47017e4b0c75169cb3a3953b8d0b308f129ea
--- /dev/null
+++ b/gas/testsuite/gas/arm/sp-pc-validations-bad-t-v8a.l
@@ -0,0 +1,192 @@
+[^:]*: Assembler messages:
+[^:]*:27: IT blocks containing 16-bit Thumb instructions of the following class are deprecated in ARMv8: Short branches, Undefined, SVC, LDM/STM
+[^:]*:27: IT blocks containing more than one conditional instruction are deprecated in ARMv8
+[^:]*:27: Error: branch must be last instruction in IT block -- `ldreq r15,\[r0\]'
+[^:]*:28: IT blocks containing 16-bit Thumb instructions of the following class are deprecated in ARMv8: Short branches, Undefined, SVC, LDM/STM
+[^:]*:28: IT blocks containing more than one conditional instruction are deprecated in ARMv8
+[^:]*:28: Error: branch must be last instruction in IT block -- `ldreq r15,\[r0,#0\]'
+[^:]*:29: IT blocks containing 16-bit Thumb instructions of the following class are deprecated in ARMv8: Short branches, Undefined, SVC, LDM/STM
+[^:]*:29: IT blocks containing more than one conditional instruction are deprecated in ARMv8
+[^:]*:29: Error: branch must be last instruction in IT block -- `ldreq r15,\[sp\]'
+[^:]*:30: IT blocks containing 16-bit Thumb instructions of the following class are deprecated in ARMv8: Short branches, Undefined, SVC, LDM/STM
+[^:]*:30: IT blocks containing more than one conditional instruction are deprecated in ARMv8
+[^:]*:30: Error: branch must be last instruction in IT block -- `ldreq r15,\[sp,#0\]'
+[^:]*:31: IT blocks containing 16-bit Thumb instructions of the following class are deprecated in ARMv8: Short branches, Undefined, SVC, LDM/STM
+[^:]*:31: IT blocks containing more than one conditional instruction are deprecated in ARMv8
+[^:]*:31: Error: branch must be last instruction in IT block -- `ldreq.w r15,\[r0\]'
+[^:]*:32: IT blocks containing 16-bit Thumb instructions of the following class are deprecated in ARMv8: Short branches, Undefined, SVC, LDM/STM
+[^:]*:32: IT blocks containing more than one conditional instruction are deprecated in ARMv8
+[^:]*:32: Error: branch must be last instruction in IT block -- `ldreq.w r15,\[r0,#0\]'
+[^:]*:33: IT blocks containing 16-bit Thumb instructions of the following class are deprecated in ARMv8: Short branches, Undefined, SVC, LDM/STM
+[^:]*:33: IT blocks containing more than one conditional instruction are deprecated in ARMv8
+[^:]*:33: Error: branch must be last instruction in IT block -- `ldreq r15,\[r0,#-4\]'
+[^:]*:34: IT blocks containing 16-bit Thumb instructions of the following class are deprecated in ARMv8: Short branches, Undefined, SVC, LDM/STM
+[^:]*:34: IT blocks containing more than one conditional instruction are deprecated in ARMv8
+[^:]*:34: Error: branch must be last instruction in IT block -- `ldreq r15,\[r0\],#4'
+[^:]*:35: IT blocks containing 16-bit Thumb instructions of the following class are deprecated in ARMv8: Short branches, Undefined, SVC, LDM/STM
+[^:]*:35: IT blocks containing more than one conditional instruction are deprecated in ARMv8
+[^:]*:35: Error: branch must be last instruction in IT block -- `ldreq r15,\[r0,#0\]!'
+[^:]*:38: IT blocks containing 16-bit Thumb instructions of the following class are deprecated in ARMv8: Short branches, Undefined, SVC, LDM/STM
+[^:]*:38: IT blocks containing more than one conditional instruction are deprecated in ARMv8
+[^:]*:38: Error: branch must be last instruction in IT block -- `ldreq r15,label'
+[^:]*:39: IT blocks containing 16-bit Thumb instructions of the following class are deprecated in ARMv8: Short branches, Undefined, SVC, LDM/STM
+[^:]*:39: IT blocks containing more than one conditional instruction are deprecated in ARMv8
+[^:]*:39: Error: branch must be last instruction in IT block -- `ldreq.w r15,label'
+[^:]*:40: IT blocks containing 16-bit Thumb instructions of the following class are deprecated in ARMv8: Short branches, Undefined, SVC, LDM/STM
+[^:]*:40: IT blocks containing more than one conditional instruction are deprecated in ARMv8
+[^:]*:40: Error: branch must be last instruction in IT block -- `ldreq.w r15,\[pc,#-0\]'
+[^:]*:43: IT blocks containing 16-bit Thumb instructions of the following class are deprecated in ARMv8: Short branches, Undefined, SVC, LDM/STM
+[^:]*:43: IT blocks containing more than one conditional instruction are deprecated in ARMv8
+[^:]*:43: Error: branch must be last instruction in IT block -- `ldreq r15,\[r0,r1\]'
+[^:]*:44: IT blocks containing 16-bit Thumb instructions of the following class are deprecated in ARMv8: Short branches, Undefined, SVC, LDM/STM
+[^:]*:44: IT blocks containing more than one conditional instruction are deprecated in ARMv8
+[^:]*:44: Error: branch must be last instruction in IT block -- `ldreq.w r15,\[r0,r1\]'
+[^:]*:45: IT blocks containing 16-bit Thumb instructions of the following class are deprecated in ARMv8: Short branches, Undefined, SVC, LDM/STM
+[^:]*:45: IT blocks containing more than one conditional instruction are deprecated in ARMv8
+[^:]*:45: Error: branch must be last instruction in IT block -- `ldreq.w r15,\[r0,r1,LSL#2\]'
+[^:]*:48: Error: r15 not allowed here -- `ldrb pc,\[r0,#4\]'
+[^:]*:51: Error: r15 not allowed here -- `ldrb.w pc,\[r0,#4\]'
+[^:]*:52: Error: r15 not allowed here -- `ldrb pc,\[r0,#-4\]'
+[^:]*:54: Error: r15 not allowed here -- `ldrb pc,\[r0\],#4'
+[^:]*:56: Error: r15 not allowed here -- `ldrb pc,\[r0,#4\]!'
+[^:]*:60: Error: r15 not allowed here -- `ldrb pc,label'
+[^:]*:61: Error: r15 not allowed here -- `ldrb pc,\[PC,#-0\]'
+[^:]*:66: Error: r15 not allowed here -- `ldrb pc,\[r0,r1\]'
+[^:]*:67: Error: cannot use register index with PC-relative addressing -- `ldrb r0,\[pc,r1\]'
+[^:]*:68: Error: r15 not allowed here -- `ldrb r0,\[r1,pc\]'
+[^:]*:69: Error: r15 not allowed here -- `ldrb.w pc,\[r0,r1,LSL#1\]'
+[^:]*:71: Error: r15 not allowed here -- `ldrb.w r2,\[r0,pc,LSL#2\]'
+[^:]*:75: Error: r15 not allowed here -- `ldrbt pc,\[r0,#4\]'
+[^:]*:79: Error: r15 not allowed here -- `ldrd pc,r0,\[r1\]'
+[^:]*:81: Error: r12 not allowed here -- `ldrd r12,\[r1\]'
+[^:]*:82: Error: r14 not allowed here -- `ldrd r14,\[r1\]'
+[^:]*:83: Error: r15 not allowed here -- `ldrd r0,pc,\[r1\]'
+[^:]*:85: Error: r15 not allowed here -- `ldrd pc,r0,\[r1\],#4'
+[^:]*:87: Error: r15 not allowed here -- `ldrd r0,pc,\[r1\],#4'
+[^:]*:89: Error: r12 not allowed here -- `ldrd r12,\[r1\],#4'
+[^:]*:90: Error: r14 not allowed here -- `ldrd r14,\[r1\],#4'
+[^:]*:91: Error: r15 not allowed here -- `ldrd pc,r0,\[r1,#4\]!'
+[^:]*:93: Error: r15 not allowed here -- `ldrd r0,pc,\[r1,#4\]!'
+[^:]*:95: Error: r12 not allowed here -- `ldrd r12,\[r1,#4\]!'
+[^:]*:96: Error: r14 not allowed here -- `ldrd r14,\[r1,#4\]!'
+[^:]*:99: Error: r15 not allowed here -- `ldrd pc,r0,label'
+[^:]*:101: Error: r15 not allowed here -- `ldrd r0,pc,label'
+[^:]*:103: Error: r15 not allowed here -- `ldrd pc,r0,\[pc,#-0\]'
+[^:]*:105: Error: r15 not allowed here -- `ldrd r0,pc,\[pc,#-0\]'
+[^:]*:111: Error: r15 not allowed here -- `ldrex pc,\[r0\]'
+[^:]*:113: Error: r15 not allowed here -- `ldrex r0,\[pc\]'
+[^:]*:114: Error: r15 not allowed here -- `ldrexb pc,\[r0\]'
+[^:]*:116: Error: r15 not allowed here -- `ldrexb r0,\[pc\]'
+[^:]*:117: Error: r15 not allowed here -- `ldrexd pc,r0,\[r1\]'
+[^:]*:119: Error: r15 not allowed here -- `ldrexd r0,pc,\[r1\]'
+[^:]*:121: Error: r15 not allowed here -- `ldrexd r0,r1,\[pc\]'
+[^:]*:122: Error: r15 not allowed here -- `ldrexh pc,\[r0\]'
+[^:]*:124: Error: r15 not allowed here -- `ldrexh r0,\[pc\]'
+[^:]*:127: Error: r15 not allowed here -- `ldrh pc,\[r0\]'
+[^:]*:128: Error: r15 not allowed here -- `ldrh pc,\[r0,#4\]'
+[^:]*:131: Error: r15 not allowed here -- `ldrh.w pc,\[r0\]'
+[^:]*:132: Error: r15 not allowed here -- `ldrh.w pc,\[r0,#4\]'
+[^:]*:135: Error: r15 not allowed here -- `ldrh pc,\[r0,#-3\]'
+[^:]*:137: Error: r15 not allowed here -- `ldrh pc,\[r0\],#4'
+[^:]*:139: Error: r15 not allowed here -- `ldrh pc,\[r0,#4\]!'
+[^:]*:143: Error: r15 not allowed here -- `ldrh pc,label'
+[^:]*:144: Error: r15 not allowed here -- `ldrh pc,\[pc,#-0\]'
+[^:]*:149: Error: r15 not allowed here -- `ldrh pc,\[r0,r1\]'
+[^:]*:150: Error: cannot use register index with PC-relative addressing -- `ldrh r0,\[pc,r1\]'
+[^:]*:151: Error: r15 not allowed here -- `ldrh r0,\[r1,pc\]'
+[^:]*:152: Error: r15 not allowed here -- `ldrh.w pc,\[r0,r1,LSL#1\]'
+[^:]*:154: Error: r15 not allowed here -- `ldrh.w r2,\[r0,pc,LSL#1\]'
+[^:]*:158: Error: r15 not allowed here -- `ldrht pc,\[r0,#4\]'
+[^:]*:162: Error: r15 not allowed here -- `ldrsb pc,\[r0,#4\]'
+[^:]*:165: Error: r15 not allowed here -- `ldrsb pc,\[r0,#-4\]'
+[^:]*:167: Error: r15 not allowed here -- `ldrsb pc,\[r0\],#4'
+[^:]*:169: Error: r15 not allowed here -- `ldrsb pc,\[r0,#4\]!'
+[^:]*:173: Error: r15 not allowed here -- `ldrsb pc,label'
+[^:]*:174: Error: r15 not allowed here -- `ldrsb pc,\[pc,#-0\]'
+[^:]*:179: Error: r15 not allowed here -- `ldrsb pc,\[r0,r1\]'
+[^:]*:180: Error: cannot use register index with PC-relative addressing -- `ldrsb r0,\[pc,r1\]'
+[^:]*:181: Error: r15 not allowed here -- `ldrsb r0,\[r1,pc\]'
+[^:]*:182: Error: r15 not allowed here -- `ldrsb.w pc,\[r0,r1,LSL#2\]'
+[^:]*:185: Error: r15 not allowed here -- `ldrsb.w r2,\[r0,pc,LSL#2\]'
+[^:]*:190: Error: r15 not allowed here -- `ldrsbt pc,\[r0,#4\]'
+[^:]*:195: Error: r15 not allowed here -- `ldrsh pc,\[r0,#4\]'
+[^:]*:197: Error: r15 not allowed here -- `ldrsh pc,\[r0,#-4\]'
+[^:]*:198: Error: r15 not allowed here -- `ldrsh pc,\[r0\],#4'
+[^:]*:199: Error: r15 not allowed here -- `ldrsh pc,\[r0,#4\]!'
+[^:]*:205: Error: r15 not allowed here -- `ldrsh pc,label'
+[^:]*:210: Error: r15 not allowed here -- `ldrsh pc,\[r0,r1\]'
+[^:]*:211: Error: cannot use register index with PC-relative addressing -- `ldrsh r0,\[pc,r1\]'
+[^:]*:212: Error: r15 not allowed here -- `ldrsh r0,\[r1,pc\]'
+[^:]*:214: Error: r15 not allowed here -- `ldrsh.w pc,\[r0,r1,LSL#3\]'
+[^:]*:217: Error: r15 not allowed here -- `ldrsh.w r0,\[r1,pc,LSL#3\]'
+[^:]*:221: Error: r15 not allowed here -- `ldrsht pc,\[r0,#4\]'
+[^:]*:226: Error: r15 not allowed here -- `ldrt pc,\[r0,#4\]'
+[^:]*:232: Error: r15 not allowed here -- `str pc,\[r0,#4\]'
+[^:]*:233: Error: cannot use register index with PC-relative addressing -- `str.w r0,\[pc,#4\]'
+[^:]*:234: Error: cannot use register index with PC-relative addressing -- `str r0,\[pc,#-4\]'
+[^:]*:235: Error: cannot use post-indexing with PC-relative addressing -- `str r0,\[pc\],#4'
+[^:]*:236: Error: cannot use writeback with PC-relative addressing -- `str r0,\[pc,#4\]!'
+[^:]*:239: Error: cannot use register index with PC-relative addressing -- `str.w r0,\[pc,r1\]'
+[^:]*:240: Error: cannot use register index with PC-relative addressing -- `str.w r0,\[pc,r1,LSL#2\]'
+[^:]*:246: Error: cannot use register index with PC-relative addressing -- `strb.w r0,\[pc,#4\]'
+[^:]*:247: Error: r15 not allowed here -- `strb.w pc,\[r0,#4\]'
+[^:]*:249: Error: cannot use register index with PC-relative addressing -- `strb r0,\[pc,#-4\]'
+[^:]*:250: Error: cannot use post-indexing with PC-relative addressing -- `strb r0,\[pc\],#4'
+[^:]*:251: Error: cannot use writeback with PC-relative addressing -- `strb r0,\[pc,#4\]!'
+[^:]*:252: Error: r15 not allowed here -- `strb pc,\[r0,#-4\]'
+[^:]*:253: Error: r15 not allowed here -- `strb pc,\[r0\],#4'
+[^:]*:254: Error: r15 not allowed here -- `strb pc,\[r0,#4\]!'
+[^:]*:260: Error: cannot use register index with PC-relative addressing -- `strb.w r0,\[pc,r1\]'
+[^:]*:261: Error: cannot use register index with PC-relative addressing -- `strb.w r0,\[pc,r1,LSL#2\]'
+[^:]*:262: Error: r15 not allowed here -- `strb.w pc,\[r0,r1\]'
+[^:]*:263: Error: r15 not allowed here -- `strb.w pc,\[r0,r1,LSL#2\]'
+[^:]*:266: Error: r15 not allowed here -- `strb.w r0,\[r1,pc\]'
+[^:]*:267: Error: r15 not allowed here -- `strb.w r0,\[r1,pc,LSL#2\]'
+[^:]*:272: Error: cannot use register index with PC-relative addressing -- `strbt r0,\[pc,#4\]'
+[^:]*:273: Error: r15 not allowed here -- `strbt pc,\[r0,#4\]'
+[^:]*:277: Error: cannot use register index with PC-relative addressing -- `strd r0,r1,\[pc,#4\]'
+[^:]*:278: Error: cannot use post-indexing with PC-relative addressing -- `strd r0,r1,\[pc\],#4'
+[^:]*:279: Error: cannot use writeback with PC-relative addressing -- `strd r0,r1,\[pc,#4\]!'
+[^:]*:280: Error: r15 not allowed here -- `strd pc,r0,\[r1,#4\]'
+[^:]*:281: Error: r15 not allowed here -- `strd pc,r0,\[r1\],#4'
+[^:]*:282: Error: r15 not allowed here -- `strd pc,r0,\[r1,#4\]!'
+[^:]*:286: Error: r15 not allowed here -- `strd r0,pc,\[r1,#4\]'
+[^:]*:287: Error: r15 not allowed here -- `strd r0,pc,\[r1\],#4'
+[^:]*:288: Error: r15 not allowed here -- `strd r0,pc,\[r1,#4\]!'
+[^:]*:297: Error: r15 not allowed here -- `strex pc,r0,\[r1\]'
+[^:]*:298: Error: r15 not allowed here -- `strex pc,r0,\[r1,#4\]'
+[^:]*:301: Error: r15 not allowed here -- `strex r0,pc,\[r1\]'
+[^:]*:302: Error: r15 not allowed here -- `strex r0,pc,\[r1,#4\]'
+[^:]*:305: Error: r15 not allowed here -- `strex r0,r1,\[pc\]'
+[^:]*:306: Error: r15 not allowed here -- `strex r0,r1,\[pc,#4\]'
+[^:]*:309: Error: r15 not allowed here -- `strexb pc,r0,\[r1\]'
+[^:]*:311: Error: r15 not allowed here -- `strexb r0,pc,\[r1\]'
+[^:]*:313: Error: r15 not allowed here -- `strexb r0,r1,\[pc\]'
+[^:]*:316: Error: r15 not allowed here -- `strexd pc,r0,r1,\[r2\]'
+[^:]*:318: Error: r15 not allowed here -- `strexd r0,pc,r1,\[r2\]'
+[^:]*:320: Error: r15 not allowed here -- `strexd r0,r1,pc,\[r2\]'
+[^:]*:322: Error: r15 not allowed here -- `strexd r0,r1,r2,\[pc\]'
+[^:]*:325: Error: r15 not allowed here -- `strexh pc,r0,\[r1\]'
+[^:]*:327: Error: r15 not allowed here -- `strexh r0,pc,\[r1\]'
+[^:]*:329: Error: r15 not allowed here -- `strexh r0,r1,\[pc\]'
+[^:]*:332: Error: cannot use register index with PC-relative addressing -- `strh.w r0,\[pc\]'
+[^:]*:333: Error: cannot use register index with PC-relative addressing -- `strh.w r0,\[pc,#4\]'
+[^:]*:334: Error: cannot use register index with PC-relative addressing -- `strh r0,\[pc,#-4\]'
+[^:]*:335: Error: cannot use post-indexing with PC-relative addressing -- `strh r0,\[pc\],#4'
+[^:]*:336: Error: cannot use writeback with PC-relative addressing -- `strh r0,\[pc,#4\]!'
+[^:]*:339: Error: cannot use register index with PC-relative addressing -- `strh.w r0,\[pc,r1\]'
+[^:]*:340: Error: cannot use register index with PC-relative addressing -- `strh.w r0,\[pc,r1,LSL#2\]'
+[^:]*:341: Error: r15 not allowed here -- `strh.w pc,\[r0,#4\]'
+[^:]*:342: Error: r15 not allowed here -- `strh.w pc,\[r0\]'
+[^:]*:345: Error: r15 not allowed here -- `strh pc,\[r0,#-4\]'
+[^:]*:346: Error: r15 not allowed here -- `strh pc,\[r0\],#4'
+[^:]*:347: Error: r15 not allowed here -- `strh pc,\[r0,#4\]!'
+[^:]*:351: Error: r15 not allowed here -- `strh.w pc,\[r0,r1\]'
+[^:]*:353: Error: r15 not allowed here -- `strh.w r0,\[r1,pc\]'
+[^:]*:355: Error: r15 not allowed here -- `strh.w pc,\[r0,r1,LSL#2\]'
+[^:]*:357: Error: r15 not allowed here -- `strh.w r0,\[r1,pc,LSL#2\]'
+[^:]*:361: Error: cannot use register index with PC-relative addressing -- `strht r0,\[pc,#4\]'
+[^:]*:362: Error: r15 not allowed here -- `strht pc,\[r0,#4\]'
+[^:]*:363: Error: cannot use register index with PC-relative addressing -- `strht sp,\[pc,#4\]'
+[^:]*:366: Error: cannot use register index with PC-relative addressing -- `strt r0,\[pc,#4\]'
+[^:]*:367: Error: r15 not allowed here -- `strt pc,\[r0,#4\]'
diff --git a/gas/testsuite/gas/arm/sp-pc-validations-bad-t.d b/gas/testsuite/gas/arm/sp-pc-validations-bad-t.d
index 8579f43aeecba69ea72a47879824dd2b722f0090..7c84944bfb922c0a773be1bfdd14a7be9d792dc8 100644
--- a/gas/testsuite/gas/arm/sp-pc-validations-bad-t.d
+++ b/gas/testsuite/gas/arm/sp-pc-validations-bad-t.d
@@ -1,2 +1,3 @@
-# name: Invalid SP and PC operands test - THUMB
+# name: Invalid SP and PC operands test - THUMB (v7a)
+# as: -march=armv7-a
# error-output: sp-pc-validations-bad-t.l
diff --git a/gas/testsuite/gas/arm/sp-pc-validations-bad-t.s b/gas/testsuite/gas/arm/sp-pc-validations-bad-t.s
index 3da0861079232f7282ceded256ceaf611d3630d7..8ea4766b337457b708aee500c62c1f9f8b0c9d99 100644
--- a/gas/testsuite/gas/arm/sp-pc-validations-bad-t.s
+++ b/gas/testsuite/gas/arm/sp-pc-validations-bad-t.s
@@ -1,5 +1,5 @@
.syntax unified
-.arch armv7-a
+@ Enable Thumb mode
.thumb
.macro it_test opcode operands:vararg
itt eq
diff --git a/gas/testsuite/gas/arm/sp-usage-thumb2-relax-on-v7.d b/gas/testsuite/gas/arm/sp-usage-thumb2-relax-on-v7.d
new file mode 100644
index 0000000000000000000000000000000000000000..0707f0e25d16ad2356b8a7dc6502c909765a8b8f
--- /dev/null
+++ b/gas/testsuite/gas/arm/sp-usage-thumb2-relax-on-v7.d
@@ -0,0 +1,4 @@
+#as: -march=armv7-a
+#name: Invalid SP operands test - THUMB (v7a)
+#source: sp-usage-thumb2-relax.s
+#error-output: sp-usage-thumb2-relax-on-v7.l
diff --git a/gas/testsuite/gas/arm/sp-usage-thumb2-relax-on-v7.l b/gas/testsuite/gas/arm/sp-usage-thumb2-relax-on-v7.l
new file mode 100644
index 0000000000000000000000000000000000000000..f19274a6370b875e635d56420d3be048db1f038c
--- /dev/null
+++ b/gas/testsuite/gas/arm/sp-usage-thumb2-relax-on-v7.l
@@ -0,0 +1,17 @@
+[^:]*: Assembler messages:
+[^:]*:25: Error: r13 not allowed here -- `add.w sp,r7,#1'
+[^:]*:25: Error: r13 not allowed here -- `sub.w sp,r7,#1'
+[^:]*:25: Error: r13 not allowed here -- `addw sp,r7,#1'
+[^:]*:25: Error: r13 not allowed here -- `subw sp,r7,#1'
+[^:]*:26: Error: r13 not allowed here -- `bic r7,sp,r2'
+[^:]*:26: Error: r13 not allowed here -- `sbcs r7,sp,r2'
+[^:]*:26: Error: r13 not allowed here -- `and r7,sp,r2'
+[^:]*:26: Error: r13 not allowed here -- `eor r7,sp,r2'
+[^:]*:27: Error: r13 not allowed here -- `smlabb sp,sp,sp,sp'
+[^:]*:27: Error: r13 not allowed here -- `smlabb r0,sp,r3,r11'
+[^:]*:27: Error: r13 not allowed here -- `smlatb sp,sp,sp,sp'
+[^:]*:27: Error: r13 not allowed here -- `smlatb r0,sp,r3,r11'
+[^:]*:27: Error: r13 not allowed here -- `smlabt sp,sp,sp,sp'
+[^:]*:27: Error: r13 not allowed here -- `smlabt r0,sp,r3,r11'
+[^:]*:27: Error: r13 not allowed here -- `smlabt sp,sp,sp,sp'
+[^:]*:27: Error: r13 not allowed here -- `smlabt r0,sp,r3,r11'
diff --git a/gas/testsuite/gas/arm/sp-usage-thumb2-relax-on-v8.d b/gas/testsuite/gas/arm/sp-usage-thumb2-relax-on-v8.d
new file mode 100644
index 0000000000000000000000000000000000000000..be2bb9e012182db82ec0cc221894a3f903d74c79
--- /dev/null
+++ b/gas/testsuite/gas/arm/sp-usage-thumb2-relax-on-v8.d
@@ -0,0 +1,25 @@
+#as: -march=armv8-a
+#source: sp-usage-thumb2-relax.s
+#objdump: -d
+
+.*: file format .*
+
+Disassembly of section \.text:
+
+.* <.*>:
+.*: f107 0d01 add.w sp, r7, #1
+.*: f1a7 0d01 sub.w sp, r7, #1
+.*: f207 0d01 addw sp, r7, #1
+.*: f2a7 0d01 subw sp, r7, #1
+.*: ea2d 0702 bic.w r7, sp, r2
+.*: eb7d 0702 sbcs.w r7, sp, r2
+.*: ea0d 0702 and.w r7, sp, r2
+.*: ea8d 0702 eor.w r7, sp, r2
+.*: fb1d dd0d smlabb sp, sp, sp, sp
+.*: fb1d b003 smlabb r0, sp, r3, fp
+.*: fb1d dd2d smlatb sp, sp, sp, sp
+.*: fb1d b023 smlatb r0, sp, r3, fp
+.*: fb1d dd1d smlabt sp, sp, sp, sp
+.*: fb1d b013 smlabt r0, sp, r3, fp
+.*: fb1d dd1d smlabt sp, sp, sp, sp
+.*: fb1d b013 smlabt r0, sp, r3, fp
diff --git a/gas/testsuite/gas/arm/sp-usage-thumb2-relax.s b/gas/testsuite/gas/arm/sp-usage-thumb2-relax.s
new file mode 100644
index 0000000000000000000000000000000000000000..99a3bf62bbae9682ad19963057e2dc9e7fe86476
--- /dev/null
+++ b/gas/testsuite/gas/arm/sp-usage-thumb2-relax.s
@@ -0,0 +1,27 @@
+ .macro iter_addsub
+ .irp m, add.w, sub.w, addw, subw
+ \m sp, r7, #1
+ .endr
+ .endm
+
+ .macro iter_arith3
+ .irp m, bic, sbcs, and, eor
+ \m r7, sp, r2
+ .endr
+ .endm
+
+ .macro iter_mla
+ .irp m, smlabb, smlatb, smlabt, smlabt
+ \m sp, sp, sp, sp
+ \m r0, sp, r3, r11
+ .endr
+ .endm
+
+ .syntax unified
+ .text
+ .thumb
+ .global foo
+foo:
+ iter_addsub
+ iter_arith3
+ iter_mla
diff --git a/gas/testsuite/gas/arm/strex-bad-t.d b/gas/testsuite/gas/arm/strex-bad-t.d
index f5ec4c59966a99205b7965c69cd0ea0e154ced3b..3640746b067ae53f4768697178a0a8327b6ea01a 100644
--- a/gas/testsuite/gas/arm/strex-bad-t.d
+++ b/gas/testsuite/gas/arm/strex-bad-t.d
@@ -1,3 +1,4 @@
# name: Bad addressing modes STREXH/STREXB. - THUMB
+# as: -march=armv7-a
# error-output: strex-bad-t.l