aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMikael Pettersson <mikpelinux@gmail.com>2023-12-11 08:40:41 -0700
committerJeff Law <jlaw@ventanamicro.com>2023-12-11 08:41:37 -0700
commiteea25179d8d1406685b8b0995ba841605f895283 (patch)
tree876568be7778ada382b96016b3de35814698429f /gcc
parentf5fc001a84a7dbb942a6252b3162dd38b4aae311 (diff)
downloadgcc-eea25179d8d1406685b8b0995ba841605f895283.zip
gcc-eea25179d8d1406685b8b0995ba841605f895283.tar.gz
gcc-eea25179d8d1406685b8b0995ba841605f895283.tar.bz2
[PATCH] wrong code on m68k with -mlong-jump-table-offsets and -malign-int (PR target/112413)
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. PR target/112413 gcc/ * 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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/m68k/linux.h4
-rw-r--r--gcc/config/m68k/m68kelf.h4
-rw-r--r--gcc/config/m68k/netbsd-elf.h4
3 files changed, 6 insertions, 6 deletions
diff --git a/gcc/config/m68k/linux.h b/gcc/config/m68k/linux.h
index 2e1cb54..37069c4 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 01ee724..f89c9b7 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 4d4a6d7..6ba581b 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)