Skip to content

Commit

Permalink
[PATCH] wrong code on m68k with -mlong-jump-table-offsets and -malign…
Browse files Browse the repository at this point in the history
…-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 gcc-mirror#32,%d0
   1c:  0000 002c       orib gcc-mirror#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.
  • Loading branch information
mikpe authored and JeffreyALaw committed Dec 11, 2023
1 parent f5fc001 commit eea2517
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 6 deletions.
4 changes: 2 additions & 2 deletions gcc/config/m68k/linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions gcc/config/m68k/m68kelf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions gcc/config/m68k/netbsd-elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit eea2517

Please sign in to comment.