OSDN Git Service

2009-05-14 Paolo Bonzini <bonzini@gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / config / m68k / m68k.h
index 1b19b4c..e91ab00 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, 2008 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;                                                        \
@@ -225,6 +232,7 @@ Boston, MA 02110-1301, USA.  */
 #define FL_ISA_C     (1 << 16)
 #define FL_FIDOA     (1 << 17)
 #define FL_MMU              0   /* Used by multilib machinery.  */
+#define FL_UCLINUX   0   /* Used by multilib machinery.  */
 
 #define TARGET_68010           ((m68k_cpu_flags & FL_ISA_68010) != 0)
 #define TARGET_68020           ((m68k_cpu_flags & FL_ISA_68020) != 0)
@@ -241,6 +249,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,7 +265,13 @@ 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 TUNE_CFV3       (m68k_tune == ucfv3)
+#define TUNE_CFV4       (m68k_tune == ucfv4 || m68k_tune == ucfv4e)
+
+#define TUNE_MAC       ((m68k_tune_flags & FL_CF_MAC) != 0)
+#define TUNE_EMAC      ((m68k_tune_flags & FL_CF_EMAC) != 0)
 
 #define OVERRIDE_OPTIONS   override_options()
 
@@ -298,11 +316,13 @@ 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 DWARF_CIE_DATA_ALIGNMENT -2
 
 #define INT_TYPE_SIZE (TARGET_SHORT ? 16 : 32)
 
@@ -434,8 +454,6 @@ Boston, MA 02110-1301, USA.  */
    pointer is shifted to %a5 on this target.  */
 #define FRAME_POINTER_REGNUM A6_REG
 
-#define FRAME_POINTER_REQUIRED 0
-
 /* Base register for access to arguments of the function.
  * This isn't a hardware register. It will be eliminated to the
  * stack pointer or frame pointer.
@@ -497,6 +515,11 @@ extern enum reg_class regno_reg_class[];
 /* Moves between fp regs and other regs are two insns.  */
 #define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2)       \
   ((((CLASS1) == FP_REGS) != ((CLASS2) == FP_REGS)) ? 4 : 2)
+
+#define IRA_COVER_CLASSES                                              \
+{                                                                      \
+  ALL_REGS, LIM_REG_CLASSES                                            \
+}
 \f
 /* Stack layout; function entry, exit and calling.  */
 
@@ -654,16 +677,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)                                 \
@@ -673,13 +696,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.
@@ -689,13 +714,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.  */
@@ -733,71 +758,9 @@ __transfer_from_trampoline ()                                      \
 #define REG_OK_FOR_INDEX_P(X) \
   m68k_legitimate_index_reg_p (X, REG_STRICT_P)
 
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)                                \
-  do                                                                   \
-    {                                                                  \
-      if (m68k_legitimate_address_p (MODE, X, REG_STRICT_P))           \
-        goto ADDR;                                                     \
-    }                                                                  \
-  while (0)
-
-/* Don't call memory_address_noforce for the address to fetch
-   the switch offset.  This address is ok as it stands,
-   but memory_address_noforce would alter it.  */
-#define PIC_CASE_VECTOR_ADDRESS(index) index
-\f
-/* For the 68000, we handle X+REG by loading X into a register R and
-   using R+REG.  R will go in an address reg and indexing will be used.
-   However, if REG is a broken-out memory address or multiplication,
-   nothing needs to be done because REG can certainly go in an address reg.  */
-#define COPY_ONCE(Y) if (!copied) { Y = copy_rtx (Y); copied = ch = 1; }
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)   \
-{ register int ch = (X) != (OLDX);                                     \
-  if (GET_CODE (X) == PLUS)                                            \
-    { int copied = 0;                                                  \
-      if (GET_CODE (XEXP (X, 0)) == MULT)                              \
-       { COPY_ONCE (X); XEXP (X, 0) = force_operand (XEXP (X, 0), 0);} \
-      if (GET_CODE (XEXP (X, 1)) == MULT)                              \
-       { COPY_ONCE (X); XEXP (X, 1) = force_operand (XEXP (X, 1), 0);} \
-      if (ch && GET_CODE (XEXP (X, 1)) == REG                          \
-         && GET_CODE (XEXP (X, 0)) == REG)                             \
-       { if (TARGET_COLDFIRE_FPU                                       \
-             && GET_MODE_CLASS (MODE) == MODE_FLOAT)                   \
-           { COPY_ONCE (X); X = force_operand (X, 0);}                 \
-         goto WIN; }                                                   \
-      if (ch) { GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN); }             \
-      if (GET_CODE (XEXP (X, 0)) == REG                                        \
-              || (GET_CODE (XEXP (X, 0)) == SIGN_EXTEND                \
-                  && GET_CODE (XEXP (XEXP (X, 0), 0)) == REG           \
-                  && GET_MODE (XEXP (XEXP (X, 0), 0)) == HImode))      \
-       { register rtx temp = gen_reg_rtx (Pmode);                      \
-         register rtx val = force_operand (XEXP (X, 1), 0);            \
-         emit_move_insn (temp, val);                                   \
-         COPY_ONCE (X);                                                \
-         XEXP (X, 1) = temp;                                           \
-         if (TARGET_COLDFIRE_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT \
-             && GET_CODE (XEXP (X, 0)) == REG)                         \
-           X = force_operand (X, 0);                                   \
-         goto WIN; }                                                   \
-      else if (GET_CODE (XEXP (X, 1)) == REG                           \
-              || (GET_CODE (XEXP (X, 1)) == SIGN_EXTEND                \
-                  && GET_CODE (XEXP (XEXP (X, 1), 0)) == REG           \
-                  && GET_MODE (XEXP (XEXP (X, 1), 0)) == HImode))      \
-       { register rtx temp = gen_reg_rtx (Pmode);                      \
-         register rtx val = force_operand (XEXP (X, 0), 0);            \
-         emit_move_insn (temp, val);                                   \
-         COPY_ONCE (X);                                                \
-         XEXP (X, 0) = temp;                                           \
-         if (TARGET_COLDFIRE_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT \
-             && GET_CODE (XEXP (X, 1)) == REG)                         \
-           X = force_operand (X, 0);                                   \
-         goto WIN; }}}
-
-/* On the 68000, only predecrement and postincrement address depend thus
-   (the amount of decrement or increment being the length of the operand).
-   These are now treated generically in recog.c.  */
-#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)
 \f
+/* This address is OK as it stands.  */
+#define PIC_CASE_VECTOR_ADDRESS(index) index
 #define CASE_VECTOR_MODE HImode
 #define CASE_VECTOR_PC_RELATIVE 1
 
@@ -831,6 +794,14 @@ __transfer_from_trampoline ()                                      \
    some or all of the saved cc's so they won't be used.  */
 #define NOTICE_UPDATE_CC(EXP,INSN) notice_update_cc (EXP, INSN)
 
+/* The shift instructions always clear the overflow bit.  */
+#define CC_OVERFLOW_UNUSABLE 01000
+
+/* The shift instructions use the carry bit in a way not compatible with
+   conditional branches.  conditions.h uses CC_NO_OVERFLOW for this purpose.
+   Rename it to something more understandable.  */
+#define CC_NO_CARRY CC_NO_OVERFLOW
+
 #define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV)  \
 do { if (cc_prev_status.flags & CC_IN_68881)                   \
     return FLOAT;                                              \
@@ -996,40 +967,6 @@ do { if (cc_prev_status.flags & CC_IN_68881)                       \
   assemble_name ((FILE), (NAME)),              \
   fprintf ((FILE), ",%u\n", (int)(ROUNDED)))
 
-/* Output a float value (represented as a C double) as an immediate operand.
-   This macro is m68k-specific.  */
-#define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE)              \
- do {                                                          \
-      if (CODE == 'f')                                         \
-        {                                                      \
-          char dstr[30];                                       \
-         real_to_decimal (dstr, &(VALUE), sizeof (dstr), 9, 0); \
-          asm_fprintf ((FILE), "%I0r%s", dstr);                        \
-        }                                                      \
-      else                                                     \
-        {                                                      \
-          long l;                                              \
-          REAL_VALUE_TO_TARGET_SINGLE (VALUE, l);              \
-          asm_fprintf ((FILE), "%I0x%lx", l);                  \
-        }                                                      \
-     } while (0)
-
-/* Output a double value (represented as a C double) as an immediate operand.
-   This macro is m68k-specific.  */
-#define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE)                          \
- do { char dstr[30];                                                   \
-      real_to_decimal (dstr, &(VALUE), sizeof (dstr), 0, 1);           \
-      asm_fprintf (FILE, "%I0r%s", dstr);                              \
-    } while (0)
-
-/* Note, long double immediate operands are not actually
-   generated by m68k.md.  */
-#define ASM_OUTPUT_LONG_DOUBLE_OPERAND(FILE,VALUE)                     \
- do { char dstr[30];                                                   \
-      real_to_decimal (dstr, &(VALUE), sizeof (dstr), 0, 1);           \
-      asm_fprintf (FILE, "%I0r%s", dstr);                              \
-    } while (0)
-
 /* On the 68000, we use several CODE characters:
    '.' for dot needed in Motorola-style opcode names.
    '-' for an operand pushing on the stack:
@@ -1063,6 +1000,12 @@ do { if (cc_prev_status.flags & CC_IN_68881)                     \
 
 #define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
 
+#define OUTPUT_ADDR_CONST_EXTRA(FILE, X, FAIL)         \
+do {                                                   \
+  if (! m68k_output_addr_const_extra (FILE, (X)))      \
+    goto FAIL;                                         \
+} while (0);
+
 /* Values used in the MICROARCH argument to M68K_DEVICE.  */
 enum uarch_type
 {
@@ -1075,6 +1018,7 @@ enum uarch_type
   u68040,
   u68060,
   ucpu32,
+  ucfv1,
   ucfv2,
   ucfv3,
   ucfv4,
@@ -1109,10 +1053,31 @@ enum m68k_function_kind
 
 /* Variables in m68k.c; see there for details.  */
 extern const char *m68k_library_id_string;
-extern int m68k_last_compare_had_fp_operands;
 extern enum target_device m68k_cpu;
 extern enum uarch_type m68k_tune;
 extern enum fpu_type m68k_fpu;
 extern unsigned int m68k_cpu_flags;
+extern unsigned int m68k_tune_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]);
+
+extern int m68k_sched_address_bypass_p (rtx, rtx);
+extern int m68k_sched_indexed_address_bypass_p (rtx, rtx);
+
+#define CPU_UNITS_QUERY 1