diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 88cc61bf932..4e0f040a656 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2017-01-06 Mikael Pettersson + + 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. + 2017-01-06 Edgar E. Iglesias David Holsgrove diff --git a/gcc/config/m68k/linux.h b/gcc/config/m68k/linux.h index 7b3f2677b14..c6e005604d4 100644 --- a/gcc/config/m68k/linux.h +++ b/gcc/config/m68k/linux.h @@ -98,9 +98,13 @@ 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)"; \ 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) diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h index 07566ccc3a0..ba7feb07cbd 100644 --- a/gcc/config/m68k/m68k.h +++ b/gcc/config/m68k/m68k.h @@ -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_68881) \ 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. */ diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md index 65bbd38eb9e..5bf6c92d3d5 100644 --- a/gcc/config/m68k/m68k.md +++ b/gcc/config/m68k/m68k.md @@ -6695,7 +6695,9 @@ { #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 @@ [(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; diff --git a/gcc/config/m68k/m68k.opt b/gcc/config/m68k/m68k.opt index 50329f4c04c..b9835f5e42f 100644 --- a/gcc/config/m68k/m68k.opt +++ b/gcc/config/m68k/m68k.opt @@ -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. diff --git a/gcc/config/m68k/m68kelf.h b/gcc/config/m68k/m68kelf.h index d5da8912b38..fb1a0a4d917 100644 --- a/gcc/config/m68k/m68kelf.h +++ b/gcc/config/m68k/m68kelf.h @@ -58,9 +58,13 @@ 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)"; \ 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) diff --git a/gcc/config/m68k/netbsd-elf.h b/gcc/config/m68k/netbsd-elf.h index 110df48d971..5e2be216140 100644 --- a/gcc/config/m68k/netbsd-elf.h +++ b/gcc/config/m68k/netbsd-elf.h @@ -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) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 83ac1353a40..83a0222ce49 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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 @@ -18476,6 +18476,11 @@ object file that accesses more than 8192 GOT entries. Very few do. 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