/* Definitions of target machine for GNU compiler. Sun 68000/68020 version.
- Copyright (C) 1987, 88, 93, 94, 95, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
This file is part of GNU CC.
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 MASK_68040_ALSO (256)
#define MASK_68040 (256|512)
#define TARGET_68040 (target_flags & MASK_68040)
#define MASK_68060 1024
#define TARGET_68060 (target_flags & MASK_68060)
+/* Compile for mcf5200 */
+#define MASK_5200 2048
+#define TARGET_5200 (target_flags & MASK_5200)
+
+/* Compile for a CPU32 */
+ /* A 68020 without bitfields is a good heuristic for a CPU32 */
+#define TARGET_CPU32 (TARGET_68020 && !TARGET_BITFIELD)
+
/* Macro to define tables used to set the flags.
This is a list in braces of pairs in braces,
each pair being { "NAME", VALUE }
{ "c68020", - (MASK_68060|MASK_68040)}, \
{ "68020", (MASK_68020|MASK_BITFIELD)}, \
{ "c68020", (MASK_68020|MASK_BITFIELD)}, \
- { "68881", MASK_68881}, \
- { "bitfield", MASK_BITFIELD}, \
{ "68000", - (MASK_68060|MASK_68040|MASK_68020|MASK_BITFIELD)}, \
{ "c68000", - (MASK_68060|MASK_68040|MASK_68020|MASK_BITFIELD)}, \
- { "soft-float", - (MASK_68060|MASK_68040_ONLY|MASK_68881)}, \
+ { "bitfield", MASK_BITFIELD}, \
{ "nobitfield", - MASK_BITFIELD}, \
{ "rtd", MASK_RTD}, \
{ "nortd", - MASK_RTD}, \
{ "short", MASK_SHORT}, \
{ "noshort", - MASK_SHORT}, \
+ { "fpa", -(MASK_SKY|MASK_68040_ONLY|MASK_68881)}, \
{ "fpa", MASK_FPA}, \
{ "nofpa", - MASK_FPA}, \
+ { "sky", -(MASK_FPA|MASK_68040_ONLY|MASK_68881)}, \
{ "sky", MASK_SKY}, \
{ "nosky", - MASK_SKY}, \
- { "68020-40", (MASK_BITFIELD|MASK_68881|MASK_68020)}, \
+ { "68881" - (MASK_FPA|MASK_SKY)}, \
+ { "68881", MASK_68881}, \
+ { "soft-float", - (MASK_FPA|MASK_SKY|MASK_68040_ONLY|MASK_68881)}, \
+ { "68020-40", (MASK_BITFIELD|MASK_68881|MASK_68020|MASK_68040_ALSO)}, \
{ "68030", - (MASK_68040|MASK_68060)}, \
{ "68030", (MASK_68020|MASK_BITFIELD)}, \
{ "68040", (MASK_68020|MASK_68881|MASK_BITFIELD|MASK_68040_ONLY)}, \
{ "68060", (MASK_68020|MASK_68881|MASK_BITFIELD \
|MASK_68040_ONLY|MASK_68060)}, \
+ { "5200", - (MASK_68060|MASK_68040|MASK_68020|MASK_BITFIELD|MASK_68881)}, \
+ { "5200", (MASK_5200)}, \
{ "68851", 0}, \
{ "no-68851", 0}, \
- { "68302", 0}, \
- { "no-68302", 0}, \
- { "68332", - (MASK_68060|MASK_68040|MASK_68020|MASK_BITFIELD)}, \
- { "no-68332", 0}, \
+ { "68302", - (MASK_68060|MASK_68040|MASK_68020|MASK_BITFIELD)}, \
+ { "68332", - (MASK_68060|MASK_68040|MASK_BITFIELD)}, \
+ { "68332", MASK_68020}, \
SUBTARGET_SWITCHES \
{ "", TARGET_DEFAULT}}
/* TARGET_DEFAULT is defined in sun*.h and isi.h, etc. */
-/* This is meant to be redefined in the host dependent files */
-#define SUBTARGET_SWITCHES
-
-#ifdef SUPPORT_SUN_FPA
-/* Blow away 68881 flag silently on TARGET_FPA (since we can't clear
- any bits in TARGET_SWITCHES above) */
-#define OVERRIDE_OPTIONS \
-{ \
- if (TARGET_FPA) target_flags &= ~ MASK_68881; \
- if (! TARGET_68020 && flag_pic == 2) \
- error("-fPIC is not currently supported on the 68000 or 68010\n"); \
- SUBTARGET_OVERRIDE_OPTIONS; \
+/* This macro is similar to `TARGET_SWITCHES' but defines names of
+ command options that have values. Its definition is an
+ initializer with a subgrouping for each command option.
+
+ Each subgrouping contains a string constant, that defines the
+ fixed part of the option name, and the address of a variable. The
+ variable, type `char *', is set to the variable part of the given
+ option if the fixed part matches. The actual option name is made
+ by appending `-m' to the specified name. */
+#define TARGET_OPTIONS \
+{ { "align-loops=", &m68k_align_loops_string }, \
+ { "align-jumps=", &m68k_align_jumps_string }, \
+ { "align-functions=", &m68k_align_funcs_string }, \
+ SUBTARGET_OPTIONS \
}
-#else
+
+/* Sometimes certain combinations of command options do not make
+ sense on a particular target machine. You can define a macro
+ `OVERRIDE_OPTIONS' to take account of this. This macro, if
+ defined, is executed once just after all the command options have
+ been parsed.
+
+ Don't use this macro to turn on various extra optimizations for
+ `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
+
#define OVERRIDE_OPTIONS \
{ \
+ override_options(); \
if (! TARGET_68020 && flag_pic == 2) \
error("-fPIC is not currently supported on the 68000 or 68010\n"); \
SUBTARGET_OVERRIDE_OPTIONS; \
}
-#endif /* defined SUPPORT_SUN_FPA */
-/* This is meant to be redefined in the host dependent files */
+/* These are meant to be redefined in the host dependent files */
+#define SUBTARGET_SWITCHES
+#define SUBTARGET_OPTIONS
#define SUBTARGET_OVERRIDE_OPTIONS
\f
/* target machine storage layout */
#define STACK_BOUNDARY 16
/* Allocation boundary (in *bits*) for the code of a function. */
-#define FUNCTION_BOUNDARY 16
+#define FUNCTION_BOUNDARY (1 << (m68k_align_funcs + 3))
/* Alignment of field after `int : 0' in a structure. */
#define EMPTY_FIELD_BOUNDARY 16
when given unaligned data. */
#define STRICT_ALIGNMENT 1
+/* Maximum power of 2 that code can be aligned to. */
+#define MAX_CODE_ALIGN 2 /* 4 byte alignment */
+
+/* Align loop starts for optimal branching. */
+#define ASM_OUTPUT_LOOP_ALIGN(FILE) ASM_OUTPUT_ALIGN ((FILE), m68k_align_loops)
+
+/* This is how to align an instruction for optimal branching. */
+#define ASM_OUTPUT_ALIGN_CODE(FILE) ASM_OUTPUT_ALIGN ((FILE), m68k_align_jumps)
+
#define SELECT_RTX_SECTION(MODE, X) \
{ \
if (!flag_pic) \
`J' is used for the range of signed numbers that fit in 16 bits.
`K' is for numbers that moveq can't handle.
`L' is for range -8 to -1, range of values that can be added with subq.
- `M' is for numbers that moveq+notb can't handle. */
+ `M' is for numbers that moveq+notb can't handle.
+ 'N' is for range 24 to 31, rotatert:SI 8 to 1 expressed as rotate.
+ 'O' is for 16 (for rotate using swap).
+ 'P' is for range 8 to 15, rotatert:HI 8 to 1 expressed as rotate. */
#define CONST_OK_FOR_LETTER_P(VALUE, C) \
((C) == 'I' ? (VALUE) > 0 && (VALUE) <= 8 : \
(C) == 'J' ? (VALUE) >= -0x8000 && (VALUE) <= 0x7FFF : \
(C) == 'K' ? (VALUE) < -0x80 || (VALUE) >= 0x80 : \
(C) == 'L' ? (VALUE) < 0 && (VALUE) >= -8 : \
- (C) == 'M' ? (VALUE) < -0x100 && (VALUE) >= 0x100 : 0)
+ (C) == 'M' ? (VALUE) < -0x100 && (VALUE) >= 0x100 : \
+ (C) == 'N' ? (VALUE) >= 24 && (VALUE) <= 31 : \
+ (C) == 'O' ? (VALUE) == 16 : \
+ (C) == 'P' ? (VALUE) >= 8 && (VALUE) <= 15 : 0)
/*
* A small bit of explanation:
the caller must always pop the args. */
#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) \
- ((TARGET_RTD && TREE_CODE (FUNTYPE) != IDENTIFIER_NODE \
+ ((TARGET_RTD && (!(FUNDECL) || TREE_CODE (FUNDECL) != IDENTIFIER_NODE) \
&& (TYPE_ARG_TYPES (FUNTYPE) == 0 \
|| (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \
== void_type_node))) \
of a trampoline, leaving space for the variable parts. */
/* On the 68k, the trampoline looks like this:
- movl pc@(8),a0
- movl pc@(8),sp@-
- rts
- .long STATIC
- .long FUNCTION
-The use of pc relative addressing mode ensures that the constants are
-accessed through the data cache. */
-
-#define TRAMPOLINE_TEMPLATE(FILE) \
-{ \
- ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x207a)); \
- ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 8)); \
- ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x2f3a)); \
- ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 8)); \
- ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x4e75)); \
- ASM_OUTPUT_INT (FILE, const0_rtx); \
- ASM_OUTPUT_INT (FILE, const0_rtx); \
-}
+ movl #STATIC,a0
+ jmp FUNCTION
+
+ 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. */
+
+/* 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 18
+#define TRAMPOLINE_SIZE 12
-/* Alignment required for a trampoline. 16 is used to find the
- beginning of a line in the instruction cache. */
+/* Alignment required for a trampoline in bits. */
#define TRAMPOLINE_ALIGNMENT 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.
CXT is an RTX for the static chain value for the function. */
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
{ \
- emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 10)), CXT); \
- emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 14)), 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
#define LEGITIMATE_INDEX_P(X) \
(LEGITIMATE_INDEX_REG_P (X) \
- || (TARGET_68020 && GET_CODE (X) == MULT \
+ || ((TARGET_68020 || TARGET_5200) && GET_CODE (X) == MULT \
&& LEGITIMATE_INDEX_REG_P (XEXP (X, 0)) \
&& GET_CODE (XEXP (X, 1)) == CONST_INT \
&& (INTVAL (XEXP (X, 1)) == 2 \
|| INTVAL (XEXP (X, 1)) == 4 \
- || INTVAL (XEXP (X, 1)) == 8)))
+ || (INTVAL (XEXP (X, 1)) == 8 && !TARGET_5200))))
/* If pic, we accept INDEX+LABEL, which is what do_tablejump makes. */
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
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 : TARGET_68020 ? 8 : 5)
+#define MULL_COST (TARGET_68060 ? 2 : TARGET_68040 ? 5 : 13)
+#define MULW_COST (TARGET_68060 ? 2 : TARGET_68040 ? 3 : TARGET_68020 ? 8 : 5)
#define DIVW_COST (TARGET_68020 ? 27 : 12)
#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 \
- && GET_CODE (XEXP (X, 0)) == REG \
- && GET_CODE (XEXP (X, 1)) == MULT \
- && GET_CODE (XEXP (XEXP (X, 1), 0)) == REG \
- && GET_CODE (XEXP (XEXP (X, 1), 1)) == CONST_INT \
- && (INTVAL (XEXP (XEXP (X, 1), 1)) == 2 \
- || INTVAL (XEXP (XEXP (X, 1), 1)) == 4 \
- || INTVAL (XEXP (XEXP (X, 1), 1)) == 8)) \
+ && GET_CODE (XEXP (X, 1)) == REG \
+ && GET_CODE (XEXP (X, 0)) == MULT \
+ && GET_CODE (XEXP (XEXP (X, 0), 0)) == REG \
+ && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
+ && (INTVAL (XEXP (XEXP (X, 0), 1)) == 2 \
+ || INTVAL (XEXP (XEXP (X, 0), 1)) == 4 \
+ || INTVAL (XEXP (XEXP (X, 0), 1)) == 8)) \
return COSTS_N_INSNS (3); /* lea an@(dx:l:i),am */ \
break; \
case ASHIFT: \
case ASHIFTRT: \
- case LSHIFTRT: \
+ case LSHIFTRT: \
+ if (TARGET_68060) \
+ return COSTS_N_INSNS(1); \
if (! TARGET_68020) \
{ \
if (GET_CODE (XEXP (X, 1)) == CONST_INT) \
extern char *output_move_const_into_data_reg ();
extern char *output_move_simode_const ();
+extern char *output_move_simode ();
+extern char *output_move_himode ();
+extern char *output_move_qimode ();
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 ();
+extern char *output_addsi3 ();
+
+/* Variables in m68k.c */
+extern char *m68k_align_loops_string;
+extern char *m68k_align_jumps_string;
+extern char *m68k_align_funcs_string;
+extern int m68k_align_loops;
+extern int m68k_align_jumps;
+extern int m68k_align_funcs;
+extern int m68k_last_compare_had_fp_operands;
+
\f
/*
Local variables: