OSDN Git Service

M68K TLS support.
[pf3gnuchains/gcc-fork.git] / gcc / config / m68k / m68k.h
index a346b81..2d3b592 100644 (file)
@@ -1,6 +1,6 @@
 /* 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, 2007 Free Software Foundation, Inc.
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -29,10 +29,6 @@ along with GCC; see the file COPYING3.  If not see
 # define TARGET_VERSION fprintf (stderr, " (68k, MIT syntax)")
 #endif
 
-/* Options 0 and 1 are the Motorola and MIT syntaxes,
-   respectively.  */
-#define ASSEMBLER_DIALECT      !MOTOROLA
-
 /* Handle --with-cpu default option from configure script.  */
 #define OPTION_DEFAULT_SPECS                                           \
   { "cpu",   "%{!mc68000:%{!m68000:%{!m68302:%{!m68010:%{!mc68020:%{!m68020:\
@@ -236,6 +232,7 @@ along with GCC; see the file COPYING3.  If not see
 #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)
@@ -270,6 +267,11 @@ along with GCC; see the file COPYING3.  If not see
 #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()
 
@@ -320,6 +322,8 @@ along with GCC; see the file COPYING3.  If not see
 #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)
 
 /* Define these to avoid dependence on meaning of `int'.  */
@@ -450,8 +454,6 @@ along with GCC; see the file COPYING3.  If not see
    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.
@@ -513,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.  */
 
@@ -743,7 +750,8 @@ __transfer_from_trampoline ()                                       \
 
 #define LEGITIMATE_PIC_OPERAND_P(X)                            \
   (!symbolic_operand (X, VOIDmode)                             \
-   || (TARGET_PCREL && REG_STRICT_P))
+   || (TARGET_PCREL && REG_STRICT_P)                           \
+   || m68k_tls_reference_p (X, true))
 
 #define REG_OK_FOR_BASE_P(X) \
   m68k_legitimate_base_reg_p (X, REG_STRICT_P)
@@ -751,71 +759,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
 
@@ -849,6 +795,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;                                              \
@@ -975,11 +929,17 @@ do { if (cc_prev_status.flags & CC_IN_68881)                      \
 #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)  \
   sprintf (LABEL, "*%s%s%ld", LOCAL_LABEL_PREFIX, PREFIX, (long)(NUM))
 
-#define ASM_OUTPUT_REG_PUSH(FILE,REGNO)                                          \
-  asm_fprintf (FILE, "\tmove%.l %s,{-(%Rsp)|%Rsp@-}\n", reg_names[REGNO])
+#define ASM_OUTPUT_REG_PUSH(FILE,REGNO)                        \
+  asm_fprintf (FILE, (MOTOROLA                         \
+                     ? "\tmove.l %s,-(%Rsp)\n"         \
+                     : "\tmovel %s,%Rsp@-\n"),         \
+              reg_names[REGNO])
 
-#define ASM_OUTPUT_REG_POP(FILE,REGNO)                                      \
-  asm_fprintf (FILE, "\tmove%.l {(%Rsp)+|%Rsp@+},%s\n", reg_names[REGNO])
+#define ASM_OUTPUT_REG_POP(FILE,REGNO)                 \
+  asm_fprintf (FILE, (MOTOROLA                         \
+                     ? "\tmove.l (%Rsp)+,%s\n"         \
+                     : "\tmovel %Rsp@+,%s\n"),         \
+              reg_names[REGNO])
 
 /* The m68k does not use absolute case-vectors, but we must define this macro
    anyway.  */
@@ -1008,39 +968,8 @@ 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)
+#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
+  m68k_final_prescan_insn (INSN, OPVEC, NOPERANDS)
 
 /* On the 68000, we use several CODE characters:
    '.' for dot needed in Motorola-style opcode names.
@@ -1057,8 +986,6 @@ do { if (cc_prev_status.flags & CC_IN_68881)                       \
    '&' for the letter `d' in an op code, but only on the 68040.
    '/' for register prefix needed by longlong.h.
    '?' for m68k_library_id_string
-   '{' for '{'
-   '}' for '}'
 
    'b' for byte insn (no effect, on the Sun; this is for the ISI).
    'd' to force memory addressing to be absolute, not relative.
@@ -1069,8 +996,7 @@ do { if (cc_prev_status.flags & CC_IN_68881)                       \
 #define PRINT_OPERAND_PUNCT_VALID_P(CODE)                              \
   ((CODE) == '.' || (CODE) == '#' || (CODE) == '-'                     \
    || (CODE) == '+' || (CODE) == '@' || (CODE) == '!'                  \
-   || (CODE) == '$' || (CODE) == '&' || (CODE) == '/' || (CODE) == '?' \
-   || (CODE) == '{' || (CODE) == '}')
+   || (CODE) == '$' || (CODE) == '&' || (CODE) == '/' || (CODE) == '?')
 
 
 /* See m68k.c for the m68k specific codes.  */
@@ -1078,6 +1004,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
 {
@@ -1125,11 +1057,11 @@ 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;
 
@@ -1149,10 +1081,7 @@ extern M68K_CONST_METHOD m68k_const_method (HOST_WIDE_INT);
 
 extern void m68k_emit_move_double (rtx [2]);
 
-extern enum attr_cpu m68k_sched_cpu;
+extern int m68k_sched_address_bypass_p (rtx, rtx);
+extern int m68k_sched_indexed_address_bypass_p (rtx, rtx);
 
-extern enum attr_opx_type m68k_sched_attr_opx_type (rtx, int);
-extern enum attr_opy_type m68k_sched_attr_opy_type (rtx, int);
-extern int m68k_sched_attr_size (rtx);
-extern enum attr_op_mem m68k_sched_attr_op_mem (rtx);
-extern enum attr_type m68k_sched_branch_type (rtx);
+#define CPU_UNITS_QUERY 1