Changes since v1:
- Rewrote the padding instructions in the macro to instead write to volatile
memory. This ensures that every expansion of the base macro is exactly 2
bytes.
If the `GO()` in f3 is removed, the generated assembly would be reduced to:
f3:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
push {lr}
cmp r0, #0
bne .LCB7
bl .L1 @far jump
.LCB7:
movs r2, #1
ldr r3, .L6
str r2, [r3]
...
str r2, [r3]
.L1:
@ sp needed
pop {pc}
Would this assembly be as stable as with the `GO()` in f3? If so, would it be
preferred to generate the simpler assembly in the test?
Ok for trunk as it is or perhaps with the simpler assembly?
--
With the changes in r15-1579-g792f97b44ff, the code used as "padding" in
the test case is optimized way. Prevent this optimization by forcing a
read of the volatile memory.
Also, validate that there is a far jump in the generated assembler.
Without this patch, the generated assembler is reduced to:
f3:
cmp r0, #0
beq .L1
ldr r4, .L6
.L1:
bx lr
.L7:
.align 2
.L6:
.word g_0_1
With the patch, the generated assembler is:
f3:
movs r2, #1
ldr r3, .L6
push {lr}
str r2, [r3]
cmp r0, #0
bne .LCB10
bl .L1 @far jump
.LCB10:
b .L7
.L8:
.align 2
.L6:
.word .LANCHOR0
.L7:
str r2, [r3]
...
str r2, [r3]
.L1:
pop {pc}
gcc/testsuite/ChangeLog:
* gcc.target/arm/thumb1-far-jump-2.c: Write to volatile memmory
in macro to avoid optimization.
Signed-off-by: Torbjörn SVENSSON <[email protected]>
---
.../gcc.target/arm/thumb1-far-jump-2.c | 95 ++++++++++---------
1 file changed, 51 insertions(+), 44 deletions(-)
diff --git a/gcc/testsuite/gcc.target/arm/thumb1-far-jump-2.c
b/gcc/testsuite/gcc.target/arm/thumb1-far-jump-2.c
index 78fcafaaf7d..c79580d660a 100644
--- a/gcc/testsuite/gcc.target/arm/thumb1-far-jump-2.c
+++ b/gcc/testsuite/gcc.target/arm/thumb1-far-jump-2.c
@@ -5,53 +5,60 @@
/* { dg-options "-Os" } */
/* { dg-skip-if "" { ! { arm_thumb1 } } } */
-volatile register int r4 asm ("r4");
+volatile int r4;
+
+#define GO() \
+ r4 = 1;
+
+#define GO8() \
+ GO() \
+ GO() \
+ GO() \
+ GO() \
+ GO() \
+ GO() \
+ GO() \
+ GO()
+
+#define GO32() \
+ GO8() \
+ GO8() \
+ GO8() \
+ GO8()
+
+#define GO128() \
+ GO32() \
+ GO32() \
+ GO32() \
+ GO32()
+
+#define GO512() \
+ GO128() \
+ GO128() \
+ GO128() \
+ GO128()
+
+#define GO1018() \
+ GO512() \
+ GO128() \
+ GO128() \
+ GO128() \
+ GO32() \
+ GO32() \
+ GO32() \
+ GO8() \
+ GO8() \
+ GO8() \
+ GO() \
+ GO()
+
void f3(int i)
{
-#define GO(n) \
- extern volatile int g_##n; \
- r4=(int)&g_##n;
-
-#define GO8(n) \
- GO(n##_0) \
- GO(n##_1) \
- GO(n##_2) \
- GO(n##_3) \
- GO(n##_4) \
- GO(n##_5) \
- GO(n##_6) \
- GO(n##_7)
-
-#define GO64(n) \
- GO8(n##_0) \
- GO8(n##_1) \
- GO8(n##_2) \
- GO8(n##_3) \
- GO8(n##_4) \
- GO8(n##_5) \
- GO8(n##_6) \
- GO8(n##_7) \
-
-#define GO498(n) \
- GO64(n##_0) \
- GO64(n##_1) \
- GO64(n##_2) \
- GO64(n##_3) \
- GO64(n##_4) \
- GO64(n##_5) \
- GO64(n##_6) \
- GO8(n##_0) \
- GO8(n##_1) \
- GO8(n##_2) \
- GO8(n##_3) \
- GO8(n##_4) \
- GO8(n##_5) \
- GO(n##_0) \
- GO(n##_1) \
-
+ GO();
if (i) {
- GO498(0);
+ GO1018();
}
}
-/* { dg-final { scan-assembler "push.*lr" } } */
+/* { dg-final { scan-assembler "\tpush.*lr" } } */
+/* { dg-final { scan-assembler "\tbl\t\\.L\[0-9\]+\t@far jump" } } */
--
2.25.1