--- gcc/config/m68k/m68k.h 2018/04/24 18:14:35 1.1.1.2 +++ gcc/config/m68k/m68k.h 2018/04/24 18:44:17 1.1.1.5 @@ -1,5 +1,5 @@ /* Definitions of target machine for GNU compiler. Sun 68000/68020 version. - Copyright (C) 1987, 1988, 1993 Free Software Foundation, Inc. + Copyright (C) 1987, 1988, 1993, 1994, 1995 Free Software Foundation, Inc. This file is part of GNU CC. @@ -15,7 +15,8 @@ GNU General Public License for more deta You should have received a copy of the GNU General Public License along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ /* Note that some other tm.h files include this one and then override @@ -142,14 +143,14 @@ extern int target_flags; if (TARGET_FPA) target_flags &= ~2; \ if (! TARGET_68020 && flag_pic == 2) \ error("-fPIC is not currently supported on the 68000 or 68010\n"); \ - SUBTARGET_OVERRIDE_OPTIONS \ + SUBTARGET_OVERRIDE_OPTIONS; \ } #else #define OVERRIDE_OPTIONS \ { \ if (! TARGET_68020 && flag_pic == 2) \ error("-fPIC is not currently supported on the 68000 or 68010\n"); \ - SUBTARGET_OVERRIDE_OPTIONS \ + SUBTARGET_OVERRIDE_OPTIONS; \ } #endif /* defined SUPPORT_SUN_FPA */ @@ -344,21 +345,9 @@ extern int target_flags; compiler's mitts completely off it. We don't bother to zero it out of register classes. If neither TARGET_FPA or TARGET_68881 is set, the compiler won't touch since no instructions that use these - registers will be valid. + registers will be valid. */ - Reserve PIC_OFFSET_TABLE_REGNUM (a5) for doing PIC relocation if - position independent code is being generated by making it a - fixed register */ - -#ifndef SUPPORT_SUN_FPA - -#define CONDITIONAL_REGISTER_USAGE \ -{ \ - if (flag_pic) \ - fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ -} - -#else /* defined SUPPORT_SUN_FPA */ +#ifdef SUPPORT_SUN_FPA #define CONDITIONAL_REGISTER_USAGE \ { \ @@ -378,8 +367,6 @@ extern int target_flags; if (TEST_HARD_REG_BIT (x, i)) \ fixed_regs[i] = call_used_regs[i] = 1; \ } \ - if (flag_pic) \ - fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ } #endif /* defined SUPPORT_SUN_FPA */ @@ -404,7 +391,8 @@ extern int target_flags; if 68881 use is disabled. */ #define HARD_REGNO_MODE_OK(REGNO, MODE) \ - (((REGNO) < 16) \ + (((REGNO) < 16 \ + && !((REGNO) < 8 && (REGNO) + GET_MODE_SIZE ((MODE)) / 4 > 8)) \ || ((REGNO) < 24 \ && TARGET_68881 \ && (GET_MODE_CLASS (MODE) == MODE_FLOAT \ @@ -677,8 +665,9 @@ extern enum reg_class regno_reg_class[]; On the 68000 series, use a data reg if possible when the value is a constant in the range where moveq could be used and we ensure that QImodes are reloaded into data regs. - Also, if a floating constant needs reloading, put it in memory - if possible. */ + Also, if a floating constant needs reloading, put it in memory. + Don't do this for !G constants, since all patterns in the md file + expect them to be loaded into a register via fpmovecr. See above. */ #define PREFERRED_RELOAD_CLASS(X,CLASS) \ ((GET_CODE (X) == CONST_INT \ @@ -689,7 +678,9 @@ extern enum reg_class regno_reg_class[]; ? DATA_REGS \ : (GET_CODE (X) == CONST_DOUBLE \ && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \ - ? NO_REGS \ + ? (! CONST_DOUBLE_OK_FOR_LETTER_P (X, 'G') \ + && (CLASS == FP_REGS || CLASS == DATA_OR_FP_REGS) \ + ? FP_REGS : NO_REGS) \ : (CLASS)) /* Return the maximum number of consecutive registers @@ -758,6 +749,7 @@ extern enum reg_class regno_reg_class[]; /* Value is the number of byte of arguments automatically popped when returning from a subroutine call. + FUNDECL is the declaration node of the function (as a tree), FUNTYPE is the data type of the function (as a tree), or for a library call it is an identifier node for the subroutine name. SIZE is the number of bytes of arguments passed on the stack. @@ -771,7 +763,7 @@ extern enum reg_class regno_reg_class[]; standard Unix calling sequences. If the option is not selected, the caller must always pop the args. */ -#define RETURN_POPS_ARGS(FUNTYPE,SIZE) \ +#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) \ ((TARGET_RTD && TREE_CODE (FUNTYPE) != IDENTIFIER_NODE \ && (TYPE_ARG_TYPES (FUNTYPE) == 0 \ || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \ @@ -943,41 +935,36 @@ extern enum reg_class regno_reg_class[]; of a trampoline, leaving space for the variable parts. */ /* On the 68k, the trampoline looks like this: - mov @#.,a0 - 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. + movl #STATIC,a0 + jmp FUNCTION -We always use the assembler label ___trampoline -regardless of whether the system adds underscores. */ + WARNING: Targets that may run on 68040+ cpus must arrange for + the instruction cache to be flushed. Previous incarnations of + the m68k trampoline code attempted to get around this by either + using an out-of-line transfer function or pc-relative data, but + the fact remains that the code to jump to the transfer function + or the code to load the pc-relative data needs to be flushed + just as much as the "variable" portion of the trampoline. + Recognizing that a cache flush is going to be required anyway, + dispense with such notions and build a smaller trampoline. */ -#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, 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); \ - ASM_OUTPUT_SHORT (FILE, const0_rtx); \ -} +/* Since more instructions are required to move a template into + place than to create it on the spot, don't use a template. */ /* Length in units of the trampoline for entering a nested function. */ -#define TRAMPOLINE_SIZE 26 +#define TRAMPOLINE_SIZE 12 + +/* Alignment required for a trampoline in bytes. */ -/* Alignment required for a trampoline. 16 is used to find the - beginning of a line in the instruction cache. */ +#define TRAMPOLINE_ALIGNMENT 2 -#define TRAMPOLINE_ALIGN 16 +/* Targets redefine this to invoke code to either flush the cache, + or enable stack execution (or both). */ + +#ifndef FINALIZE_TRAMPOLINE +#define FINALIZE_TRAMPOLINE(TRAMP) +#endif /* Emit RTL insns to initialize the variable parts of a trampoline. FNADDR is an RTX for the address of the function's pure code. @@ -985,14 +972,20 @@ regardless of whether the system adds un #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ { \ - emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 2)), TRAMP); \ - emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 18)), CXT); \ - emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 22)), FNADDR); \ + emit_move_insn (gen_rtx (MEM, HImode, TRAMP), GEN_INT(0x207C)); \ + emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 2)), CXT); \ + emit_move_insn (gen_rtx (MEM, HImode, plus_constant (TRAMP, 6)), \ + GEN_INT(0x4EF9)); \ + emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 8)), FNADDR); \ + FINALIZE_TRAMPOLINE(TRAMP); \ } /* This is the library routine that is used to transfer control from the trampoline - to the actual nested function. */ + to the actual nested function. + It is defined for backward compatibility, + for linking with object code that used the old + trampoline definition. */ /* A colon is used with no explicit operands to cause the template string to be scanned for %-constructs. */ @@ -1088,7 +1081,12 @@ __transfer_from_trampoline () \ that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ #define LEGITIMATE_PIC_OPERAND_P(X) \ - (! symbolic_operand (X, VOIDmode)) + ((! symbolic_operand (X, VOIDmode) \ + && ! (GET_CODE (X) == CONST_DOUBLE && CONST_DOUBLE_MEM (X) \ + && GET_CODE (CONST_DOUBLE_MEM (X)) == MEM \ + && symbolic_operand (XEXP (CONST_DOUBLE_MEM (X), 0), \ + VOIDmode))) \ + || (GET_CODE (X) == SYMBOL_REF && SYMBOL_REF_FLAG (X))) /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx and check its validity for a certain class. @@ -1353,12 +1351,8 @@ __transfer_from_trampoline () \ case CONST_INT: \ /* Constant zero is super cheap due to clr instruction. */ \ if (RTX == const0_rtx) return 0; \ - /* Constants between -128 and 127 are cheap due to moveq */ \ - 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 ((OUTER_CODE) == SET && INTVAL (RTX) >= -136 \ - && INTVAL (RTX) <= 254) return 2; \ + /* if ((OUTER_CODE) == SET) */ \ + return const_int_cost(RTX); \ case CONST: \ case LABEL_REF: \ case SYMBOL_REF: \ @@ -1372,8 +1366,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. */ +/* div?.w is relatively cheaper on 68000 counted in COSTS_N_INSNS terms. */ #define MULL_COST (TARGET_68040 ? 5 : 13) -#define MULW_COST (TARGET_68040 ? 3 : 8) +#define MULW_COST (TARGET_68040 ? 3 : TARGET_68020 ? 8 : 5) +#define DIVW_COST (TARGET_68020 ? 27 : 12) #define RTX_COSTS(X,CODE,OUTER_CODE) \ case PLUS: \ @@ -1390,8 +1386,19 @@ __transfer_from_trampoline () \ break; \ case ASHIFT: \ case ASHIFTRT: \ - case LSHIFT: \ - case LSHIFTRT: \ + case LSHIFTRT: \ + if (! TARGET_68020) \ + { \ + if (GET_CODE (XEXP (X, 1)) == CONST_INT) \ + { \ + if (INTVAL (XEXP (X, 1)) < 16) \ + return COSTS_N_INSNS (2) + INTVAL (XEXP (X, 1)) / 2; \ + else \ + /* We're using clrw + swap for these cases. */ \ + return COSTS_N_INSNS (4) + (INTVAL (XEXP (X, 1)) - 16) / 2; \ + } \ + return COSTS_N_INSNS (10); /* worst case */ \ + } \ /* A shift by a big integer takes an extra instruction. */ \ if (GET_CODE (XEXP (X, 1)) == CONST_INT \ && (INTVAL (XEXP (X, 1)) == 16)) \ @@ -1402,6 +1409,10 @@ __transfer_from_trampoline () \ return COSTS_N_INSNS (3); /* lsr #i,dn */ \ break; \ case MULT: \ + if ((GET_CODE (XEXP (X, 0)) == ZERO_EXTEND \ + || GET_CODE (XEXP (X, 0)) == SIGN_EXTEND) \ + && GET_MODE (X) == SImode) \ + return COSTS_N_INSNS (MULW_COST); \ if (GET_MODE (X) == QImode || GET_MODE (X) == HImode) \ return COSTS_N_INSNS (MULW_COST); \ else \ @@ -1411,7 +1422,7 @@ __transfer_from_trampoline () \ case MOD: \ case UMOD: \ if (GET_MODE (X) == QImode || GET_MODE (X) == HImode) \ - return COSTS_N_INSNS (27); /* div.w */ \ + return COSTS_N_INSNS (DIVW_COST); /* div.w */ \ return COSTS_N_INSNS (43); /* div.l */ /* Tell final.c how to eliminate redundant test instructions. */ @@ -1945,10 +1956,12 @@ do { long l; \ /* Define functions defined in aux-output.c and used in templates. */ +extern char *output_move_const_into_data_reg (); extern char *output_move_double (); extern char *output_move_const_single (); extern char *output_move_const_double (); extern char *output_btst (); +extern char *output_scc_di (); /* Local variables: