]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/config/m68k/m68k.h
(MACHINE_STATE_SAVE, MACHINE_STATE_RESTORE): Test
[gcc.git] / gcc / config / m68k / m68k.h
index 8faa573131e416a581839a82ad9dab67754d48cf..07ce8724209c01990bc6cadcaa6e5875210d4c67 100644 (file)
@@ -1,5 +1,5 @@
 /* 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.
 
@@ -50,37 +50,41 @@ extern int target_flags;
 /* Macros used in the machine description to test the flags.  */
 
 /* Compile for a 68020 (not a 68000 or 68010).  */
-#define TARGET_68020 (target_flags & 1)
+#define MASK_68020     1
+#define TARGET_68020 (target_flags & MASK_68020)
 
 /* Compile 68881 insns for floating point (not library calls).  */
-#define TARGET_68881 (target_flags & 2)
+#define MASK_68881     2
+#define TARGET_68881 (target_flags & MASK_68881)
 
 /* Compile using 68020 bitfield insns.  */
-#define TARGET_BITFIELD (target_flags & 4)
+#define MASK_BITFIELD  4
+#define TARGET_BITFIELD (target_flags & MASK_BITFIELD)
 
 /* Compile using rtd insn calling sequence.
    This will not work unless you use prototypes at least
    for all functions that can take varying numbers of args.  */
-#define TARGET_RTD (target_flags & 8)
+#define MASK_RTD       8
+#define TARGET_RTD (target_flags & MASK_RTD)
 
 /* Compile passing first two args in regs 0 and 1.
    This exists only to test compiler features that will
    be needed for RISC chips.  It is not usable
    and is not intended to be usable on this cpu.  */
-#define TARGET_REGPARM (target_flags & 020)
+#define MASK_REGPARM   16
+#define TARGET_REGPARM (target_flags & MASK_REGPARM)
 
 /* Compile with 16-bit `int'.  */
-#define TARGET_SHORT (target_flags & 040)
+#define MASK_SHORT     32
+#define TARGET_SHORT (target_flags & MASK_SHORT)
 
 /* Compile with special insns for Sun FPA.  */
-#ifdef SUPPORT_SUN_FPA
-#define TARGET_FPA (target_flags & 0100)
-#else
-#define TARGET_FPA 0
-#endif
+#define MASK_FPA       64
+#define TARGET_FPA (target_flags & MASK_FPA)
 
 /* Compile (actually, link) for Sun SKY board.  */
-#define TARGET_SKY (target_flags & 0200)
+#define MASK_SKY       128
+#define TARGET_SKY (target_flags & MASK_SKY)
 
 /* Optimize for 68040, but still allow execution on 68020
    (-m68020-40 or -m68040).
@@ -88,18 +92,36 @@ extern int target_flags;
    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 & 01400)
+#define MASK_68040     256
+#define TARGET_68040 (target_flags & MASK_68040)
 
 /* Use the 68040-only fp instructions (-m68040 or -m68060).  */
-#define TARGET_68040_ONLY (target_flags & 01000)
+#define MASK_68040_ONLY        512
+#define TARGET_68040_ONLY (target_flags & MASK_68040_ONLY)
 
 /* Optimize for 68060, but still allow execution on 68020
-   (-m68060).
+   (-m68020-60 or -m68060).
    The 68060 will execute all 68030 and 68881/2 instructions, but some
    of them must be emulated in software by the OS.  When TARGET_68060 is
    turned on, these instructions won't be used.  This code will still
    run on a 68030 and 68881/2. */
-#define TARGET_68060 (target_flags & 02000)
+#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)
+
+/* Align ints to a word boundary.  This breaks compatibility with the 
+   published ABI's for structures containing ints, but produces faster
+   code on cpus with 32 bit busses (020, 030, 040, 060, CPU32+, coldfire).
+   It's required for coldfire cpus without a misalignment module.  */
+#define MASK_ALIGN_INT 4096
+#define TARGET_ALIGN_INT (target_flags & MASK_ALIGN_INT)
+
+/* 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,
@@ -108,62 +130,92 @@ extern int target_flags;
    An empty string NAME is used to identify the default VALUE.  */
 
 #define TARGET_SWITCHES  \
-  { { "68020", -03400},                                \
-    { "c68020", -03400},                       \
-    { "68020", 5},                             \
-    { "c68020", 5},                            \
-    { "68881", 2},                             \
-    { "bitfield", 4},                          \
-    { "68000", -03405},                                \
-    { "c68000", -03405},                       \
-    { "soft-float", -03102},                   \
-    { "nobitfield", -4},                       \
-    { "rtd", 8},                               \
-    { "nortd", -8},                            \
-    { "short", 040},                           \
-    { "noshort", -040},                                \
-    { "fpa", 0100},                            \
-    { "nofpa", -0100},                         \
-    { "sky", 0200},                            \
-    { "nosky", -0200},                         \
-    { "68020-40", 0407},                       \
-    { "68030", -03400},                                \
-    { "68030", 5},                             \
-    { "68040", 01007},                         \
-    { "68060", 03007},                         \
-    { "68851", 0},     /* Affects *_SPEC and/or GAS.  */       \
-    { "no-68851", 0},  /* Affects *_SPEC and/or GAS.  */       \
-    { "68302", 0},     /* Affects *_SPEC and/or GAS.  */       \
-    { "no-68302", 0},  /* Affects *_SPEC and/or GAS.  */       \
-    { "68332", 0},     /* Affects *_SPEC and/or GAS.  */       \
-    { "no-68332", 0},  /* Affects *_SPEC and/or GAS.  */       \
-    SUBTARGET_SWITCHES                         \
+  { { "68020", - (MASK_5200|MASK_68060|MASK_68040|MASK_68040_ONLY)},   \
+    { "c68020", - (MASK_5200|MASK_68060|MASK_68040|MASK_68040_ONLY)},  \
+    { "68020", (MASK_68020|MASK_BITFIELD)},                            \
+    { "c68020", (MASK_68020|MASK_BITFIELD)},                           \
+    { "68000", - (MASK_5200|MASK_68060|MASK_68040|MASK_68040_ONLY      \
+               |MASK_68020|MASK_BITFIELD)},                            \
+    { "c68000", - (MASK_5200|MASK_68060|MASK_68040|MASK_68040_ONLY     \
+               |MASK_68020|MASK_BITFIELD)},                            \
+    { "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},                                            \
+    { "68881" - (MASK_FPA|MASK_SKY)},                                  \
+    { "68881", MASK_68881},                                            \
+    { "soft-float", - (MASK_FPA|MASK_SKY|MASK_68040_ONLY|MASK_68881)}, \
+    { "68020-40", -(MASK_5200|MASK_68060)},                            \
+    { "68020-40", (MASK_BITFIELD|MASK_68881|MASK_68020|MASK_68040)},   \
+    { "68020-60", -(MASK_5200|MASK_68040)},                            \
+    { "68020-60", (MASK_BITFIELD|MASK_68881|MASK_68020|MASK_68060)},   \
+    { "68030", - (MASK_5200|MASK_68060|MASK_68040|MASK_68040_ONLY)},   \
+    { "68030", (MASK_68020|MASK_BITFIELD)},                            \
+    { "68040", - (MASK_5200|MASK_68060)},                              \
+    { "68040", (MASK_68020|MASK_68881|MASK_BITFIELD                    \
+               |MASK_68040_ONLY|MASK_68040)},                          \
+    { "68060", - (MASK_5200|MASK_68040)},                              \
+    { "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", - (MASK_5200|MASK_68060|MASK_68040|MASK_68020|MASK_BITFIELD)}, \
+    { "68332", - (MASK_5200|MASK_68060|MASK_68040|MASK_BITFIELD)},     \
+    { "68332", MASK_68020},                                            \
+    { "cpu32", - (MASK_5200|MASK_68060|MASK_68040|MASK_BITFIELD)},     \
+    { "cpu32", MASK_68020},                                            \
+    { "align-int", MASK_ALIGN_INT },                                   \
+    { "no-align-int", -MASK_ALIGN_INT },                               \
+    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 &= ~2;  \
-  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 */
@@ -218,18 +270,31 @@ extern int target_flags;
 #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
 
-/* No data type wants to be aligned rounder than this.  */
-#define BIGGEST_ALIGNMENT 16
+/* No data type wants to be aligned rounder than this. 
+   Most published ABIs say that ints should be aligned on 16 bit
+   boundries, but cpus with 32 bit busses get better performance
+   aligned on 32 bit boundries.  Coldfires without a misalignment
+   module require 32 bit alignment. */
+#define BIGGEST_ALIGNMENT (TARGET_ALIGN_INT ? 32 : 16)
 
 /* Set this nonzero if move instructions will actually fail to work
    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)                                                       \
@@ -643,14 +708,20 @@ extern enum reg_class regno_reg_class[];
    `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:
@@ -669,6 +740,19 @@ extern enum reg_class regno_reg_class[];
    (C) == 'H' ? (TARGET_FPA && standard_sun_fpa_constant_p (VALUE)) : 0)
 #endif /* defined SUPPORT_SUN_FPA */
 
+/* A C expression that defines the optional machine-dependent constraint
+   letters that can be used to segregate specific types of operands,  
+   usually memory references, for the target machine.  It should return 1 if
+   VALUE corresponds to the operand type represented by the constraint letter
+   C.  If C is not defined as an extra constraint, the value returned should 
+   be 0 regardless of VALUE.  */
+
+/* For the m68k, `Q' means address register indirect addressing mode. */
+
+#define EXTRA_CONSTRAINT(OP, C)        \
+  ((C) == 'Q' ? (GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG) : \
+   0 )
+
 /* Given an rtx X being reloaded into a reg required to be
    in class CLASS, return the class of reg to actually use.
    In general this is just CLASS; but on some machines
@@ -752,8 +836,9 @@ extern enum reg_class regno_reg_class[];
 
 /* If we generate an insn to push BYTES bytes,
    this says how many the stack pointer really advances by.
-   On the 68000, sp@- in a byte insn really pushes a word.  */
-#define PUSH_ROUNDING(BYTES) (((BYTES) + 1) & ~1)
+   On the 68000, sp@- in a byte insn really pushes a word.
+   On the 5200 (coldfire), sp@- in a byte insn pushes just a byte.  */
+#define PUSH_ROUNDING(BYTES) (TARGET_5200 ? BYTES : ((BYTES) + 1) & ~1)
 
 /* Offset of first parameter from the argument pointer register value.  */
 #define FIRST_PARM_OFFSET(FNDECL) 8
@@ -775,7 +860,7 @@ extern enum reg_class regno_reg_class[];
    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)))                                \
@@ -835,7 +920,7 @@ extern enum reg_class regno_reg_class[];
 
    On the m68k, the offset starts at 0.  */
 
-#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME      \
+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT)      \
  ((CUM) = 0)
 
 /* Update the data in CUM to advance over an argument
@@ -935,29 +1020,102 @@ while(0)
 #define FUNCTION_BLOCK_PROFILER_EXIT(FILE)             \
   asm_fprintf (FILE, "\tjsr %U__bb_trace_ret\n");
 
-/* Save all registers which may be clobbered by a function call. */
+/* Save all registers which may be clobbered by a function call.
+   MACHINE_STATE_SAVE and MACHINE_STATE_RESTORE are target-code macros,
+   used in libgcc2.c.  They may not refer to TARGET_* macros !!! */
+#if defined (__mc68010__) || defined(mc68010) \
+       || defined(__mc68020__) || defined(mc68020) \
+       || defined(__mc68030__) || defined(mc68030) \
+       || defined(__mc68040__) || defined(mc68040) \
+       || defined(__mc68332__) || defined(mc68332)
+#define MACHINE_STATE_m68010_up
+#endif
 
 #ifdef MOTOROLA
+#if defined(__mcf5200__)
 #define MACHINE_STATE_SAVE(id)         \
-  asm ("move.w %ccr,-(%sp)");          \
-  asm ("movm.l &0xc0c0,-(%sp)");
-#else
+    {                                  \
+      asm ("sub.l 20,%sp");            \
+      asm ("movm.l &0x0303,4(%sp)");   \
+      asm ("move.w %ccr,%d0");         \
+      asm ("movm.l &0x0001,(%sp)");    \
+    }
+#else /* !__mcf5200__ */
+#if defined(MACHINE_STATE_m68010_up)
 #define MACHINE_STATE_SAVE(id)         \
-  asm ("movew cc,sp@-");               \
-  asm ("moveml d0/d1/a0/a1,sp@-");
-#endif
+    {                                  \
+      asm ("move.w %ccr,-(%sp)");      \
+      asm ("movm.l &0xc0c0,-(%sp)");   \
+    }
+#else /* !MACHINE_STATE_m68010_up */
+#define MACHINE_STATE_SAVE(id)         \
+    {                                  \
+      asm ("move.w %sr,-(%sp)");       \
+      asm ("movm.l &0xc0c0,-(%sp)");   \
+    }
+#endif /* MACHINE_STATE_m68010_up */
+#endif /* __mcf5200__ */
+#else /* !MOTOROLA */
+#if defined(__mcf5200__)
+#define MACHINE_STATE_SAVE(id)         \
+    {                                  \
+      asm ("subl 20,sp");              \
+      asm ("movml d0/d1/a0/a1,sp@(4)");        \
+      asm ("movew cc,d0");             \
+      asm ("movml d0,sp@");            \
+    }
+#else /* !__mcf5200__ */
+#if defined(MACHINE_STATE_m68010_up)
+#define MACHINE_STATE_SAVE(id)         \
+    {                                  \
+      asm ("movew cc,sp@-");           \
+      asm ("moveml d0/d1/a0/a1,sp@-"); \
+    }
+#else /* !MACHINE_STATE_m68010_up */
+#define MACHINE_STATE_SAVE(id)         \
+    {                                  \
+      asm ("movew sr,sp@-");           \
+      asm ("moveml d0/d1/a0/a1,sp@-"); \
+    }
+#endif /* MACHINE_STATE_m68010_up */
+#endif /* __mcf5200__ */
+#endif /* MOTOROLA */
 
 /* Restore all registers saved by MACHINE_STATE_SAVE. */
 
 #ifdef MOTOROLA
+#if defined(__mcf5200__)
 #define MACHINE_STATE_RESTORE(id)      \
-  asm ("movm.l (%sp)+,&0x0303");       \
-  asm ("move.w (%sp)+,%ccr");
-#else
+    {                                  \
+      asm ("movm.l (%sp),&0x0001");    \
+      asm ("move.w %d0,%ccr");         \
+      asm ("movm.l 4(%sp),&0x0303");   \
+      asm ("add.l 20,%sp");            \
+    }
+#else /* !__mcf5200__ */
 #define MACHINE_STATE_RESTORE(id)      \
-  asm ("moveml sp@+,d0/d1/a0/a1");     \
-  asm ("movew sp@+,cc");
-#endif
+    {                                  \
+      asm ("movm.l (%sp)+,&0x0303");   \
+      asm ("move.w (%sp)+,%ccr");      \
+    }
+#endif /* __mcf5200__ */
+#else /* !MOTOROLA */
+#if defined(__mcf5200__)
+#define MACHINE_STATE_RESTORE(id)      \
+    {                                  \
+      asm ("movml sp@,d0");            \
+      asm ("movew d0,cc");             \
+      asm ("movml sp@(4),d0/d1/a0/a1");        \
+      asm ("addl 20,sp");              \
+    }
+#else /* !__mcf5200__ */
+#define MACHINE_STATE_RESTORE(id)      \
+    {                                  \
+      asm ("moveml sp@+,d0/d1/a0/a1"); \
+      asm ("movew sp@+,cc");           \
+    }
+#endif /* __mcf5200__ */
+#endif /* MOTOROLA */
 
 /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
    the stack pointer does not matter.  The value is tested only in
@@ -1004,42 +1162,49 @@ while(0)
    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
@@ -1270,12 +1435,12 @@ __transfer_from_trampoline ()                                   \
 
 #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)                                \
@@ -1429,26 +1594,28 @@ __transfer_from_trampoline ()                                   \
    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)                        \
@@ -2022,11 +2189,28 @@ 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_simode_const ();
+extern char *output_move_simode ();
+extern char *output_move_himode ();
+extern char *output_move_qimode ();
+extern char *output_move_stricthi ();
+extern char *output_move_strictqi ();
 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:
This page took 0.048658 seconds and 5 git commands to generate.