OSDN Git Service

* config/m68k/m68k.c (sched-int.h, insn-codes.h): New includes.
[pf3gnuchains/gcc-fork.git] / gcc / config / m68k / m68k.h
index a872ee9..d8e1d3a 100644 (file)
@@ -1,12 +1,12 @@
 /* Definitions of target machine for GCC for Motorola 680x0/ColdFire.
    Copyright (C) 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GCC is distributed in the hope that it will be useful,
@@ -15,9 +15,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 /* We need to have MOTOROLA always defined (either 0 or 1) because we use
    if-statements and ?: on it.  This way we have compile-time error checking
@@ -48,11 +47,15 @@ Boston, MA 02110-1301, USA.  */
 %{m68060}%{mcpu32}%{m68332}%{m5200}%{m5206e}%{m528x}%{m5307}%{m5407}%{mcfv4e}\
 %{mcpu=*:-mcpu=%*}%{march=*:-march=%*}\
 "
+#define ASM_PCREL_SPEC "%{fPIC|fpic|mpcrel:--pcrel} \
+ %{msep-data|mid-shared-library:--pcrel} \
+"
 
-#define ASM_SPEC "%(asm_cpu_spec)"
+#define ASM_SPEC "%(asm_cpu_spec) %(asm_pcrel_spec)"
 
 #define EXTRA_SPECS                                    \
   { "asm_cpu_spec", ASM_CPU_SPEC },                    \
+  { "asm_pcrel_spec", ASM_PCREL_SPEC },                        \
   SUBTARGET_EXTRA_SPECS
 
 #define SUBTARGET_EXTRA_SPECS
@@ -105,6 +108,10 @@ Boston, MA 02110-1301, USA.  */
          builtin_define_std ("mc68020");                               \
          break;                                                        \
                                                                        \
+       case ucfv1:                                                     \
+         builtin_define ("__mcfv1__");                                 \
+         break;                                                        \
+                                                                       \
        case ucfv2:                                                     \
          builtin_define ("__mcfv2__");                                 \
          break;                                                        \
@@ -241,6 +248,10 @@ Boston, MA 02110-1301, USA.  */
 #define TARGET_ISAB            ((m68k_cpu_flags & FL_ISA_B) != 0)
 #define TARGET_ISAC            ((m68k_cpu_flags & FL_ISA_C) != 0)
 
+/* Some instructions are common to more than one ISA.  */
+#define ISA_HAS_MVS_MVZ        (TARGET_ISAB || TARGET_ISAC)
+#define ISA_HAS_FF1    (TARGET_ISAAPLUS || TARGET_ISAC)
+
 #define TUNE_68000     (m68k_tune == u68000)
 #define TUNE_68010     (m68k_tune == u68010)
 #define TUNE_68000_10  (TUNE_68000 || TUNE_68010)
@@ -253,6 +264,7 @@ Boston, MA 02110-1301, USA.  */
 #define TUNE_68060     (m68k_tune == u68060 || m68k_tune == u68020_60)
 #define TUNE_68040_60  (TUNE_68040 || TUNE_68060)
 #define TUNE_CPU32     (m68k_tune == ucpu32)
+#define TUNE_CFV1       (m68k_tune == ucfv1)
 #define TUNE_CFV2      (m68k_tune == ucfv2)
 
 #define OVERRIDE_OPTIONS   override_options()
@@ -262,13 +274,15 @@ Boston, MA 02110-1301, USA.  */
 \f
 /* target machine storage layout */
 
-/* "long double" is the same as "double" on ColdFire targets.  */
+/* "long double" is the same as "double" on ColdFire and fido
+   targets.  */
 
-#define LONG_DOUBLE_TYPE_SIZE (TARGET_COLDFIRE ? 64 : 80)
+#define LONG_DOUBLE_TYPE_SIZE                  \
+  ((TARGET_COLDFIRE || TARGET_FIDOA) ? 64 : 80)
 
 /* We need to know the size of long double at compile-time in libgcc2.  */
 
-#ifdef __mcoldfire__
+#if defined(__mcoldfire__) || defined(__mfido__)
 #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
 #else
 #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 80
@@ -296,11 +310,11 @@ Boston, MA 02110-1301, USA.  */
 /* No data type wants to be aligned rounder than this.
    Most published ABIs say that ints should be aligned on 16-bit
    boundaries, but CPUs with 32-bit busses get better performance
-   aligned on 32-bit boundaries.  ColdFires without a misalignment
-   module require 32-bit alignment.  */
+   aligned on 32-bit boundaries.  */
 #define BIGGEST_ALIGNMENT (TARGET_ALIGN_INT ? 32 : 16)
 
 #define STRICT_ALIGNMENT (TARGET_STRICT_ALIGNMENT)
+#define M68K_HONOR_TARGET_STRICT_ALIGNMENT 1
 
 #define INT_TYPE_SIZE (TARGET_SHORT ? 16 : 32)
 
@@ -483,74 +497,6 @@ extern enum reg_class regno_reg_class[];
 #define INDEX_REG_CLASS GENERAL_REGS
 #define BASE_REG_CLASS ADDR_REGS
 
-/* We do a trick here to modify the effective constraints on the
-   machine description; we zorch the constraint letters that aren't
-   appropriate for a specific target.  This allows us to guarantee
-   that a specific kind of register will not be used for a given target
-   without fiddling with the register classes above.  */
-#define REG_CLASS_FROM_LETTER(C) \
-  ((C) == 'a' ? ADDR_REGS :                    \
-   ((C) == 'd' ? DATA_REGS :                   \
-    ((C) == 'f' ? (TARGET_HARD_FLOAT ?         \
-                  FP_REGS : NO_REGS) :         \
-     NO_REGS)))
-
-/* For the m68k, `I' is used for the range 1 to 8
-   allowed as immediate shift counts and in addq.
-   `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.
-   '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.
-   'R' is for numbers that mov3q can handle.  */
-#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 : \
-   (C) == 'N' ? (VALUE) >= 24 && (VALUE) <= 31 : \
-   (C) == 'O' ? (VALUE) == 16 : \
-   (C) == 'P' ? (VALUE) >= 8 && (VALUE) <= 15 : \
-   (C) == 'R' ? valid_mov3q_const (VALUE) : 0)
-
-/* "G" defines all of the floating constants that are *NOT* 68881
-   constants.  This is so 68881 constants get reloaded and the
-   fpmovecr is used.  */
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C)  \
-  ((C) == 'G' ? ! (TARGET_68881 && standard_68881_constant_p (VALUE)) : 0 )
-
-/* `Q' means address register indirect addressing mode.
-   `S' is for operands that satisfy 'm' when -mpcrel is in effect.
-   `T' is for operands that satisfy 's' when -mpcrel is not in effect.
-   `U' is for register offset addressing.
-   `W' is for const_call_operands.  */
-#define EXTRA_CONSTRAINT(OP,CODE)                      \
-  ((CODE) == 'S'                                       \
-   ? (TARGET_PCREL                                     \
-      && GET_CODE (OP) == MEM                          \
-      && (GET_CODE (XEXP (OP, 0)) == SYMBOL_REF                \
-         || GET_CODE (XEXP (OP, 0)) == LABEL_REF       \
-         || GET_CODE (XEXP (OP, 0)) == CONST))         \
-   :                                                   \
-   (CODE) == 'T'                                       \
-   ? (!flag_pic                                                \
-      && (GET_CODE (OP) == SYMBOL_REF                  \
-         || GET_CODE (OP) == LABEL_REF                 \
-         || GET_CODE (OP) == CONST))                   \
-   :                                                   \
-   (CODE) == 'Q'                                       \
-   ? m68k_matches_q_p (OP)                             \
-   :                                                   \
-   (CODE) == 'U'                                       \
-   ? m68k_matches_u_p (OP)                             \
-   :                                                   \
-   (CODE) == 'W'                                       \
-   ? const_call_operand (OP, VOIDmode)                 \
-   : 0)
-
 #define PREFERRED_RELOAD_CLASS(X,CLASS) \
   m68k_preferred_reload_class (X, CLASS)
 
@@ -720,16 +666,16 @@ __transfer_from_trampoline ()                                     \
 /* Macros to check register numbers against specific register classes.  */
 
 /* True for data registers, D0 through D7.  */
-#define DATA_REGNO_P(REGNO) ((unsigned int) (REGNO) < 8)
+#define DATA_REGNO_P(REGNO)    IN_RANGE (REGNO, 0, 7)
 
 /* True for address registers, A0 through A7.  */
-#define ADDRESS_REGNO_P(REGNO) (((unsigned int) (REGNO) - 8) < 8)
+#define ADDRESS_REGNO_P(REGNO) IN_RANGE (REGNO, 8, 15)
 
 /* True for integer registers, D0 through D7 and A0 through A7.  */
-#define INT_REGNO_P(REGNO) ((unsigned int) (REGNO) < 16)
+#define INT_REGNO_P(REGNO)     IN_RANGE (REGNO, 0, 15)
 
 /* True for floating point registers, FP0 through FP7.  */
-#define FP_REGNO_P(REGNO) (((unsigned int) (REGNO) - 16) < 8)
+#define FP_REGNO_P(REGNO)      IN_RANGE (REGNO, 16, 23)
 
 #define REGNO_OK_FOR_INDEX_P(REGNO)                    \
   (INT_REGNO_P (REGNO)                                 \
@@ -739,13 +685,15 @@ __transfer_from_trampoline ()                                     \
   (ADDRESS_REGNO_P (REGNO)                             \
    || ADDRESS_REGNO_P (reg_renumber[REGNO]))
 
-#define REGNO_OK_FOR_DATA_P(REGNO)                     \
-  (DATA_REGNO_P (REGNO)                                        \
-   || DATA_REGNO_P (reg_renumber[REGNO]))
+#define REGNO_OK_FOR_INDEX_NONSTRICT_P(REGNO)          \
+  (INT_REGNO_P (REGNO)                                 \
+   || REGNO == ARG_POINTER_REGNUM                      \
+   || REGNO >= FIRST_PSEUDO_REGISTER)
 
-#define REGNO_OK_FOR_FP_P(REGNO)                       \
-  (FP_REGNO_P (REGNO)                                  \
-   || FP_REGNO_P (reg_renumber[REGNO]))
+#define REGNO_OK_FOR_BASE_NONSTRICT_P(REGNO)           \
+  (ADDRESS_REGNO_P (REGNO)                             \
+   || REGNO == ARG_POINTER_REGNUM                      \
+   || REGNO >= FIRST_PSEUDO_REGISTER)
 
 /* Now macros that check whether X is a register and also,
    strictly, whether it is in a specified class.
@@ -755,13 +703,13 @@ __transfer_from_trampoline ()                                     \
    define_optimization.  */
 
 /* 1 if X is a data register.  */
-#define DATA_REG_P(X) (REG_P (X) && REGNO_OK_FOR_DATA_P (REGNO (X)))
+#define DATA_REG_P(X)  (REG_P (X) && DATA_REGNO_P (REGNO (X)))
 
 /* 1 if X is an fp register.  */
-#define FP_REG_P(X) (REG_P (X) && REGNO_OK_FOR_FP_P (REGNO (X)))
+#define FP_REG_P(X)    (REG_P (X) && FP_REGNO_P (REGNO (X)))
 
 /* 1 if X is an address register  */
-#define ADDRESS_REG_P(X) (REG_P (X) && REGNO_OK_FOR_BASE_P (REGNO (X)))
+#define ADDRESS_REG_P(X) (REG_P (X) && ADDRESS_REGNO_P (REGNO (X)))
 \f
 /* True if SYMBOL + OFFSET constants must refer to something within
    SYMBOL's section.  */
@@ -969,8 +917,10 @@ do { if (cc_prev_status.flags & CC_IN_68881)                       \
 #define INCOMING_FRAME_SP_OFFSET 4
 
 /* All registers are live on exit from an interrupt routine.  */
-#define EPILOGUE_USES(REGNO) \
-  (reload_completed && m68k_interrupt_function_p (current_function_decl))
+#define EPILOGUE_USES(REGNO)                                   \
+  (reload_completed                                            \
+   && (m68k_get_function_kind (current_function_decl)  \
+       == m68k_fk_interrupt_handler))
 
 /* Describe how we implement __builtin_eh_return.  */
 #define EH_RETURN_DATA_REGNO(N) \
@@ -1139,6 +1089,7 @@ enum uarch_type
   u68040,
   u68060,
   ucpu32,
+  ucfv1,
   ucfv2,
   ucfv3,
   ucfv4,
@@ -1164,6 +1115,13 @@ enum fpu_type
   FPUTYPE_COLDFIRE
 };
 
+enum m68k_function_kind
+{
+  m68k_fk_normal_function,
+  m68k_fk_interrupt_handler,
+  m68k_fk_interrupt_thread
+};
+
 /* Variables in m68k.c; see there for details.  */
 extern const char *m68k_library_id_string;
 extern int m68k_last_compare_had_fp_operands;
@@ -1173,3 +1131,21 @@ extern enum fpu_type m68k_fpu;
 extern unsigned int m68k_cpu_flags;
 extern const char *m68k_symbolic_call;
 extern const char *m68k_symbolic_jump;
+
+enum M68K_SYMBOLIC_CALL { M68K_SYMBOLIC_CALL_NONE, M68K_SYMBOLIC_CALL_JSR,
+                         M68K_SYMBOLIC_CALL_BSR_C, M68K_SYMBOLIC_CALL_BSR_P };
+
+extern enum M68K_SYMBOLIC_CALL m68k_symbolic_call_var;
+
+/* ??? HOST_WIDE_INT is not being defined for auto-generated files.
+   Workaround that.  */
+#ifdef HOST_WIDE_INT
+typedef enum { MOVL, SWAP, NEGW, NOTW, NOTB, MOVQ, MVS, MVZ }
+  M68K_CONST_METHOD;
+
+extern M68K_CONST_METHOD m68k_const_method (HOST_WIDE_INT);
+#endif
+
+extern void m68k_emit_move_double (rtx [2]);
+
+#define CPU_UNITS_QUERY 1