--- gcc/config/m68k.h 2018/04/24 17:51:37 1.1 +++ gcc/config/m68k.h 2018/04/24 18:06:00 1.1.1.4 @@ -81,14 +81,15 @@ extern int target_flags; /* Compile (actually, link) for Sun SKY board. */ #define TARGET_SKY (target_flags & 0200) -/* Optimize for 68040. - The 68040 will execute all 68030 and 68881/2 instrcutions, but some +/* Optimize for 68040, but still allow execution on 68020 + (-m68020-40 or -m68040). + The 68040 will execute all 68030 and 68881/2 instructions, but some of them must be emulated in software by the OS. When TARGET_68040 is turned on, these instructions won't be used. This code will still run on a 68030 and 68881/2. */ -#define TARGET_68040 (target_flags & 0400) +#define TARGET_68040 (target_flags & 01400) -/* Support 68040 fp instructions. */ +/* Use the 68040-only fp instructions (-m68040). */ #define TARGET_68040_ONLY (target_flags & 01000) /* Macro to define tables used to set the flags. @@ -114,10 +115,10 @@ extern int target_flags; { "nofpa", -0100}, \ { "sky", 0200}, \ { "nosky", -0200}, \ - { "68040", 0407}, \ + { "68020-40", 0407}, \ { "68030", -01400}, \ { "68030", 7}, \ - { "68040-only", 01000}, \ + { "68040", 01007}, \ { "", TARGET_DEFAULT}} /* TARGET_DEFAULT is defined in sun*.h and isi.h, etc. */ @@ -158,7 +159,7 @@ extern int target_flags; So let's be consistent. */ #define WORDS_BIG_ENDIAN 1 -/* number of bits in an addressible storage unit */ +/* number of bits in an addressable storage unit */ #define BITS_PER_UNIT 8 /* Width in bits of a "word", which is the contents of a machine register. @@ -189,9 +190,9 @@ extern int target_flags; /* No data type wants to be aligned rounder than this. */ #define BIGGEST_ALIGNMENT 16 -/* Define this if move instructions will actually fail to work +/* Set this nonzero if move instructions will actually fail to work when given unaligned data. */ -#define STRICT_ALIGNMENT +#define STRICT_ALIGNMENT 1 #define SELECT_RTX_SECTION(MODE, X) \ { \ @@ -912,23 +913,26 @@ extern enum reg_class regno_reg_class[]; /* On the 68k, the trampoline looks like this: mov @#.,a0 - jsr @#__trampoline - jsr @#__trampoline + jsr @#___trampoline + jsr @#___trampoline .long STATIC .long FUNCTION The reason for having three jsr insns is so that an entire line of the instruction cache is filled in a predictable way -that will always be the same. */ +that will always be the same. + +We always use the assembler label ___trampoline +regardless of whether the system adds underscores. */ #define TRAMPOLINE_TEMPLATE(FILE) \ { \ ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x207c)); \ ASM_OUTPUT_SHORT (FILE, const0_rtx); \ ASM_OUTPUT_SHORT (FILE, const0_rtx); \ - ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x4ef9)); \ - ASM_OUTPUT_INT (FILE, gen_rtx (SYMBOL_REF, SImode, "__trampoline")); \ - ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x4ef9)); \ - ASM_OUTPUT_INT (FILE, gen_rtx (SYMBOL_REF, SImode, "__trampoline")); \ + ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x4eb9)); \ + ASM_OUTPUT_INT (FILE, gen_rtx (SYMBOL_REF, SImode, "*___trampoline"));\ + ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x4eb9)); \ + ASM_OUTPUT_INT (FILE, gen_rtx (SYMBOL_REF, SImode, "*___trampoline"));\ ASM_OUTPUT_SHORT (FILE, const0_rtx); \ ASM_OUTPUT_SHORT (FILE, const0_rtx); \ ASM_OUTPUT_SHORT (FILE, const0_rtx); \ @@ -969,9 +973,10 @@ void \ __transfer_from_trampoline () \ { \ register char *a0 asm ("%a0"); \ + asm (GLOBAL_ASM_OP " ___trampoline"); \ asm ("___trampoline:"); \ - asm volatile ("mov%.l %0,%@" : : "m" (a0[22])); \ - asm volatile ("mov%.l %1,%0" : "=a" (a0) : "m" (a0[18])); \ + asm volatile ("move%.l %0,%@" : : "m" (a0[22])); \ + asm volatile ("move%.l %1,%0" : "=a" (a0) : "m" (a0[18])); \ asm ("rts":); \ } @@ -1123,8 +1128,15 @@ __transfer_from_trampoline () \ #define GO_IF_NONINDEXED_ADDRESS(X, ADDR) \ { if (INDIRECTABLE_1_ADDRESS_P (X)) goto ADDR; } -#define GO_IF_INDEXABLE_BASE(X, ADDR) \ -{ if (GET_CODE (X) == LABEL_REF) goto ADDR; \ +/* Only labels on dispatch tables are valid for indexing from. */ +#define GO_IF_INDEXABLE_BASE(X, ADDR) \ +{ rtx temp; \ + if (GET_CODE (X) == LABEL_REF \ + && (temp = next_nonnote_insn (XEXP (X, 0))) != 0 \ + && GET_CODE (temp) == JUMP_INSN \ + && (GET_CODE (PATTERN (temp)) == ADDR_VEC \ + || GET_CODE (PATTERN (temp)) == ADDR_DIFF_VEC)) \ + goto ADDR; \ if (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) goto ADDR; } #define GO_IF_INDEXING(X, ADDR) \ @@ -1254,11 +1266,6 @@ __transfer_from_trampoline () \ /* Nonzero if access to memory by bytes is slow and undesirable. */ #define SLOW_BYTE_ACCESS 0 -/* Define if shifts truncate the shift count - which implies one can omit a sign-extension or zero-extension - of a shift count. */ -#define SHIFT_COUNT_TRUNCATED - /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits is done just by pretending it is already truncated. */ #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 @@ -1286,7 +1293,7 @@ __transfer_from_trampoline () \ of a switch statement. If the code is computed here, return it with a return statement. Otherwise, break from the switch. */ -#define CONST_COSTS(RTX,CODE) \ +#define CONST_COSTS(RTX,CODE,OUTER_CODE) \ case CONST_INT: \ /* Constant zero is super cheap due to clr instruction. */ \ if (RTX == const0_rtx) return 0; \ @@ -1294,7 +1301,8 @@ __transfer_from_trampoline () \ if (INTVAL (RTX) >= -128 && INTVAL (RTX) <= 127) return 1; \ /* Constants between -136 and 254 are easily generated */ \ /* by intelligent uses of moveq, add[q], and subq */ \ - if (INTVAL (RTX) >= -136 && INTVAL (RTX) <= 254) return 2; \ + if ((OUTER_CODE) == SET && INTVAL (RTX) >= -136 \ + && INTVAL (RTX) <= 254) return 2; \ case CONST: \ case LABEL_REF: \ case SYMBOL_REF: \ @@ -1308,8 +1316,10 @@ __transfer_from_trampoline () \ work properly in synth_mult on the 68020, relative to an average of the time for add and the time for shift, taking away a little more because sometimes move insns are needed. */ +#define MULL_COST (TARGET_68040 ? 5 : 13) +#define MULW_COST (TARGET_68040 ? 3 : 8) -#define RTX_COSTS(X,CODE) \ +#define RTX_COSTS(X,CODE,OUTER_CODE) \ case PLUS: \ /* An lea costs about three times as much as a simple add. */ \ if (GET_MODE (X) == SImode \ @@ -1328,6 +1338,9 @@ __transfer_from_trampoline () \ case LSHIFTRT: \ /* A shift by a big integer takes an extra instruction. */ \ if (GET_CODE (XEXP (X, 1)) == CONST_INT \ + && (INTVAL (XEXP (X, 1)) == 16)) \ + return COSTS_N_INSNS (2); /* clrw;swap */ \ + if (GET_CODE (XEXP (X, 1)) == CONST_INT \ && !(INTVAL (XEXP (X, 1)) > 0 \ && INTVAL (XEXP (X, 1)) <= 8)) \ return COSTS_N_INSNS (3); /* lsr #i,dn */ \ @@ -1335,11 +1348,21 @@ __transfer_from_trampoline () \ case MULT: \ if (GET_CODE (XEXP (x, 1)) == CONST_INT \ && exact_log2 (INTVAL (XEXP (x, 1))) >= 0) \ - total = 2; \ + { \ + /* A shift by a big integer takes an extra instruction. */ \ + if (GET_CODE (XEXP (X, 1)) == CONST_INT \ + && (INTVAL (XEXP (X, 1)) == (1 << 16))) \ + return COSTS_N_INSNS (2); /* clrw;swap */ \ + if (GET_CODE (XEXP (X, 1)) == CONST_INT \ + && !(INTVAL (XEXP (X, 1)) > 1 \ + && INTVAL (XEXP (X, 1)) <= 256)) \ + return COSTS_N_INSNS (3); /* lsr #i,dn */ \ + break; \ + } \ else if (GET_MODE (X) == QImode || GET_MODE (X) == HImode) \ - return COSTS_N_INSNS (8); /* mul.w */ \ + return COSTS_N_INSNS (MULW_COST); \ else \ - return COSTS_N_INSNS (13); /* mul.l */ \ + return COSTS_N_INSNS (MULL_COST); \ break; \ case DIV: \ case UDIV: \ @@ -1465,20 +1488,23 @@ __transfer_from_trampoline () \ /* This is how to output a command to make the user-level label named NAME defined for reference from other files. */ +#define GLOBAL_ASM_OP ".globl" #define ASM_GLOBALIZE_LABEL(FILE,NAME) \ - do { fputs (".globl ", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE);} while (0) + do { fprintf (FILE, "%s ", GLOBAL_ASM_OP); \ + assemble_name (FILE, NAME); \ + fputs ("\n", FILE);} while (0) /* This is how to output a reference to a user-level label named NAME. `assemble_name' uses this. */ #define ASM_OUTPUT_LABELREF(FILE,NAME) \ - asm_fprintf (FILE, "%U%s", NAME) + asm_fprintf (FILE, "%0U%s", NAME) /* This is how to output an internal numbered label where PREFIX is the class of label and NUM is the number within the class. */ #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ - asm_fprintf (FILE, "%L%s%d:\n", PREFIX, NUM) + asm_fprintf (FILE, "%0L%s%d:\n", PREFIX, NUM) /* This is how to store into the string LABEL the symbol_ref name of an internal numbered label where @@ -1511,7 +1537,7 @@ do { union { float f; long l;} tem; \ fprintf (FILE, "\t.long 0x%x\n", tem.l); \ } while (0) -#endif /* not CROSS_COMPILER */ +#endif /* not CROSS_COMPILE */ /* This is how to output an assembler line defining an `int' constant. */ @@ -1565,11 +1591,11 @@ do { union { float f; long l;} tem; \ that says to advance the location counter to a multiple of 2**LOG bytes. */ +/* 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. */ #define ASM_OUTPUT_ALIGN(FILE,LOG) \ - if ((LOG) == 1) \ - fprintf (FILE, "\t.even\n"); \ - else if ((LOG) != 0) \ - abort (); + if ((LOG) >= 1) \ + fprintf (FILE, "\t.even\n"); #define ASM_OUTPUT_SKIP(FILE,SIZE) \ fprintf (FILE, "\t.skip %u\n", (SIZE)) @@ -1637,7 +1663,7 @@ do { union { float f; long l;} tem; \ sp@, (sp) or (%sp) depending on the style of syntax. '#' for an immediate operand prefix (# in MIT and Motorola syntax but & in SGS syntax). - '!' for the cc register (used in an `and to cc' insn). + '!' for the fpcr register (used in some float-to-fixed conversions). '$' for the letter `s' in an op code, but only on the 68040. '&' for the letter `d' in an op code, but only on the 68040. @@ -1665,7 +1691,7 @@ do { union { float f; long l;} tem; \ u.i[0] = CONST_DOUBLE_HIGH (X); u.i[1] = CONST_DOUBLE_LOW (X); #endif -#ifdef CROSS_COMPILER +#ifdef CROSS_COMPILE #define PRINT_OPERAND_PRINT_FLOAT(CODE, FILE) \ ASM_OUTPUT_FLOAT_OPERAND (FILE, u1.f); #else