]> 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 a23bfbc86a80bd09a745888a68872ec58276fd28..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.
 
@@ -92,7 +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     (256|512)
+#define MASK_68040     256
 #define TARGET_68040 (target_flags & MASK_68040)
 
 /* Use the 68040-only fp instructions (-m68040 or -m68060).  */
@@ -100,7 +100,7 @@ extern int target_flags;
 #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
@@ -112,6 +112,17 @@ extern int target_flags;
 #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,
    each pair being { "NAME", VALUE }
@@ -119,12 +130,14 @@ extern int target_flags;
    An empty string NAME is used to identify the default VALUE.  */
 
 #define TARGET_SWITCHES  \
-  { { "68020", - (MASK_68060|MASK_68040)},                             \
-    { "c68020", - (MASK_68060|MASK_68040)},                            \
+  { { "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_68060|MASK_68040|MASK_68020|MASK_BITFIELD)},    \
-    { "c68000", - (MASK_68060|MASK_68040|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},                                                        \
@@ -140,34 +153,69 @@ extern int target_flags;
     { "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)},              \
-    { "68030", - (MASK_68040|MASK_68060)},                             \
+    { "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_68020|MASK_68881|MASK_BITFIELD|MASK_68040_ONLY)}, \
+    { "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_68060|MASK_68040|MASK_68020|MASK_BITFIELD)},    \
-    { "68332", - (MASK_68060|MASK_68040|MASK_BITFIELD)},               \
+    { "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
+/* 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                                                    \
+}
+
+/* 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;          \
 }
 
-/* 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 */
@@ -222,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)                                                       \
@@ -647,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:
@@ -673,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
@@ -756,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
@@ -779,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)))                                \
@@ -939,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
@@ -1448,13 +1602,13 @@ __transfer_from_trampoline ()                                   \
   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:                                                 \
@@ -2036,11 +2190,27 @@ 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_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.044245 seconds and 5 git commands to generate.