OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / config / xtensa / xtensa.h
index 11c4184..ee528ef 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions of Tensilica's Xtensa target machine for GNU compiler.
-   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
 
@@ -7,7 +7,7 @@ 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) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -16,30 +16,14 @@ 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/>.  */
 
 /* Get Xtensa configuration settings */
 #include "xtensa-config.h"
 
-/* Standard GCC variables that we reference.  */
-extern int current_function_calls_alloca;
-extern int optimize;
-
 /* External variables defined in xtensa.c.  */
 
-/* comparison type */
-enum cmp_type {
-  CMP_SI,                              /* four byte integers */
-  CMP_DI,                              /* eight byte integers */
-  CMP_SF,                              /* single precision floats */
-  CMP_DF,                              /* double precision floats */
-  CMP_MAX                              /* max comparison type */
-};
-
-extern struct rtx_def * branch_cmp[2]; /* operands for compare */
-extern enum cmp_type branch_type;      /* what type of branch to use */
 extern unsigned xtensa_current_frame_size;
 
 /* Macros used in the machine description to select various Xtensa
@@ -47,6 +31,15 @@ extern unsigned xtensa_current_frame_size;
 #ifndef XCHAL_HAVE_MUL32_HIGH
 #define XCHAL_HAVE_MUL32_HIGH 0
 #endif
+#ifndef XCHAL_HAVE_RELEASE_SYNC
+#define XCHAL_HAVE_RELEASE_SYNC 0
+#endif
+#ifndef XCHAL_HAVE_S32C1I
+#define XCHAL_HAVE_S32C1I 0
+#endif
+#ifndef XCHAL_HAVE_THREADPTR
+#define XCHAL_HAVE_THREADPTR 0
+#endif
 #define TARGET_BIG_ENDIAN      XCHAL_HAVE_BE
 #define TARGET_DENSITY         XCHAL_HAVE_DENSITY
 #define TARGET_MAC16           XCHAL_HAVE_MAC16
@@ -65,23 +58,18 @@ extern unsigned xtensa_current_frame_size;
 #define TARGET_HARD_FLOAT_RSQRT        XCHAL_HAVE_FP_RSQRT
 #define TARGET_ABS             XCHAL_HAVE_ABS
 #define TARGET_ADDX            XCHAL_HAVE_ADDX
+#define TARGET_RELEASE_SYNC    XCHAL_HAVE_RELEASE_SYNC
+#define TARGET_S32C1I          XCHAL_HAVE_S32C1I
+#define TARGET_ABSOLUTE_LITERALS XSHAL_USE_ABSOLUTE_LITERALS
+#define TARGET_THREADPTR       XCHAL_HAVE_THREADPTR
 
-#define TARGET_DEFAULT (                                               \
-  (XCHAL_HAVE_L32R     ? 0 : MASK_CONST16))
-
-#define OVERRIDE_OPTIONS override_options ()
+#define TARGET_DEFAULT \
+  ((XCHAL_HAVE_L32R    ? 0 : MASK_CONST16) |                           \
+   MASK_SERIALIZE_VOLATILE)
 
-/* Reordering blocks for Xtensa is not a good idea unless the compiler
-   understands the range of conditional branches.  Currently all branch
-   relaxation for Xtensa is handled in the assembler, so GCC cannot do a
-   good job of reordering blocks.  Do not enable reordering unless it is
-   explicitly requested.  */
-#define OPTIMIZATION_OPTIONS(LEVEL, SIZE)                              \
-  do                                                                   \
-    {                                                                  \
-      flag_reorder_blocks = 0;                                         \
-    }                                                                  \
-  while (0)
+#ifndef HAVE_AS_TLS
+#define HAVE_AS_TLS 0
+#endif
 
 \f
 /* Target CPU builtins.  */
@@ -106,16 +94,6 @@ extern unsigned xtensa_current_frame_size;
 #define EXTRA_SPECS                                                    \
   { "subtarget_cpp_spec", SUBTARGET_CPP_SPEC },
 
-#ifdef __XTENSA_EB__
-#define LIBGCC2_WORDS_BIG_ENDIAN 1
-#else
-#define LIBGCC2_WORDS_BIG_ENDIAN 0
-#endif
-
-/* Show we can debug even without a frame pointer.  */
-#define CAN_DEBUG_WITHOUT_FP
-
-
 /* Target machine storage layout */
 
 /* Define this if most significant bit is lowest numbered
@@ -281,7 +259,7 @@ extern unsigned xtensa_current_frame_size;
    incoming argument in a2 is live throughout the function and
    local-alloc decides to use a2, then the incoming argument must
    either be spilled or copied to another register.  To get around
-   this, we define ORDER_REGS_FOR_LOCAL_ALLOC to redefine
+   this, we define ADJUST_REG_ALLOC_ORDER to redefine
    reg_alloc_order for leaf functions such that lowest numbered
    registers are used first with the exception that the incoming
    argument registers are not used until after other register choices
@@ -295,7 +273,7 @@ extern unsigned xtensa_current_frame_size;
   35, \
 }
 
-#define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc ()
+#define ADJUST_REG_ALLOC_ORDER order_regs_for_local_alloc ()
 
 /* For Xtensa, the only point of this is to prevent GCC from otherwise
    giving preference to call-used registers.  To minimize window
@@ -375,26 +353,9 @@ extern char xtensa_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER];
    either the stack pointer or the hard frame pointer.  */
 #define FRAME_POINTER_REGNUM (GP_REG_FIRST + 16)
 
-/* Value should be nonzero if functions must have frame pointers.
-   Zero means the frame pointer need not be set up (and parms
-   may be accessed via the stack pointer) in functions that seem suitable.
-   This is computed in 'reload', in reload1.c.  */
-#define FRAME_POINTER_REQUIRED xtensa_frame_pointer_required ()
-
 /* Base register for access to arguments of the function.  */
 #define ARG_POINTER_REGNUM (GP_REG_FIRST + 17)
 
-/* If the static chain is passed in memory, these macros provide rtx
-   giving 'mem' expressions that denote where they are stored.
-   'STATIC_CHAIN' and 'STATIC_CHAIN_INCOMING' give the locations as
-   seen by the calling and called functions, respectively.  */
-
-#define STATIC_CHAIN                                                   \
-  gen_rtx_MEM (Pmode, plus_constant (stack_pointer_rtx, -5 * UNITS_PER_WORD))
-
-#define STATIC_CHAIN_INCOMING                                          \
-  gen_rtx_MEM (Pmode, plus_constant (arg_pointer_rtx, -5 * UNITS_PER_WORD))
-
 /* For now we don't try to use the full set of boolean registers.  Without
    software pipelining of FP operations, there's not much to gain and it's
    a real pain to get them reloaded.  */
@@ -471,6 +432,11 @@ enum reg_class
   { 0xffffffff, 0x0000000f }  /* all registers */ \
 }
 
+#define IRA_COVER_CLASSES                                              \
+{                                                                      \
+  BR_REGS, FP_REGS, ACC_REG, AR_REGS, LIM_REG_CLASSES                  \
+}
+
 /* A C expression whose value is a register class containing hard
    register REGNO.  In general there is more that one such class;
    choose a class which is "minimal", meaning that no smaller class
@@ -484,10 +450,10 @@ extern const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER];
 #define BASE_REG_CLASS AR_REGS
 #define INDEX_REG_CLASS NO_REGS
 
-/* SMALL_REGISTER_CLASSES is required for Xtensa, because all of the
-   16 AR registers may be explicitly used in the RTL, as either
-   incoming or outgoing arguments.  */
-#define SMALL_REGISTER_CLASSES 1
+/* The small_register_classes_for_mode_p hook must always return true for
+   Xtrnase, because all of the 16 AR registers may be explicitly used in
+   the RTL, as either incoming or outgoing arguments.  */
+#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
 
 #define PREFERRED_RELOAD_CLASS(X, CLASS)                               \
   xtensa_preferred_reload_class (X, CLASS, 0)
@@ -495,12 +461,6 @@ extern const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER];
 #define PREFERRED_OUTPUT_RELOAD_CLASS(X, CLASS)                                \
   xtensa_preferred_reload_class (X, CLASS, 1)
   
-#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X)                   \
-  xtensa_secondary_reload_class (CLASS, MODE, X, 0)
-
-#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X)                  \
-  xtensa_secondary_reload_class (CLASS, MODE, X, 1)
-
 /* Return the maximum number of consecutive registers
    needed to represent mode MODE in a register of class CLASS.  */
 #define CLASS_UNITS(mode, size)                                                \
@@ -516,7 +476,7 @@ extern const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER];
 
 /* Offset within stack frame to start allocating local variables at.  */
 #define STARTING_FRAME_OFFSET                                          \
-  current_function_outgoing_args_size
+  crtl->outgoing_args_size
 
 /* The ARG_POINTER and FRAME_POINTER are not real Xtensa registers, so
    they are eliminated to either the stack pointer or hard frame pointer.  */
@@ -526,8 +486,6 @@ extern const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER];
  { FRAME_POINTER_REGNUM,       STACK_POINTER_REGNUM},                  \
  { FRAME_POINTER_REGNUM,       HARD_FRAME_POINTER_REGNUM}}
 
-#define CAN_ELIMINATE(FROM, TO) 1
-
 /* Specify the initial difference between the specified pair of registers.  */
 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)                   \
   do {                                                                 \
@@ -547,7 +505,7 @@ extern const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER];
 
 /* If defined, the maximum amount of space required for outgoing
    arguments will be computed and placed into the variable
-   'current_function_outgoing_args_size'.  No space will be pushed
+   'crtl->outgoing_args_size'.  No space will be pushed
    onto the stack for each call; instead, the function prologue
    should increase the stack frame size by this amount.  */
 #define ACCUMULATE_OUTGOING_ARGS 1
@@ -562,9 +520,6 @@ extern const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER];
    128-bit datatypes defined in TIE (e.g., for Vectra).  */
 #define STACK_BOUNDARY 128
 
-/* Functions do not pop arguments off the stack.  */
-#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE) 0
-
 /* Use a fixed register window size of 8.  */
 #define WINDOW_SIZE 8
 
@@ -586,7 +541,7 @@ extern const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER];
 
 /* Define how to find the value returned by a library function
    assuming the value has mode MODE.  Because we have defined
-   TARGET_PROMOTE_FUNCTION_RETURN that returns true, we have to
+   TARGET_PROMOTE_FUNCTION_MODE to promote everything, we have to
    perform the same promotions as PROMOTE_MODE.  */
 #define XTENSA_LIBCALL_VALUE(MODE, OUTGOINGP)                          \
   gen_rtx_REG ((GET_MODE_CLASS (MODE) == MODE_INT                      \
@@ -600,22 +555,6 @@ extern const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER];
 #define LIBCALL_OUTGOING_VALUE(MODE)                                   \
   XTENSA_LIBCALL_VALUE ((MODE), 1)
 
-/* Define how to find the value returned by a function.
-   VALTYPE is the data type of the value (as a tree).
-   If the precise function being called is known, FUNC is its FUNCTION_DECL;
-   otherwise, FUNC is 0.  */
-#define XTENSA_FUNCTION_VALUE(VALTYPE, FUNC, OUTGOINGP)                        \
-  gen_rtx_REG ((INTEGRAL_TYPE_P (VALTYPE)                              \
-               && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)            \
-              ? SImode: TYPE_MODE (VALTYPE),                           \
-              OUTGOINGP ? GP_OUTGOING_RETURN : GP_RETURN)
-
-#define FUNCTION_VALUE(VALTYPE, FUNC)                                  \
-  XTENSA_FUNCTION_VALUE (VALTYPE, FUNC, 0)
-
-#define FUNCTION_OUTGOING_VALUE(VALTYPE, FUNC)                         \
-  XTENSA_FUNCTION_VALUE (VALTYPE, FUNC, 1)
-
 /* A C expression that is nonzero if REGNO is the number of a hard
    register in which the values of called function may come back.  A
    register whose use for returning values is limited to serving as
@@ -652,18 +591,6 @@ typedef struct xtensa_args
 #define INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME)            \
   init_cumulative_args (&CUM, 1)
 
-/* Update the data in CUM to advance over an argument
-   of mode MODE and data type TYPE.
-   (TYPE is null for libcalls where that information may not be available.)  */
-#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)                   \
-  function_arg_advance (&CUM, MODE, TYPE)
-
-#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
-  function_arg (&CUM, MODE, TYPE, FALSE)
-
-#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
-  function_arg (&CUM, MODE, TYPE, TRUE)
-
 #define FUNCTION_ARG_BOUNDARY function_arg_boundary
 
 /* Profiling Xtensa code is typically done with the built-in profiling
@@ -697,87 +624,12 @@ typedef struct xtensa_args
 /* Stack pointer value doesn't matter at exit.  */
 #define EXIT_IGNORE_STACK 1
 
-/* A C statement to output, on the stream FILE, assembler code for a
-   block of data that contains the constant parts of a trampoline. 
-   This code should not include a label--the label is taken care of
-   automatically.
-
-   For Xtensa, the trampoline must perform an entry instruction with a
-   minimal stack frame in order to get some free registers.  Once the
-   actual call target is known, the proper stack frame size is extracted
-   from the entry instruction at the target and the current frame is
-   adjusted to match.  The trampoline then transfers control to the
-   instruction following the entry at the target.  Note: this assumes
-   that the target begins with an entry instruction.  */
-
-/* minimum frame = reg save area (4 words) plus static chain (1 word)
-   and the total number of words must be a multiple of 128 bits */
-#define MIN_FRAME_SIZE (8 * UNITS_PER_WORD)
-
-#define TRAMPOLINE_TEMPLATE(STREAM)                                    \
-  do {                                                                 \
-    fprintf (STREAM, "\t.begin no-transform\n");                       \
-    fprintf (STREAM, "\tentry\tsp, %d\n", MIN_FRAME_SIZE);             \
-                                                                       \
-    /* save the return address */                                      \
-    fprintf (STREAM, "\tmov\ta10, a0\n");                              \
-                                                                       \
-    /* Use a CALL0 instruction to skip past the constants and in the   \
-       process get the PC into A0.  This allows PC-relative access to  \
-       the constants without relying on L32R, which may not always be  \
-       available.  */                                                  \
-                                                                       \
-    fprintf (STREAM, "\tcall0\t.Lskipconsts\n");                       \
-    fprintf (STREAM, "\t.align\t4\n");                                 \
-    fprintf (STREAM, ".Lchainval:%s0\n", integer_asm_op (4, TRUE));    \
-    fprintf (STREAM, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE));      \
-    fprintf (STREAM, ".Lskipconsts:\n");                               \
-                                                                       \
-    /* store the static chain */                                       \
-    fprintf (STREAM, "\taddi\ta0, a0, 3\n");                           \
-    fprintf (STREAM, "\tl32i\ta8, a0, 0\n");                           \
-    fprintf (STREAM, "\ts32i\ta8, sp, %d\n", MIN_FRAME_SIZE - 20);     \
-                                                                       \
-    /* set the proper stack pointer value */                           \
-    fprintf (STREAM, "\tl32i\ta8, a0, 4\n");                           \
-    fprintf (STREAM, "\tl32i\ta9, a8, 0\n");                           \
-    fprintf (STREAM, "\textui\ta9, a9, %d, 12\n",                      \
-            TARGET_BIG_ENDIAN ? 8 : 12);                               \
-    fprintf (STREAM, "\tslli\ta9, a9, 3\n");                           \
-    fprintf (STREAM, "\taddi\ta9, a9, %d\n", -MIN_FRAME_SIZE);         \
-    fprintf (STREAM, "\tsub\ta9, sp, a9\n");                           \
-    fprintf (STREAM, "\tmovsp\tsp, a9\n");                             \
-                                                                       \
-    /* restore the return address */                                   \
-    fprintf (STREAM, "\tmov\ta0, a10\n");                              \
-                                                                       \
-    /* jump to the instruction following the entry */                  \
-    fprintf (STREAM, "\taddi\ta8, a8, 3\n");                           \
-    fprintf (STREAM, "\tjx\ta8\n");                                    \
-    fprintf (STREAM, "\t.byte\t0\n");                                  \
-    fprintf (STREAM, "\t.end no-transform\n");                         \
-  } while (0)
-
 /* Size in bytes of the trampoline, as an integer.  Make sure this is
    a multiple of TRAMPOLINE_ALIGNMENT to avoid -Wpadded warnings.  */
-#define TRAMPOLINE_SIZE 60
+#define TRAMPOLINE_SIZE (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS ? 60 : 52)
 
 /* Alignment required for trampolines, in bits.  */
-#define TRAMPOLINE_ALIGNMENT (32)
-
-/* A C statement to initialize the variable parts of a trampoline.  */
-#define INITIALIZE_TRAMPOLINE(ADDR, FUNC, CHAIN)                       \
-  do {                                                                 \
-    rtx addr = ADDR;                                                   \
-    emit_move_insn (gen_rtx_MEM (SImode, plus_constant (addr, 12)), CHAIN); \
-    emit_move_insn (gen_rtx_MEM (SImode, plus_constant (addr, 16)), FUNC); \
-    emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_sync_caches"), \
-                      0, VOIDmode, 1, addr, Pmode);                    \
-  } while (0)
-
-/* Implement `va_start' for varargs and stdarg.  */
-#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
-  xtensa_va_start (valist, nextarg)
+#define TRAMPOLINE_ALIGNMENT 32
 
 /* If defined, a C expression that produces the machine-specific code
    to setup the stack so that arbitrary frames can be accessed.
@@ -851,13 +703,6 @@ typedef struct xtensa_args
 /* Maximum number of registers that can appear in a valid memory address.  */
 #define MAX_REGS_PER_ADDRESS 1
 
-/* Identify valid Xtensa addresses.  */
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, ADDR, LABEL)                    \
-  do {                                                                 \
-    if (xtensa_legitimate_address_p (MODE, ADDR, REG_OK_STRICT_FLAG))  \
-      goto LABEL;                                                      \
-  } while (0)
-
 /* A C expression that is 1 if the RTX X is a constant which is a
    valid address.  This is defined to be the same as 'CONSTANT_P (X)',
    but rejecting CONST_DOUBLE.  */
@@ -868,7 +713,7 @@ typedef struct xtensa_args
 
 /* Nonzero if the constant value X is a legitimate general operand.
    It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
-#define LEGITIMATE_CONSTANT_P(X) 1
+#define LEGITIMATE_CONSTANT_P(X) (! xtensa_tls_referenced_p (X))
 
 /* A C expression that is nonzero if X is a legitimate immediate
    operand on the target machine when generating position independent
@@ -879,17 +724,6 @@ typedef struct xtensa_args
    && GET_CODE (X) != LABEL_REF                                                \
    && GET_CODE (X) != CONST)
 
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)                         \
-  do {                                                                 \
-    rtx new_x = xtensa_legitimize_address (X, OLDX, MODE);             \
-    if (new_x)                                                         \
-      {                                                                        \
-       X = new_x;                                                      \
-       goto WIN;                                                       \
-      }                                                                        \
-  } while (0)
-
-
 /* Treat constant-pool references as "mode dependent" since they can
    only be accessed with SImode loads.  This works around a bug in the
    combiner where a constant pool reference is temporarily converted
@@ -958,7 +792,7 @@ typedef struct xtensa_args
 
 #define MEMORY_MOVE_COST(MODE, CLASS, IN) 4
 
-#define BRANCH_COST 3
+#define BRANCH_COST(speed_p, predictable_p) 3
 
 /* How to refer to registers in assembler output.
    This sequence is indexed by compiler's hard-register-number (see above).  */
@@ -1055,8 +889,28 @@ typedef struct xtensa_args
 /* How to start an assembler comment.  */
 #define ASM_COMMENT_START "#"
 
-/* Exception handling TODO!! */
-#define DWARF_UNWIND_INFO 0
+/* Exception handling.  Xtensa uses much of the standard DWARF2 unwinding
+   machinery, but the variable size register window save areas are too
+   complicated to efficiently describe with CFI entries.  The CFA must
+   still be specified in DWARF so that DW_AT_frame_base is set correctly
+   for debugging.  */
+#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, 0)
+#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (0)
+#define DWARF_FRAME_REGISTERS 16
+#define EH_RETURN_DATA_REGNO(N) ((N) < 2 ? (N) + 2 : INVALID_REGNUM)
+#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL)                     \
+  (flag_pic                                                            \
+   ? (((GLOBAL) ? DW_EH_PE_indirect : 0)                               \
+      | DW_EH_PE_pcrel | DW_EH_PE_sdata4)                              \
+   : DW_EH_PE_absptr)
+
+/* Emit a PC-relative relocation.  */
+#define ASM_OUTPUT_DWARF_PCREL(FILE, SIZE, LABEL)                      \
+  do {                                                                 \
+    fputs (integer_asm_op (SIZE, FALSE), FILE);                                \
+    assemble_name (FILE, LABEL);                                       \
+    fputs ("@pcrel", FILE);                                            \
+  } while (0)
 
 /* Xtensa constant pool breaks the devices in crtstuff.c to control
    section in where code resides.  We have to write it as asm code.  Use