Jeff Law writes: > On 01/06/2017 09:08 AM, Mikael Pettersson wrote: > > This fixes / works-around the wrong-code PR57583 on M68K, caused by > > overflowing the 16-bit jump table offsets the backend uses. > > > > Ideally the backend should define CASE_VECTOR_SHORTEN_MODE, but that > > AFAIK needs insn length attributes, which the backend only has for CF > > but not for classic M68K. > > > > Instead this patch adds an -mlong-jump-table-offsets option, and adjusts > > the code for emitting and using jump table offsets to handle both short > > and long offsets. As long as the option is not selected, the backend > > behaves exactly as before. > > > > John Paul Adrian Glaubitz tested this patch by compiling "mednafen" > > with it, which previously failed; I also tested earlier versions. > > > > Is this Ok for trunk? > > > > /Mikael > > > > > > gcc/ > > > > 2017-01-06 Mikael Pettersson <mikpeli...@gmail.com> > > > > PR target/57583 > > * config/m68k/m68k.opt (LONG_JUMP_TABLE_OFFSETS): New option. > > * config/m68k/linux.h (ASM_RETURN_CASE_JUMP): Handle > > TARGET_LONG_JUMP_TABLE_OFFSETS. > > * config/m68k/m68kelf.h (ASM_RETURN_CASE_JUMP): Likewise. > > * config/m68k/netbsd-elf.h (ASM_RETURN_CASE_JUMP): Likewise. > > * config/m68k/m68k.h (CASE_VECTOR_MODE): Likewise. > > (ASM_OUTPUT_ADDR_DIFF_ELF): Likewise. > > * config/m68k/m68k.md (tablejump expander): Likewise. > > (*tablejump_pcrel_hi): Renamed from unnamed insn, reject > > TARGET_LONG_JUMP_TABLE_OFFSETS. > > (*tablejump_pcrel_si): New insn, handle TARGET_LONG_JUMP_TABLE_OFFSETS. > > * doc/invoke.texi (M68K options): Add -mlong-jump-table-offsets. > Can't tablejump_pcrel_si be simplified? Isn't the output pattern just: > > #ifdef ASM_RETURN_CASE_JUMP > ASM_RETURN_CASE_JUMP; > #else > return MOTOROLA ? "jmp (2,pc,%0.l)" : "jmp pc@(2,%0:l)"; > #endif > > With that simplification I think this will be fine. > > jeff
Indeed, good catch. Revised patch below. /Mikael gcc/ 2017-01-06 Mikael Pettersson <mikpeli...@gmail.com> PR target/57583 * config/m68k/m68k.opt (LONG_JUMP_TABLE_OFFSETS): New option. * config/m68k/linux.h (ASM_RETURN_CASE_JUMP): Handle TARGET_LONG_JUMP_TABLE_OFFSETS. * config/m68k/m68kelf.h (ASM_RETURN_CASE_JUMP): Likewise. * config/m68k/netbsd-elf.h (ASM_RETURN_CASE_JUMP): Likewise. * config/m68k/m68k.h (CASE_VECTOR_MODE): Likewise. (ASM_OUTPUT_ADDR_DIFF_ELF): Likewise. * config/m68k/m68k.md (tablejump expander): Likewise. (*tablejump_pcrel_hi): Renamed from unnamed insn, reject TARGET_LONG_JUMP_TABLE_OFFSETS. (*tablejump_pcrel_si): New insn, handle TARGET_LONG_JUMP_TABLE_OFFSETS. * doc/invoke.texi (M68K options): Add -mlong-jump-table-offsets. --- gcc-7-20170101/gcc/config/m68k/linux.h.~1~ 2017-01-01 13:07:43.000000000 +0100 +++ gcc-7-20170101/gcc/config/m68k/linux.h 2017-01-06 20:16:25.278132607 +0100 @@ -98,9 +98,13 @@ along with GCC; see the file COPYING3. { \ 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)"; \ else \ return "ext%.l %0\n\tjmp %%pc@(2,%0:l)"; \ } \ + else if (TARGET_LONG_JUMP_TABLE_OFFSETS) \ + return "jmp %%pc@(2,%0:l)"; \ else \ return "jmp %%pc@(2,%0:w)"; \ } while (0) --- gcc-7-20170101/gcc/config/m68k/m68k.h.~1~ 2017-01-01 13:07:43.000000000 +0100 +++ gcc-7-20170101/gcc/config/m68k/m68k.h 2017-01-06 20:16:25.278132607 +0100 @@ -675,7 +675,7 @@ __transfer_from_trampoline () \ /* This address is OK as it stands. */ #define PIC_CASE_VECTOR_ADDRESS(index) index -#define CASE_VECTOR_MODE HImode +#define CASE_VECTOR_MODE (TARGET_LONG_JUMP_TABLE_OFFSETS ? SImode : HImode) #define CASE_VECTOR_PC_RELATIVE 1 #define DEFAULT_SIGNED_CHAR 1 @@ -857,7 +857,11 @@ do { if (cc_prev_status.flags & CC_IN_68 asm_fprintf (FILE, "\t.long %LL%d\n", VALUE) #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ - asm_fprintf (FILE, "\t.word %LL%d-%LL%d\n", VALUE, REL) + asm_fprintf (FILE, \ + TARGET_LONG_JUMP_TABLE_OFFSETS \ + ? "\t.long %LL%d-%LL%d\n" \ + : "\t.word %LL%d-%LL%d\n", \ + VALUE, REL) /* We don't have a way to align to more than a two-byte boundary, so do the best we can and don't complain. */ --- gcc-7-20170101/gcc/config/m68k/m68k.md.~1~ 2017-01-01 13:07:43.000000000 +0100 +++ gcc-7-20170101/gcc/config/m68k/m68k.md 2017-01-06 20:21:32.677641812 +0100 @@ -6695,7 +6695,9 @@ (define_expand "tablejump" { #if CASE_VECTOR_PC_RELATIVE operands[0] = gen_rtx_PLUS (SImode, pc_rtx, - gen_rtx_SIGN_EXTEND (SImode, operands[0])); + TARGET_LONG_JUMP_TABLE_OFFSETS + ? operands[0] + : gen_rtx_SIGN_EXTEND (SImode, operands[0])); #endif }) @@ -6710,12 +6712,26 @@ (define_insn "*tablejump_internal" [(set_attr "type" "jmp")]) ;; Jump to variable address from dispatch table of relative addresses. -(define_insn "" +(define_insn "*tablejump_pcrel_si" + [(set (pc) + (plus:SI (pc) + (match_operand:SI 0 "register_operand" "r"))) + (use (label_ref (match_operand 1 "" "")))] + "TARGET_LONG_JUMP_TABLE_OFFSETS" +{ +#ifdef ASM_RETURN_CASE_JUMP + ASM_RETURN_CASE_JUMP; +#else + return MOTOROLA ? "jmp (2,pc,%0.l)" : "jmp pc@(2,%0:l)"; +#endif +}) + +(define_insn "*tablejump_pcrel_hi" [(set (pc) (plus:SI (pc) (sign_extend:SI (match_operand:HI 0 "register_operand" "r")))) (use (label_ref (match_operand 1 "" "")))] - "" + "!TARGET_LONG_JUMP_TABLE_OFFSETS" { #ifdef ASM_RETURN_CASE_JUMP ASM_RETURN_CASE_JUMP; --- gcc-7-20170101/gcc/config/m68k/m68k.opt.~1~ 2017-01-01 13:07:43.000000000 +0100 +++ gcc-7-20170101/gcc/config/m68k/m68k.opt 2017-01-06 20:16:25.278132607 +0100 @@ -142,6 +142,10 @@ mid-shared-library Target Report Mask(ID_SHARED_LIBRARY) Enable ID based shared library. +mlong-jump-table-offsets +Target Report RejectNegative Mask(LONG_JUMP_TABLE_OFFSETS) +Use 32-bit offsets in jump tables rather than 16-bit offsets. + mnobitfield Target RejectNegative InverseMask(BITFIELD) Do not use the bit-field instructions. --- gcc-7-20170101/gcc/config/m68k/m68kelf.h.~1~ 2017-01-01 13:07:43.000000000 +0100 +++ gcc-7-20170101/gcc/config/m68k/m68kelf.h 2017-01-06 20:16:25.278132607 +0100 @@ -58,9 +58,13 @@ along with GCC; see the file COPYING3. { \ 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)"; \ else \ return "ext%.l %0\n\tjmp %%pc@(2,%0:l)"; \ } \ + else if (TARGET_LONG_JUMP_TABLE_OFFSETS) \ + return "jmp %%pc@(2,%0:l)"; \ else \ return "jmp %%pc@(2,%0:w)"; \ } while (0) --- gcc-7-20170101/gcc/config/m68k/netbsd-elf.h.~1~ 2017-01-01 13:07:43.000000000 +0100 +++ gcc-7-20170101/gcc/config/m68k/netbsd-elf.h 2017-01-06 20:16:25.278132607 +0100 @@ -136,9 +136,13 @@ 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)"; \ else \ return "ext%.l %0\n\tjmp %%pc@(2,%0:l)"; \ } \ + else if (TARGET_LONG_JUMP_TABLE_OFFSETS) \ + return "jmp %%pc@(2,%0:l)"; \ else \ return "jmp %%pc@(2,%0:w)"; \ } while (0) --- gcc-7-20170101/gcc/doc/invoke.texi.~1~ 2017-01-01 13:07:43.000000000 +0100 +++ gcc-7-20170101/gcc/doc/invoke.texi 2017-01-06 20:16:25.278132607 +0100 @@ -837,7 +837,7 @@ Objective-C and Objective-C++ Dialects}. -mno-short -mhard-float -m68881 -msoft-float -mpcrel @gol -malign-int -mstrict-align -msep-data -mno-sep-data @gol -mshared-library-id=n -mid-shared-library -mno-id-shared-library @gol --mxgot -mno-xgot} +-mxgot -mno-xgot -mlong-jump-table-offsets} @emph{MCore Options} @gccoptlist{-mhardlit -mno-hardlit -mdiv -mno-div -mrelax-immediates @gol @@ -18460,6 +18460,11 @@ object file that accesses more than 8192 These options have no effect unless GCC is generating position-independent code. +@item -mlong-jump-table-offsets +@opindex mlong-jump-table-offsets +Use 32-bit offsets in @code{switch} tables. The default is to use +16-bit offsets. + @end table @node MCore Options