OSDN Git Service

(output_addsi3): Add declaration.
[pf3gnuchains/gcc-fork.git] / gcc / config / m68k / m68k.h
index 76456d6..ba728bc 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.
 
@@ -92,6 +92,7 @@ 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 MASK_68040_ALSO (256)
 #define MASK_68040     (256|512)
 #define TARGET_68040 (target_flags & MASK_68040)
 
@@ -108,6 +109,14 @@ extern int target_flags;
 #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 }
@@ -119,59 +128,76 @@ extern int target_flags;
     { "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 */
@@ -226,7 +252,7 @@ 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
@@ -238,6 +264,15 @@ extern int target_flags;
    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)                                                       \
@@ -651,14 +686,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:
@@ -783,7 +824,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)))                                \
@@ -1012,42 +1053,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
@@ -1278,12 +1326,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)                                \
@@ -1437,26 +1485,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)                        \
@@ -2031,11 +2081,25 @@ do { long l;                                            \
 
 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: