OSDN Git Service

* configure.ac: Add HAVE_AS_TLS check for Xtensa.
[pf3gnuchains/gcc-fork.git] / gcc / config / xtensa / xtensa.h
index cc6d1b2..1427fd0 100644 (file)
@@ -1,12 +1,13 @@
 /* Definitions of Tensilica's Xtensa target machine for GNU compiler.
-   Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   Free Software Foundation, Inc.
    Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
 
 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
@@ -15,16 +16,13 @@ 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, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, 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 target_flags;
 extern int optimize;
 
 /* External variables defined in xtensa.c.  */
@@ -42,17 +40,26 @@ 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;
 
-/* Masks for the -m switches */
-#define MASK_NO_FUSED_MADD     0x00000001      /* avoid f-p mul/add */
-#define MASK_CONST16           0x00000002      /* use CONST16 instruction */
-
 /* Macros used in the machine description to select various Xtensa
    configuration options.  */
+#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
 #define TARGET_MUL16           XCHAL_HAVE_MUL16
 #define TARGET_MUL32           XCHAL_HAVE_MUL32
+#define TARGET_MUL32_HIGH      XCHAL_HAVE_MUL32_HIGH
 #define TARGET_DIV32           XCHAL_HAVE_DIV32
 #define TARGET_NSA             XCHAL_HAVE_NSA
 #define TARGET_MINMAX          XCHAL_HAVE_MINMAX
@@ -65,56 +72,45 @@ 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
 
-/* Macros controlled by command-line options.  */
-#define TARGET_NO_FUSED_MADD   (target_flags & MASK_NO_FUSED_MADD)
-#define TARGET_CONST16         (target_flags & MASK_CONST16)
+#define TARGET_DEFAULT \
+  ((XCHAL_HAVE_L32R    ? 0 : MASK_CONST16) |                           \
+   MASK_SERIALIZE_VOLATILE)
 
-#define TARGET_DEFAULT (                                               \
-  (XCHAL_HAVE_L32R     ? 0 : MASK_CONST16))
+#ifndef HAVE_AS_TLS
+#define HAVE_AS_TLS 0
+#endif
 
-#define TARGET_SWITCHES                                                        \
-{                                                                      \
-  {"const16",                  MASK_CONST16,                           \
-    N_("Use CONST16 instruction to load constants")},                  \
-  {"no-const16",               -MASK_CONST16,                          \
-    N_("Use PC-relative L32R instruction to load constants")},         \
-  {"no-fused-madd",            MASK_NO_FUSED_MADD,                     \
-    N_("Disable fused multiply/add and multiply/subtract FP instructions")}, \
-  {"fused-madd",               -MASK_NO_FUSED_MADD,                    \
-    N_("Enable fused multiply/add and multiply/subtract FP instructions")}, \
-  {"text-section-literals",    0,                                      \
-    N_("Intersperse literal pools with code in the text section")},    \
-  {"no-text-section-literals", 0,                                      \
-    N_("Put literal pools in a separate literal section")},            \
-  {"target-align",             0,                                      \
-    N_("Automatically align branch targets to reduce branch penalties")}, \
-  {"no-target-align",          0,                                      \
-    N_("Do not automatically align branch targets")},                  \
-  {"longcalls",                        0,                                      \
-    N_("Use indirect CALLXn instructions for large programs")},                \
-  {"no-longcalls",             0,                                      \
-    N_("Use direct CALLn instructions for fast calls")},               \
-  {"",                         TARGET_DEFAULT, 0}                      \
-}
+#define OVERRIDE_OPTIONS override_options ()
 
+/* 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)
 
-#define OVERRIDE_OPTIONS override_options ()
 \f
 /* Target CPU builtins.  */
 #define TARGET_CPU_CPP_BUILTINS()                                      \
   do {                                                                 \
     builtin_assert ("cpu=xtensa");                                     \
     builtin_assert ("machine=xtensa");                                 \
+    builtin_define ("__xtensa__");                                     \
     builtin_define ("__XTENSA__");                                     \
+    builtin_define ("__XTENSA_WINDOWED_ABI__");                                \
     builtin_define (TARGET_BIG_ENDIAN ? "__XTENSA_EB__" : "__XTENSA_EL__"); \
     if (!TARGET_HARD_FLOAT)                                            \
       builtin_define ("__XTENSA_SOFT_FLOAT__");                                \
-    if (flag_pic)                                                      \
-      {                                                                        \
-        builtin_define ("__PIC__");                                    \
-        builtin_define ("__pic__");                                    \
-      }                                                                        \
   } while (0)
 
 #define CPP_SPEC " %(subtarget_cpp_spec) "
@@ -161,7 +157,6 @@ extern unsigned xtensa_current_frame_size;
 #define INT_TYPE_SIZE 32
 #define SHORT_TYPE_SIZE 16
 #define LONG_TYPE_SIZE 32
-#define MAX_LONG_TYPE_SIZE 32
 #define LONG_LONG_TYPE_SIZE 64
 #define FLOAT_TYPE_SIZE 32
 #define DOUBLE_TYPE_SIZE 64
@@ -208,6 +203,15 @@ extern unsigned xtensa_current_frame_size;
    bitfields and the structures that contain them.  */
 #define PCC_BITFIELD_TYPE_MATTERS 1
 
+/* Disable the use of word-sized or smaller complex modes for structures,
+   and for function arguments in particular, where they cause problems with
+   register a7.  The xtensa_copy_incoming_a7 function assumes that there is
+   a single reference to an argument in a7, but with small complex modes the
+   real and imaginary components may be extracted separately, leading to two
+   uses of the register, only one of which would be replaced.  */
+#define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) \
+  ((MODE) == CQImode || (MODE) == CHImode)
+
 /* Align string constants and constructors to at least a word boundary.
    The typical use of this macro is to increase alignment for string
    constants to be word aligned so that 'strcpy' calls that copy
@@ -416,10 +420,6 @@ extern char xtensa_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER];
    call an address kept in a register.  */
 #define NO_FUNCTION_CSE 1
 
-/* It is as good or better for a function to call itself with an
-   explicit address than to call an address kept in a register.  */
-#define NO_RECURSIVE_FUNCTION_CSE 1
-
 /* Xtensa processors have "register windows".  GCC does not currently
    take advantage of the possibility for variable-sized windows; instead,
    we use a fixed window size of 8.  */
@@ -487,6 +487,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
@@ -505,108 +510,12 @@ extern const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER];
    incoming or outgoing arguments.  */
 #define SMALL_REGISTER_CLASSES 1
 
-
-/* REGISTER AND CONSTANT CLASSES */
-
-/* Get reg_class from a letter such as appears in the machine
-   description.
-
-   Available letters: a-f,h,j-l,q,t-z,A-D,W,Y-Z
-
-   DEFINED REGISTER CLASSES:
-
-   'a'  general-purpose registers except sp
-   'q'  sp (aka a1)
-   'D' general-purpose registers (only if density option enabled)
-   'd'  general-purpose registers, including sp (only if density enabled)
-   'A' MAC16 accumulator (only if MAC16 option enabled)
-   'B' general-purpose registers (only if sext instruction enabled)
-   'C'  general-purpose registers (only if mul16 option enabled)
-   'W'  general-purpose registers (only if const16 option enabled)
-   'b' coprocessor boolean registers
-   'f' floating-point registers
-*/
-
-extern enum reg_class xtensa_char_to_class[256];
-
-#define REG_CLASS_FROM_LETTER(C) xtensa_char_to_class[ (int) (C) ]
-
-/* The letters I, J, K, L, M, N, O, and P in a register constraint
-   string can be used to stand for particular ranges of immediate
-   operands.  This macro defines what the ranges are.  C is the
-   letter, and VALUE is a constant value.  Return 1 if VALUE is
-   in the range specified by C.
-
-   For Xtensa:
-
-   I = 12-bit signed immediate for movi
-   J = 8-bit signed immediate for addi
-   K = 4-bit value in (b4const U {0})
-   L = 4-bit value in b4constu
-   M = 7-bit value in simm7
-   N = 8-bit unsigned immediate shifted left by 8 bits for addmi
-   O = 4-bit value in ai4const
-   P = valid immediate mask value for extui */
-
-#define CONST_OK_FOR_LETTER_P(VALUE, C)                                        \
-  ((C) == 'I' ? (xtensa_simm12b (VALUE))                               \
-   : (C) == 'J' ? (xtensa_simm8 (VALUE))                               \
-   : (C) == 'K' ? (((VALUE) == 0) || xtensa_b4const (VALUE))           \
-   : (C) == 'L' ? (xtensa_b4constu (VALUE))                            \
-   : (C) == 'M' ? (xtensa_simm7 (VALUE))                               \
-   : (C) == 'N' ? (xtensa_simm8x256 (VALUE))                           \
-   : (C) == 'O' ? (xtensa_ai4const (VALUE))                            \
-   : (C) == 'P' ? (xtensa_mask_immediate (VALUE))                      \
-   : FALSE)
-
-
-/* Similar, but for floating constants, and defining letters G and H.
-   Here VALUE is the CONST_DOUBLE rtx itself.  */
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) (0)
-
-
-/* Other letters can be defined in a machine-dependent fashion to
-   stand for particular classes of registers or other arbitrary
-   operand types.
-
-   R = memory that can be accessed with a 4-bit unsigned offset
-   T = memory in a constant pool (addressable with a pc-relative load)
-   U = memory *NOT* in a constant pool
-
-   The offset range should not be checked here (except to distinguish
-   denser versions of the instructions for which more general versions
-   are available).  Doing so leads to problems in reloading: an
-   argptr-relative address may become invalid when the phony argptr is
-   eliminated in favor of the stack pointer (the offset becomes too
-   large to fit in the instruction's immediate field); a reload is
-   generated to fix this but the RTL is not immediately updated; in
-   the meantime, the constraints are checked and none match.  The
-   solution seems to be to simply skip the offset check here.  The
-   address will be checked anyway because of the code in
-   GO_IF_LEGITIMATE_ADDRESS.  */
-
-#define EXTRA_CONSTRAINT(OP, CODE)                                     \
-  ((GET_CODE (OP) != MEM) ?                                            \
-       ((CODE) >= 'R' && (CODE) <= 'U'                                 \
-       && reload_in_progress && GET_CODE (OP) == REG                   \
-        && REGNO (OP) >= FIRST_PSEUDO_REGISTER)                                \
-   : ((CODE) == 'R') ? smalloffset_mem_p (OP)                          \
-   : ((CODE) == 'T') ? !TARGET_CONST16 && constantpool_mem_p (OP)      \
-   : ((CODE) == 'U') ? !constantpool_mem_p (OP)                                \
-   : FALSE)
-
 #define PREFERRED_RELOAD_CLASS(X, CLASS)                               \
   xtensa_preferred_reload_class (X, CLASS, 0)
 
 #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)                                                \
@@ -622,7 +531,7 @@ extern enum reg_class xtensa_char_to_class[256];
 
 /* 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.  */
@@ -638,17 +547,22 @@ extern enum reg_class xtensa_char_to_class[256];
 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)                   \
   do {                                                                 \
     compute_frame_size (get_frame_size ());                            \
-    if ((FROM) == FRAME_POINTER_REGNUM)                                        \
-      (OFFSET) = 0;                                                    \
-    else if ((FROM) == ARG_POINTER_REGNUM)                             \
-      (OFFSET) = xtensa_current_frame_size;                            \
-    else                                                               \
-      abort ();                                                                \
+    switch (FROM)                                                      \
+      {                                                                        \
+      case FRAME_POINTER_REGNUM:                                       \
+        (OFFSET) = 0;                                                  \
+       break;                                                          \
+      case ARG_POINTER_REGNUM:                                         \
+        (OFFSET) = xtensa_current_frame_size;                          \
+       break;                                                          \
+      default:                                                         \
+       gcc_unreachable ();                                             \
+      }                                                                        \
   } while (0)
 
 /* 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
@@ -701,22 +615,6 @@ extern enum reg_class xtensa_char_to_class[256];
 #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
@@ -737,23 +635,21 @@ extern enum reg_class xtensa_char_to_class[256];
 #define FUNCTION_ARG_REGNO_P(N)                                                \
   ((N) >= GP_OUTGOING_ARG_FIRST && (N) <= GP_OUTGOING_ARG_LAST)
 
-/* Define a data type for recording info about an argument list
-   during the scan of that argument list.  This data type should
-   hold all necessary information about the function itself
-   and about the args processed so far, enough to enable macros
-   such as FUNCTION_ARG to determine where the next arg should go.  */
-typedef struct xtensa_args {
-    int arg_words;             /* # total words the arguments take */
+/* Record the number of argument words seen so far, along with a flag to
+   indicate whether these are incoming arguments.  (FUNCTION_INCOMING_ARG
+   is used for both incoming and outgoing args, so a separate flag is
+   needed.  */
+typedef struct xtensa_args
+{
+  int arg_words;
+  int incoming;
 } CUMULATIVE_ARGS;
 
-/* Initialize a variable CUM of type CUMULATIVE_ARGS
-   for a call to a function whose data type is FNTYPE.
-   For a library call, FNTYPE is 0.  */
-#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT)           \
-  init_cumulative_args (&CUM, FNTYPE, LIBNAME)
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
+  init_cumulative_args (&CUM, 0)
 
 #define INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME)            \
-  init_cumulative_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.
@@ -767,43 +663,7 @@ typedef struct xtensa_args {
 #define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
   function_arg (&CUM, MODE, TYPE, TRUE)
 
-/* Arguments are never passed partly in memory and partly in registers.  */
-#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) (0)
-
-/* Specify function argument alignment.  */
-#define FUNCTION_ARG_BOUNDARY(MODE, TYPE)                              \
-  ((TYPE) != 0                                                         \
-   ? (TYPE_ALIGN (TYPE) <= PARM_BOUNDARY                               \
-      ? PARM_BOUNDARY                                                  \
-      : TYPE_ALIGN (TYPE))                                             \
-   : (GET_MODE_ALIGNMENT (MODE) <= PARM_BOUNDARY                       \
-      ? PARM_BOUNDARY                                                  \
-      : GET_MODE_ALIGNMENT (MODE)))
-
-/* Nonzero if we do not know how to pass TYPE solely in registers.
-   We cannot do so in the following cases:
-
-   - if the type has variable size
-   - if the type is marked as addressable (it is required to be constructed
-     into the stack)
-
-   This differs from the default in that it does not check if the padding
-   and mode of the type are such that a copy into a register would put it
-   into the wrong part of the register.  */
-
-#define MUST_PASS_IN_STACK(MODE, TYPE)                                 \
-  ((TYPE) != 0                                                         \
-   && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST                     \
-       || TREE_ADDRESSABLE (TYPE)))
-
-/* Pass complex arguments independently.  */
-#define SPLIT_COMPLEX_ARGS 1
-
-/* Because Xtensa's function_arg() wraps BLKmode arguments passed in
-   a7 inside a PARALLEL, BLOCK_REG_PADDING needs to be defined
-   to get emit_group_store to do the right thing.  */
-#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
-  FUNCTION_ARG_PADDING (MODE, TYPE)
+#define FUNCTION_ARG_BOUNDARY function_arg_boundary
 
 /* Profiling Xtensa code is typically done with the built-in profiling
    feature of Tensilica's instruction set simulator, which does not
@@ -836,89 +696,19 @@ 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.
+#define TRAMPOLINE_TEMPLATE(STREAM) xtensa_trampoline_template (STREAM)
 
-   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-generics\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.end no-generics\n");                          \
-  } while (0)
-
-/* Size in bytes of the trampoline, as an integer.  */
-#define TRAMPOLINE_SIZE 59
+/* 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 (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS ? 60 : 52)
 
 /* Alignment required for trampolines, in bits.  */
-#define TRAMPOLINE_ALIGNMENT (32)
+#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)
+  xtensa_initialize_trampoline (ADDR, FUNC, CHAIN)
 
-/* Implement `va_arg'.  */
-#define EXPAND_BUILTIN_VA_ARG(valist, type) \
-  xtensa_va_arg (valist, type)
 
 /* If defined, a C expression that produces the machine-specific code
    to setup the stack so that arbitrary frames can be accessed.
@@ -967,39 +757,27 @@ typedef struct xtensa_args {
 /* Addressing modes, and classification of registers for them.  */
 
 /* C expressions which are nonzero if register number NUM is suitable
-   for use as a base or index register in operand addresses.  It may
-   be either a suitable hard register or a pseudo register that has
-   been allocated such a hard register. The difference between an
-   index register and a base register is that the index register may
-   be scaled.  */
+   for use as a base or index register in operand addresses.  */
 
+#define REGNO_OK_FOR_INDEX_P(NUM) 0
 #define REGNO_OK_FOR_BASE_P(NUM) \
   (GP_REG_P (NUM) || GP_REG_P ((unsigned) reg_renumber[NUM]))
 
-#define REGNO_OK_FOR_INDEX_P(NUM) 0
-
 /* C expressions that are nonzero if X (assumed to be a `reg' RTX) is
-   valid for use as a base or index register.  For hard registers, it
-   should always accept those which the hardware permits and reject
-   the others.  Whether the macro accepts or rejects pseudo registers
-   must be controlled by `REG_OK_STRICT'.  This usually requires two
-   variant definitions, of which `REG_OK_STRICT' controls the one
-   actually used. The difference between an index register and a base
-   register is that the index register may be scaled.  */
+   valid for use as a base or index register.  */
 
 #ifdef REG_OK_STRICT
+#define REG_OK_STRICT_FLAG 1
+#else
+#define REG_OK_STRICT_FLAG 0
+#endif
 
-#define REG_OK_FOR_INDEX_P(X) 0
-#define REG_OK_FOR_BASE_P(X) \
-  REGNO_OK_FOR_BASE_P (REGNO (X))
-
-#else /* !REG_OK_STRICT */
+#define BASE_REG_P(X, STRICT)                                          \
+  ((!(STRICT) && REGNO (X) >= FIRST_PSEUDO_REGISTER)                   \
+   || REGNO_OK_FOR_BASE_P (REGNO (X)))
 
 #define REG_OK_FOR_INDEX_P(X) 0
-#define REG_OK_FOR_BASE_P(X) \
-  ((REGNO (X) >= FIRST_PSEUDO_REGISTER) || (GP_REG_P (REGNO (X))))
-
-#endif /* !REG_OK_STRICT */
+#define REG_OK_FOR_BASE_P(X) BASE_REG_P (X, REG_OK_STRICT_FLAG)
 
 /* Maximum number of registers that can appear in a valid memory address.  */
 #define MAX_REGS_PER_ADDRESS 1
@@ -1007,52 +785,8 @@ typedef struct xtensa_args {
 /* Identify valid Xtensa addresses.  */
 #define GO_IF_LEGITIMATE_ADDRESS(MODE, ADDR, LABEL)                    \
   do {                                                                 \
-    rtx xinsn = (ADDR);                                                        \
-                                                                       \
-    /* allow constant pool addresses */                                        \
-    if ((MODE) != BLKmode && GET_MODE_SIZE (MODE) >= UNITS_PER_WORD    \
-       && !TARGET_CONST16 && constantpool_address_p (xinsn))           \
-      goto LABEL;                                                      \
-                                                                       \
-    while (GET_CODE (xinsn) == SUBREG)                                 \
-      xinsn = SUBREG_REG (xinsn);                                      \
-                                                                       \
-    /* allow base registers */                                         \
-    if (GET_CODE (xinsn) == REG && REG_OK_FOR_BASE_P (xinsn))          \
+    if (xtensa_legitimate_address_p (MODE, ADDR, REG_OK_STRICT_FLAG))  \
       goto LABEL;                                                      \
-                                                                       \
-    /* check for "register + offset" addressing */                     \
-    if (GET_CODE (xinsn) == PLUS)                                      \
-      {                                                                        \
-       rtx xplus0 = XEXP (xinsn, 0);                                   \
-       rtx xplus1 = XEXP (xinsn, 1);                                   \
-       enum rtx_code code0;                                            \
-       enum rtx_code code1;                                            \
-                                                                       \
-       while (GET_CODE (xplus0) == SUBREG)                             \
-         xplus0 = SUBREG_REG (xplus0);                                 \
-       code0 = GET_CODE (xplus0);                                      \
-                                                                       \
-       while (GET_CODE (xplus1) == SUBREG)                             \
-         xplus1 = SUBREG_REG (xplus1);                                 \
-       code1 = GET_CODE (xplus1);                                      \
-                                                                       \
-       /* swap operands if necessary so the register is first */       \
-       if (code0 != REG && code1 == REG)                               \
-         {                                                             \
-           xplus0 = XEXP (xinsn, 1);                                   \
-           xplus1 = XEXP (xinsn, 0);                                   \
-           code0 = GET_CODE (xplus0);                                  \
-           code1 = GET_CODE (xplus1);                                  \
-         }                                                             \
-                                                                       \
-       if (code0 == REG && REG_OK_FOR_BASE_P (xplus0)                  \
-           && code1 == CONST_INT                                       \
-           && xtensa_mem_offset (INTVAL (xplus1), (MODE)))             \
-         {                                                             \
-           goto LABEL;                                                 \
-         }                                                             \
-      }                                                                        \
   } while (0)
 
 /* A C expression that is 1 if the RTX X is a constant which is a
@@ -1065,46 +799,24 @@ 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
    code.  */
 #define LEGITIMATE_PIC_OPERAND_P(X)                                    \
-  ((GET_CODE (X) != SYMBOL_REF || SYMBOL_REF_LOCAL_P (X))              \
+  ((GET_CODE (X) != SYMBOL_REF                                         \
+    || (SYMBOL_REF_LOCAL_P (X) && !SYMBOL_REF_EXTERNAL_P (X)))         \
    && GET_CODE (X) != LABEL_REF                                                \
    && GET_CODE (X) != CONST)
 
-/* Tell GCC how to use ADDMI to generate addresses.  */
 #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)                         \
   do {                                                                 \
-    rtx xinsn = (X);                                                   \
-    if (GET_CODE (xinsn) == PLUS)                                      \
-      {                                                                \
-       rtx plus0 = XEXP (xinsn, 0);                                    \
-       rtx plus1 = XEXP (xinsn, 1);                                    \
-                                                                       \
-       if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)         \
-         {                                                             \
-           plus0 = XEXP (xinsn, 1);                                    \
-           plus1 = XEXP (xinsn, 0);                                    \
-         }                                                             \
-                                                                       \
-       if (GET_CODE (plus0) == REG                                     \
-           && GET_CODE (plus1) == CONST_INT                            \
-           && !xtensa_mem_offset (INTVAL (plus1), MODE)                \
-           && !xtensa_simm8 (INTVAL (plus1))                           \
-           && xtensa_mem_offset (INTVAL (plus1) & 0xff, MODE)          \
-           && xtensa_simm8x256 (INTVAL (plus1) & ~0xff))               \
-         {                                                             \
-           rtx temp = gen_reg_rtx (Pmode);                             \
-           emit_insn (gen_rtx_SET (Pmode, temp,                        \
-                               gen_rtx_PLUS (Pmode, plus0,             \
-                                        GEN_INT (INTVAL (plus1) & ~0xff)))); \
-           (X) = gen_rtx_PLUS (Pmode, temp,                            \
-                          GEN_INT (INTVAL (plus1) & 0xff));            \
-           goto WIN;                                                   \
-         }                                                             \
+    rtx new_x = xtensa_legitimize_address (X, OLDX, MODE);             \
+    if (new_x)                                                         \
+      {                                                                        \
+       X = new_x;                                                      \
+       goto WIN;                                                       \
       }                                                                        \
   } while (0)
 
@@ -1127,11 +839,6 @@ typedef struct xtensa_args {
    for the index in the tablejump instruction.  */
 #define CASE_VECTOR_MODE (SImode)
 
-/* Define this if the tablejump instruction expects the table
-   to contain offsets from the address of the table.
-   Do not define this if the table should contain absolute addresses.  */
-/* #define CASE_VECTOR_PC_RELATIVE */
-
 /* Define this as 1 if 'char' should by default be signed; else as 0.  */
 #define DEFAULT_SIGNED_CHAR 0
 
@@ -1143,11 +850,6 @@ typedef struct xtensa_args {
 /* Prefer word-sized loads.  */
 #define SLOW_BYTE_ACCESS 1
 
-/* ??? Xtensa doesn't have any instructions that set integer values
-   based on the results of comparisons, but the simplification code in
-   the combiner also uses STORE_FLAG_VALUE.  The default value (1) is
-   fine for us, but (-1) might be better.  */
-
 /* Shift instructions ignore all but the low-order few bits.  */
 #define SHIFT_COUNT_TRUNCATED 1
 
@@ -1155,6 +857,9 @@ typedef struct xtensa_args {
    is done just by pretending it is already truncated.  */
 #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
 
+#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE)  ((VALUE) = 32, 1)
+#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE)  ((VALUE) = -1, 1)
+
 /* Specify the machine mode that pointers have.
    After generation of rtl, the compiler makes no further distinction
    between pointers and any other objects of this machine mode.  */
@@ -1184,38 +889,7 @@ typedef struct xtensa_args {
 
 #define MEMORY_MOVE_COST(MODE, CLASS, IN) 4
 
-#define BRANCH_COST 3
-
-/* Optionally define this if you have added predicates to
-   'MACHINE.c'.  This macro is called within an initializer of an
-   array of structures.  The first field in the structure is the
-   name of a predicate and the second field is an array of rtl
-   codes.  For each predicate, list all rtl codes that can be in
-   expressions matched by the predicate.  The list should have a
-   trailing comma.  */
-
-#define PREDICATE_CODES                                                        \
-  {"add_operand",              { REG, CONST_INT, SUBREG }},            \
-  {"arith_operand",            { REG, CONST_INT, SUBREG }},            \
-  {"nonimmed_operand",         { REG, SUBREG, MEM }},                  \
-  {"mem_operand",              { MEM }},                               \
-  {"mask_operand",             { REG, CONST_INT, SUBREG }},            \
-  {"extui_fldsz_operand",      { CONST_INT }},                         \
-  {"sext_fldsz_operand",       { CONST_INT }},                         \
-  {"lsbitnum_operand",         { CONST_INT }},                         \
-  {"fpmem_offset_operand",     { CONST_INT }},                         \
-  {"sext_operand",             { REG, SUBREG, MEM }},                  \
-  {"branch_operand",           { REG, CONST_INT, SUBREG }},            \
-  {"ubranch_operand",          { REG, CONST_INT, SUBREG }},            \
-  {"call_insn_operand",                { CONST_INT, CONST, SYMBOL_REF, REG }}, \
-  {"move_operand",             { REG, SUBREG, MEM, CONST_INT, CONST_DOUBLE, \
-                                 CONST, SYMBOL_REF, LABEL_REF }},      \
-  {"const_float_1_operand",    { CONST_DOUBLE }},                      \
-  {"branch_operator",          { EQ, NE, LT, GE }},                    \
-  {"ubranch_operator",         { LTU, GEU }},                          \
-  {"boolean_operator",         { EQ, NE }},
-
-/* Control the assembler format that we output.  */
+#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).  */
@@ -1245,20 +919,7 @@ typedef struct xtensa_args {
    constants.  Used for PIC-specific UNSPECs.  */
 #define OUTPUT_ADDR_CONST_EXTRA(STREAM, X, FAIL)                       \
   do {                                                                 \
-    if (flag_pic && GET_CODE (X) == UNSPEC && XVECLEN ((X), 0) == 1)   \
-      {                                                                        \
-       switch (XINT ((X), 1))                                          \
-         {                                                             \
-         case UNSPEC_PLT:                                              \
-           output_addr_const ((STREAM), XVECEXP ((X), 0, 0));          \
-           fputs ("@PLT", (STREAM));                                   \
-           break;                                                      \
-         default:                                                      \
-           goto FAIL;                                                  \
-         }                                                             \
-       break;                                                          \
-      }                                                                        \
-    else                                                               \
+    if (xtensa_output_addr_const_extra (STREAM, X) == FALSE)           \
       goto FAIL;                                                       \
   } while (0)
 
@@ -1302,36 +963,18 @@ typedef struct xtensa_args {
 #define BSS_SECTION_ASM_OP     "\t.section\t.bss"
 
 
-/* Define output to appear before the constant pool.  If the function
-   has been assigned to a specific ELF section, or if it goes into a
-   unique section, set the name of that section to be the literal
-   prefix.  */
+/* Define output to appear before the constant pool.  */
 #define ASM_OUTPUT_POOL_PROLOGUE(FILE, FUNNAME, FUNDECL, SIZE)          \
   do {                                                                 \
-    tree fnsection;                                                    \
-    resolve_unique_section ((FUNDECL), 0, flag_function_sections);     \
-    fnsection = DECL_SECTION_NAME (FUNDECL);                           \
-    if (fnsection != NULL_TREE)                                                \
-      {                                                                        \
-       const char *fnsectname = TREE_STRING_POINTER (fnsection);       \
-       fprintf (FILE, "\t.begin\tliteral_prefix %s\n",                 \
-                strcmp (fnsectname, ".text") ? fnsectname : "");       \
-      }                                                                        \
     if ((SIZE) > 0)                                                    \
       {                                                                        \
-       function_section (FUNDECL);                                     \
+       resolve_unique_section ((FUNDECL), 0, flag_function_sections);  \
+       switch_to_section (function_section (FUNDECL));                 \
        fprintf (FILE, "\t.literal_position\n");                        \
       }                                                                        \
   } while (0)
 
 
-/* Define code to write out the ".end literal_prefix" directive for a
-   function in a special section.  This is appended to the standard ELF
-   code for ASM_DECLARE_FUNCTION_SIZE.  */
-#define XTENSA_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL)                        \
-  if (DECL_SECTION_NAME (DECL) != NULL_TREE)                           \
-    fprintf (FILE, "\t.end\tliteral_prefix\n")
-
 /* A C statement (with or without semicolon) to output a constant in
    the constant pool, if it needs special treatment.  */
 #define ASM_OUTPUT_SPECIAL_POOL_ENTRY(FILE, X, MODE, ALIGN, LABELNO, JUMPTO) \
@@ -1343,8 +986,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