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 <torbjorn.svens...@foss.st.com> --- .../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