Message ID | 20231211125158.2872910-2-mikpelinux@gmail.com |
---|---|
State | New |
Headers | show |
Series | wrong code on m68k with -mlong-jump-table-offsets and -malign-int (PR target/112413) | expand |
On 12/11/23 05:51, Mikael Pettersson wrote: > On m68k the compiler assumes that the PC-relative jump-via-jump-table > instruction and the jump table are adjacent with no padding in between. > > When -mlong-jump-table-offsets is combined with -malign-int, a 2-byte > nop may be inserted before the jump table, causing the jump to add the > fetched offset to the wrong PC base and thus jump to the wrong address. > > Fixed by referencing the jump table via its label. On the test case > in the PR the object code change is (the moveal at 16 is the nop): > > a: 6536 bcss 42 <f+0x42> > c: e588 lsll #2,%d0 > e: 203b 0808 movel %pc@(18 <f+0x18>,%d0:l),%d0 > - 12: 4efb 0802 jmp %pc@(16 <f+0x16>,%d0:l) > + 12: 4efb 0804 jmp %pc@(18 <f+0x18>,%d0:l) > 16: 284c moveal %a4,%a4 > 18: 0000 0020 orib #32,%d0 > 1c: 0000 002c orib #44,%d0 > > Bootstrapped and tested on m68k-linux-gnu, no regressions. > > Note: I don't have commit rights to I would need assistance applying this. > > 2023-12-11 Mikael Pettersson <mikpelinux@gmail.com> > > PR target/112413 > * config/m68k/linux.h (ASM_RETURN_CASE_JUMP): For > TARGET_LONG_JUMP_TABLE_OFFSETS, reference the jump table > via its label. > * config/m68k/m68kelf.h (ASM_RETURN_CASE_JUMP: Likewise. > * config/m68k/netbsd-elf.h (ASM_RETURN_CASE_JUMP): Likewise. THanks. Installed. jeff
diff --git a/gcc/config/m68k/linux.h b/gcc/config/m68k/linux.h index 2e1cb5498b8..37069c4d082 100644 --- a/gcc/config/m68k/linux.h +++ b/gcc/config/m68k/linux.h @@ -102,12 +102,12 @@ along with GCC; see the file COPYING3. If not see if (ADDRESS_REG_P (operands[0])) \ return "jmp %%pc@(2,%0:l)"; \ else if (TARGET_LONG_JUMP_TABLE_OFFSETS) \ - return "jmp %%pc@(2,%0:l)"; \ + return "jmp %%pc@(%l1,%0:l)"; \ else \ return "ext%.l %0\n\tjmp %%pc@(2,%0:l)"; \ } \ else if (TARGET_LONG_JUMP_TABLE_OFFSETS) \ - return "jmp %%pc@(2,%0:l)"; \ + return "jmp %%pc@(%l1,%0:l)"; \ else \ return "jmp %%pc@(2,%0:w)"; \ } while (0) diff --git a/gcc/config/m68k/m68kelf.h b/gcc/config/m68k/m68kelf.h index 01ee724ef2b..f89c9b70455 100644 --- a/gcc/config/m68k/m68kelf.h +++ b/gcc/config/m68k/m68kelf.h @@ -59,12 +59,12 @@ along with GCC; see the file COPYING3. If not see if (ADDRESS_REG_P (operands[0])) \ return "jmp %%pc@(2,%0:l)"; \ else if (TARGET_LONG_JUMP_TABLE_OFFSETS) \ - return "jmp %%pc@(2,%0:l)"; \ + return "jmp %%pc@(%l1,%0:l)"; \ else \ return "ext%.l %0\n\tjmp %%pc@(2,%0:l)"; \ } \ else if (TARGET_LONG_JUMP_TABLE_OFFSETS) \ - return "jmp %%pc@(2,%0:l)"; \ + return "jmp %%pc@(%l1,%0:l)"; \ else \ return "jmp %%pc@(2,%0:w)"; \ } while (0) diff --git a/gcc/config/m68k/netbsd-elf.h b/gcc/config/m68k/netbsd-elf.h index 4d4a6d71cc4..6ba581b7b18 100644 --- a/gcc/config/m68k/netbsd-elf.h +++ b/gcc/config/m68k/netbsd-elf.h @@ -137,12 +137,12 @@ while (0) if (ADDRESS_REG_P (operands[0])) \ return "jmp %%pc@(2,%0:l)"; \ else if (TARGET_LONG_JUMP_TABLE_OFFSETS) \ - return "jmp %%pc@(2,%0:l)"; \ + return "jmp %%pc@(%l1,%0:l)"; \ else \ return "ext%.l %0\n\tjmp %%pc@(2,%0:l)"; \ } \ else if (TARGET_LONG_JUMP_TABLE_OFFSETS) \ - return "jmp %%pc@(2,%0:l)"; \ + return "jmp %%pc@(%l1,%0:l)"; \ else \ return "jmp %%pc@(2,%0:w)"; \ } while (0)