OSDN Git Service

* config/xtensa/linux.h (TARGET_OS_CPP_BUILTINS): Back out previous
[pf3gnuchains/gcc-fork.git] / gcc / config / xtensa / xtensa.h
index 4cd8616..84f131d 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions of Tensilica's Xtensa target machine for GNU compiler.
-   Copyright (C) 2001 Free Software Foundation, Inc.
+   Copyright 2001,2002,2003 Free Software Foundation, Inc.
    Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
 
 This file is part of GCC.
@@ -191,29 +191,37 @@ extern unsigned xtensa_current_frame_size;
 
 
 #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 (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)
 
-#if XCHAL_HAVE_BE
-#define CPP_ENDIAN_SPEC "\
-  %{mlittle-endian:-D__XTENSA_EL__} \
-  %{!mlittle-endian:-D__XTENSA_EB__} "
-#else /* !XCHAL_HAVE_BE */
-#define CPP_ENDIAN_SPEC "\
-  %{mbig-endian:-D__XTENSA_EB__} \
-  %{!mbig-endian:-D__XTENSA_EL__} "
-#endif /* !XCHAL_HAVE_BE */
-
-#if XCHAL_HAVE_FP
-#define CPP_FLOAT_SPEC "%{msoft-float:-D__XTENSA_SOFT_FLOAT__}"
-#else
-#define CPP_FLOAT_SPEC "%{!mhard-float:-D__XTENSA_SOFT_FLOAT__}"
+#define CPP_SPEC " %(subtarget_cpp_spec) "
+
+#ifndef SUBTARGET_CPP_SPEC
+#define SUBTARGET_CPP_SPEC ""
 #endif
 
-#undef CPP_SPEC
-#define CPP_SPEC CPP_ENDIAN_SPEC CPP_FLOAT_SPEC
+#define EXTRA_SPECS                                                    \
+  { "subtarget_cpp_spec", SUBTARGET_CPP_SPEC },
 
-/* Define this to set the endianness to use in libgcc2.c, which can
-   not depend on target_flags.  */
-#define LIBGCC2_WORDS_BIG_ENDIAN XCHAL_HAVE_BE
+#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
@@ -242,7 +250,6 @@ extern unsigned xtensa_current_frame_size;
 
 /* Size in bits of various types on the target machine.  */
 #define INT_TYPE_SIZE 32
-#define MAX_INT_TYPE_SIZE 32
 #define SHORT_TYPE_SIZE 16
 #define LONG_TYPE_SIZE 32
 #define MAX_LONG_TYPE_SIZE 32
@@ -251,13 +258,6 @@ extern unsigned xtensa_current_frame_size;
 #define DOUBLE_TYPE_SIZE 64
 #define LONG_DOUBLE_TYPE_SIZE 64
 
-/* Tell the preprocessor the maximum size of wchar_t.  */
-#ifndef MAX_WCHAR_TYPE_SIZE
-#ifndef WCHAR_TYPE_SIZE
-#define MAX_WCHAR_TYPE_SIZE MAX_INT_TYPE_SIZE
-#endif
-#endif
-
 /* Allocation boundary (in *bits*) for storing pointers in memory.  */
 #define POINTER_BOUNDARY 32
 
@@ -356,7 +356,6 @@ extern unsigned xtensa_current_frame_size;
    0 - 15      AR[0] - AR[15]
    16          FRAME_POINTER (fake = initial sp)
    17          ARG_POINTER (fake = initial sp + framesize)
-   18           LOOP_COUNT (loop count special register)
    18          BR[0] for floating-point CC
    19 - 34     FR[0] - FR[15]
    35          MAC16 accumulator */
@@ -405,10 +404,11 @@ extern unsigned xtensa_current_frame_size;
    have been exhausted.  */
 
 #define REG_ALLOC_ORDER \
-{  8,  9, 10, 11, 12, 13, 14, 15,  7,  6,  5,  4,  3,  2, 19, \
-  20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, \
+{  8,  9, 10, 11, 12, 13, 14, 15,  7,  6,  5,  4,  3,  2, \
+  18, \
+  19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, \
    0,  1, 16, 17, \
-  36, \
+  35, \
 }
 
 #define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc ()
@@ -435,11 +435,6 @@ extern int leaf_function;
 #define GP_REG_LAST  17
 #define GP_REG_NUM   (GP_REG_LAST - GP_REG_FIRST + 1)
 
-/* Special registers */
-#define SPEC_REG_FIRST 18
-#define SPEC_REG_LAST  18
-#define SPEC_REG_NUM   (SPEC_REG_LAST - SPEC_REG_FIRST + 1)
-
 /* Coprocessor registers */
 #define BR_REG_FIRST 18
 #define BR_REG_LAST  18 
@@ -484,9 +479,6 @@ extern char xtensa_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER];
    == (GET_MODE_CLASS (MODE2) == MODE_FLOAT ||                         \
        GET_MODE_CLASS (MODE2) == MODE_COMPLEX_FLOAT))
 
-/* Register to use for LCOUNT special register.  */
-#define COUNT_REGISTER_REGNUM (SPEC_REG_FIRST + 0)
-
 /* Register to use for pushing function arguments.  */
 #define STACK_POINTER_REGNUM (GP_REG_FIRST + 1)
 
@@ -559,6 +551,7 @@ enum reg_class
   FP_REGS,                     /* floating point registers */
   ACC_REG,                     /* MAC16 accumulator */
   SP_REG,                      /* sp register (aka a1) */
+  RL_REGS,                     /* preferred reload regs (not sp or fp) */
   GR_REGS,                     /* integer registers except sp */
   AR_REGS,                     /* all integer registers */
   ALL_REGS,                    /* all registers */
@@ -579,6 +572,7 @@ enum reg_class
   "FP_REGS",                                                           \
   "ACC_REG",                                                           \
   "SP_REG",                                                            \
+  "RL_REGS",                                                           \
   "GR_REGS",                                                           \
   "AR_REGS",                                                           \
   "ALL_REGS"                                                           \
@@ -594,6 +588,7 @@ enum reg_class
   { 0xfff80000, 0x00000007 }, /* floating-point registers */ \
   { 0x00000000, 0x00000008 }, /* MAC16 accumulator */ \
   { 0x00000002, 0x00000000 }, /* stack pointer register */ \
+  { 0x0000ff7d, 0x00000000 }, /* preferred reload registers */ \
   { 0x0000fffd, 0x00000000 }, /* general-purpose registers */ \
   { 0x0003ffff, 0x00000000 }, /* integer registers */ \
   { 0xffffffff, 0x0000000f }  /* all registers */ \
@@ -708,15 +703,11 @@ extern enum reg_class xtensa_char_to_class[256];
    : ((CODE) == 'U') ? !constantpool_mem_p (OP)                                \
    : FALSE)
 
-/* Given an rtx X being reloaded into a reg required to be
-   in class CLASS, return the class of reg to actually use.  */
 #define PREFERRED_RELOAD_CLASS(X, CLASS)                               \
-  (CONSTANT_P (X)                                                      \
-   ? (GET_CODE (X) == CONST_DOUBLE) ? NO_REGS : (CLASS)                        \
-   : (CLASS))
+  xtensa_preferred_reload_class (X, CLASS, 0)
 
 #define PREFERRED_OUTPUT_RELOAD_CLASS(X, CLASS)                                \
-  (CLASS)
+  xtensa_preferred_reload_class (X, CLASS, 1)
   
 #define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X)                   \
   xtensa_secondary_reload_class (CLASS, MODE, X, 0)
@@ -802,13 +793,13 @@ extern enum reg_class xtensa_char_to_class[256];
 /* Don't worry about compatibility with PCC.  */
 #define DEFAULT_PCC_STRUCT_RETURN 0
 
-/* For Xtensa, we would like to be able to return up to 6 words in
-   memory but GCC cannot support that.  The return value must be given
-   one of the standard MODE_INT modes, and there is no 6 word mode.
-   Instead, if we try to return a 6 word structure, GCC selects the
-   next biggest mode (OImode, 8 words) and then the register allocator
-   fails because there is no 8-register group beginning with a10.  So
-   we have to fall back on the next largest size which is 4 words... */
+/* For Xtensa, up to 4 words can be returned in registers.  (It would
+   have been nice to allow up to 6 words in registers but GCC cannot
+   support that.  The return value must be given one of the standard
+   MODE_INT modes, and there is no 6 word mode.  Instead, if we try to
+   return a 6 word structure, GCC selects the next biggest mode
+   (OImode, 8 words) and then the register allocator fails because
+   there is no 8-register group beginning with a10.)  */
 #define RETURN_IN_MEMORY(TYPE)                                         \
   ((unsigned HOST_WIDE_INT) int_size_in_bytes (TYPE) > 4 * UNITS_PER_WORD)
 
@@ -864,9 +855,6 @@ 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)
 
-/* Use IEEE floating-point format.  */
-#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
-
 /* 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
@@ -927,29 +915,33 @@ typedef struct xtensa_args {
    && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST                     \
        || TREE_ADDRESSABLE (TYPE)))
 
-/* Output assembler code to FILE to increment profiler label LABELNO
-   for profiling a function entry.
-
-   The mcount code in glibc doesn't seem to use this LABELNO stuff.
-   Some ports (e.g., MIPS) don't even bother to pass the label
-   address, and even those that do (e.g., i386) don't seem to use it.
-   The information needed by mcount() is the current PC and the
-   current return address, so that mcount can identify an arc in the
-   call graph.  For Xtensa, we pass the current return address as
-   the first argument to mcount, and the current PC is available as
-   a0 in mcount's register window.  Both of these values contain
-   window size information in the two most significant bits; we assume
-   that the mcount code will mask off those bits.  The call to mcount
-   uses a window size of 8 to make sure that mcount doesn't clobber
+/* Profiling Xtensa code is typically done with the built-in profiling
+   feature of Tensilica's instruction set simulator, which does not
+   require any compiler support.  Profiling code on a real (i.e.,
+   non-simulated) Xtensa processor is currently only supported by
+   GNU/Linux with glibc.  The glibc version of _mcount doesn't require
+   counter variables.  The _mcount function needs the current PC and
+   the current return address to identify an arc in the call graph.
+   Pass the current return address as the first argument; the current
+   PC is available as a0 in _mcount's register window.  Both of these
+   values contain window size information in the two most significant
+   bits; we assume that _mcount will mask off those bits.  The call to
+   _mcount uses a window size of 8 to make sure that it doesn't clobber
    any incoming argument values. */
 
-#define FUNCTION_PROFILER(FILE, LABELNO)                               \
+#define NO_PROFILE_COUNTERS
+
+#define FUNCTION_PROFILER(FILE, LABELNO) \
   do {                                                                 \
-    fprintf (FILE, "\taddi\t%s, %s, 0\t# save current return address\n", \
-            reg_names[GP_REG_FIRST+10],                                \
-            reg_names[GP_REG_FIRST+0]);                                \
-    fprintf (FILE, "\tcall8\t_mcount\n");                              \
-  } while (0);
+    fprintf (FILE, "\t%s\ta10, a0\n", TARGET_DENSITY ? "mov.n" : "mov"); \
+    if (flag_pic)                                                      \
+      {                                                                        \
+       fprintf (FILE, "\tmovi\ta8, _mcount@PLT\n");                    \
+       fprintf (FILE, "\tcallx8\ta8\n");                               \
+      }                                                                        \
+    else                                                               \
+      fprintf (FILE, "\tcall8\t_mcount\n");                            \
+  } while (0)
 
 /* Stack pointer value doesn't matter at exit.  */
 #define EXIT_IGNORE_STACK 1
@@ -1037,8 +1029,8 @@ typedef struct xtensa_args {
   xtensa_builtin_saveregs
 
 /* Implement `va_start' for varargs and stdarg.  */
-#define EXPAND_BUILTIN_VA_START(stdarg, valist, nextarg) \
-  xtensa_va_start (stdarg, valist, nextarg)
+#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
+  xtensa_va_start (valist, nextarg)
 
 /* Implement `va_arg'.  */
 #define EXPAND_BUILTIN_VA_ARG(valist, type) \
@@ -1062,8 +1054,7 @@ typedef struct xtensa_args {
    we currently need to ensure that there is a frame pointer when these
    builtin functions are used. */
 
-#define SETUP_FRAME_ADDRESSES() \
-  xtensa_setup_frame_addresses ()
+#define SETUP_FRAME_ADDRESSES  xtensa_setup_frame_addresses
 
 /* A C expression whose value is RTL representing the address in a
    stack frame where the pointer to the caller's frame is stored.
@@ -1087,22 +1078,8 @@ typedef struct xtensa_args {
 
 /* A C expression whose value is RTL representing the value of the
    return address for the frame COUNT steps up from the current
-   frame, after the prologue.  FRAMEADDR is the frame pointer of the
-   COUNT frame, or the frame pointer of the COUNT - 1 frame if
-   'RETURN_ADDR_IN_PREVIOUS_FRAME' is defined.
-
-   The 2 most-significant bits of the return address on Xtensa hold
-   the register window size.  To get the real return address, these bits
-   must be masked off and replaced with the high bits from the current
-   PC.  Since it is unclear how the __builtin_return_address function
-   is used, the current code does not do this masking and simply returns
-   the raw return address from the a0 register. */
-#define RETURN_ADDR_RTX(count, frame)                                  \
-  ((count) == -1                                                       \
-   ? gen_rtx_REG (Pmode, 0)                                            \
-   : gen_rtx_MEM (Pmode, memory_address                                        \
-                 (Pmode, plus_constant (frame, -4 * UNITS_PER_WORD))))
-
+   frame, after the prologue.  */
+#define RETURN_ADDR_RTX  xtensa_return_addr
 
 /* Addressing modes, and classification of registers for them.  */
 
@@ -1263,14 +1240,6 @@ typedef struct xtensa_args {
       goto LABEL;                                                      \
   } while (0)
 
-/* If we are referencing a function that is static, make the SYMBOL_REF
-   special so that we can generate direct calls to it even with -fpic.  */
-#define ENCODE_SECTION_INFO(DECL, FIRST)                               \
-  do {                                                                 \
-    if (TREE_CODE (DECL) == FUNCTION_DECL && ! TREE_PUBLIC (DECL))     \
-      SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1;                 \
-  } while (0)
-
 /* Specify the machine mode that this machine uses
    for the index in the tablejump instruction.  */
 #define CASE_VECTOR_MODE (SImode)
@@ -1280,12 +1249,6 @@ typedef struct xtensa_args {
    Do not define this if the table should contain absolute addresses.  */
 /* #define CASE_VECTOR_PC_RELATIVE */
 
-/* Specify the tree operation to be used to convert reals to integers.  */
-#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
-
-/* This is the kind of divide that is easiest to do in the general case.  */
-#define EASY_DIV_EXPR TRUNC_DIV_EXPR
-
 /* Define this as 1 if 'char' should by default be signed; else as 0.  */
 #define DEFAULT_SIGNED_CHAR 0
 
@@ -1321,162 +1284,6 @@ typedef struct xtensa_args {
    indexing purposes) so give the MEM rtx a words's mode.  */
 #define FUNCTION_MODE SImode
 
-/* A C expression that evaluates to true if it is ok to perform a
-   sibling call to DECL.  */
-/* TODO: fix this up to allow at least some sibcalls */
-#define FUNCTION_OK_FOR_SIBCALL(DECL) 0
-
-/* Xtensa constant costs.  */
-#define CONST_COSTS(X, CODE, OUTER_CODE)                               \
-  case CONST_INT:                                                      \
-    switch (OUTER_CODE)                                                        \
-      {                                                                        \
-      case SET:                                                                \
-       if (xtensa_simm12b (INTVAL (X))) return 4;                      \
-       break;                                                          \
-      case PLUS:                                                       \
-       if (xtensa_simm8 (INTVAL (X))) return 0;                        \
-       if (xtensa_simm8x256 (INTVAL (X))) return 0;                    \
-       break;                                                          \
-      case AND:                                                                \
-       if (xtensa_mask_immediate (INTVAL (X))) return 0;               \
-       break;                                                          \
-      case COMPARE:                                                    \
-       if ((INTVAL (X) == 0) || xtensa_b4const (INTVAL (X))) return 0; \
-       break;                                                          \
-      case ASHIFT:                                                     \
-      case ASHIFTRT:                                                   \
-      case LSHIFTRT:                                                   \
-      case ROTATE:                                                     \
-      case ROTATERT:                                                   \
-        /* no way to tell if X is the 2nd operand so be conservative */        \
-      default: break;                                                  \
-      }                                                                        \
-    if (xtensa_simm12b (INTVAL (X))) return 5;                         \
-    return 6;                                                          \
-  case CONST:                                                          \
-  case LABEL_REF:                                                      \
-  case SYMBOL_REF:                                                     \
-    return 5;                                                          \
-  case CONST_DOUBLE:                                                   \
-    return 7;
-
-/* Costs of various Xtensa operations.  */
-#define RTX_COSTS(X, CODE, OUTER_CODE)                                 \
-  case MEM:                                                            \
-    {                                                                  \
-       int num_words =                                                 \
-         (GET_MODE_SIZE (GET_MODE (X)) > UNITS_PER_WORD) ?  2 : 1;     \
-       if (memory_address_p (GET_MODE (X), XEXP ((X), 0)))             \
-         return COSTS_N_INSNS (num_words);                             \
-                                                                       \
-       return COSTS_N_INSNS (2*num_words);                             \
-    }                                                                  \
-                                                                       \
-  case FFS:                                                            \
-    return COSTS_N_INSNS (TARGET_NSA ? 5 : 50);                                \
-                                                                       \
-  case NOT:                                                            \
-    return COSTS_N_INSNS ((GET_MODE (X) == DImode) ? 3 : 2);           \
-                                                                       \
-  case AND:                                                            \
-  case IOR:                                                            \
-  case XOR:                                                            \
-    if (GET_MODE (X) == DImode) return COSTS_N_INSNS (2);              \
-    return COSTS_N_INSNS (1);                                          \
-                                                                       \
-  case ASHIFT:                                                         \
-  case ASHIFTRT:                                                       \
-  case LSHIFTRT:                                                       \
-    if (GET_MODE (X) == DImode) return COSTS_N_INSNS (50);             \
-    return COSTS_N_INSNS (1);                                          \
-                                                                       \
-  case ABS:                                                            \
-    {                                                                  \
-       enum machine_mode xmode = GET_MODE (X);                         \
-       if (xmode == SFmode)                                            \
-         return COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50);            \
-       if (xmode == DFmode)                                            \
-         return COSTS_N_INSNS (50);                                    \
-       return COSTS_N_INSNS (4);                                       \
-    }                                                                  \
-                                                                       \
-  case PLUS:                                                           \
-  case MINUS:                                                          \
-    {                                                                  \
-       enum machine_mode xmode = GET_MODE (X);                         \
-       if (xmode == SFmode)                                            \
-         return COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50);            \
-       if (xmode == DFmode || xmode == DImode)                         \
-         return COSTS_N_INSNS (50);                                    \
-       return COSTS_N_INSNS (1);                                       \
-    }                                                                  \
-                                                                       \
-  case NEG:                                                            \
-    return COSTS_N_INSNS ((GET_MODE (X) == DImode) ? 4 : 2);           \
-                                                                       \
-  case MULT:                                                           \
-    {                                                                  \
-       enum machine_mode xmode = GET_MODE (X);                         \
-       if (xmode == SFmode)                                            \
-         return COSTS_N_INSNS (TARGET_HARD_FLOAT ? 4 : 50);            \
-       if (xmode == DFmode || xmode == DImode)                         \
-           return COSTS_N_INSNS (50);                                  \
-       if (TARGET_MUL32)                                               \
-         return COSTS_N_INSNS (4);                                     \
-       if (TARGET_MAC16)                                               \
-         return COSTS_N_INSNS (16);                                    \
-       if (TARGET_MUL16)                                               \
-         return COSTS_N_INSNS (12);                                    \
-       return COSTS_N_INSNS (50);                                      \
-    }                                                                  \
-                                                                       \
-  case DIV:                                                            \
-  case MOD:                                                            \
-    {                                                                  \
-       enum machine_mode xmode = GET_MODE (X);                         \
-       if (xmode == SFmode)                                            \
-         return COSTS_N_INSNS (TARGET_HARD_FLOAT_DIV ? 8 : 50);        \
-       if (xmode == DFmode)                                            \
-         return COSTS_N_INSNS (50);                                    \
-    }                                                                  \
-    /* fall through */                                                 \
-                                                                       \
-  case UDIV:                                                           \
-  case UMOD:                                                           \
-    {                                                                  \
-       enum machine_mode xmode = GET_MODE (X);                         \
-       if (xmode == DImode)                                            \
-         return COSTS_N_INSNS (50);                                    \
-       if (TARGET_DIV32)                                               \
-         return COSTS_N_INSNS (32);                                    \
-       return COSTS_N_INSNS (50);                                      \
-    }                                                                  \
-                                                                       \
-  case SQRT:                                                           \
-    if (GET_MODE (X) == SFmode)                                                \
-      return COSTS_N_INSNS (TARGET_HARD_FLOAT_SQRT ? 8 : 50);          \
-    return COSTS_N_INSNS (50);                                         \
-                                                                       \
-  case SMIN:                                                           \
-  case UMIN:                                                           \
-  case SMAX:                                                           \
-  case UMAX:                                                           \
-    return COSTS_N_INSNS (TARGET_MINMAX ? 1 : 50);                     \
-                                                                       \
-  case SIGN_EXTRACT:                                                   \
-  case SIGN_EXTEND:                                                    \
-    return COSTS_N_INSNS (TARGET_SEXT ? 1 : 2);                                \
-                                                                       \
-  case ZERO_EXTRACT:                                                   \
-  case ZERO_EXTEND:                                                    \
-    return COSTS_N_INSNS (1);
-
-
-/* An expression giving the cost of an addressing mode that
-   contains ADDRESS.  */
-#define ADDRESS_COST(ADDR) 1
-
 /* A C expression for the cost of moving data from a register in
    class FROM to one in class TO.  The classes are expressed using
    the enumeration values such as 'GENERAL_REGS'.  A value of 2 is
@@ -1511,7 +1318,6 @@ typedef struct xtensa_args {
   {"add_operand",              { REG, CONST_INT, SUBREG }},            \
   {"arith_operand",            { REG, CONST_INT, SUBREG }},            \
   {"nonimmed_operand",         { REG, SUBREG, MEM }},                  \
-  {"non_acc_reg_operand",      { REG, SUBREG }},                       \
   {"mem_operand",              { MEM }},                               \
   {"mask_operand",             { REG, CONST_INT, SUBREG }},            \
   {"extui_fldsz_operand",      { CONST_INT }},                         \
@@ -1577,32 +1383,12 @@ typedef struct xtensa_args {
       goto FAIL;                                                       \
   } while (0)
 
+/* Globalizing directive for a label.  */
+#define GLOBAL_ASM_OP "\t.global\t"
 
-/* This is how to output the definition of a user-level label named NAME,
-   such as the label on a static function or variable NAME. */
-#define ASM_OUTPUT_LABEL(STREAM, NAME)                                 \
-  do {                                                                 \
-    assemble_name (STREAM, NAME);                                      \
-    fputs (":\n", STREAM);                                             \
-  } while (0)
-
-/* This is how to output a command to make the user-level label named NAME
-   defined for reference from other files.  */
-#define ASM_GLOBALIZE_LABEL(STREAM, NAME)                              \
-  do {                                                                 \
-    fputs ("\t.global\t", STREAM);                                     \
-    assemble_name (STREAM, NAME);                                      \
-    fputs ("\n", STREAM);                                              \
-  } while (0)
-
-/* This says how to define a global common symbol.  */
-#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED)                 \
-  xtensa_declare_object (STREAM, NAME, "\n\t.comm\t", ",%u\n", (SIZE))
-
-/* This says how to define a local common symbol (ie, not visible to
-   linker).  */
-#define ASM_OUTPUT_LOCAL(STREAM, NAME, SIZE, ROUNDED)                  \
-  xtensa_declare_object (STREAM, NAME, "\n\t.lcomm\t", ",%u\n", (SIZE))
+/* Declare an uninitialized external linkage data object.  */
+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
+  asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
 
 /* This is how to output an element of a case-vector that is absolute.  */
 #define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE)                         \
@@ -1648,8 +1434,9 @@ typedef struct xtensa_args {
 
 
 /* Define the strings to put out for each section in the object file.  */
-#define TEXT_SECTION_ASM_OP    "\t.text"       /* instructions */
-#define DATA_SECTION_ASM_OP    "\t.data"       /* large data */
+#define TEXT_SECTION_ASM_OP    "\t.text"
+#define DATA_SECTION_ASM_OP    "\t.data"
+#define BSS_SECTION_ASM_OP     "\t.section\t.bss"
 
 
 /* Define output to appear before the constant pool.  If the function
@@ -1659,7 +1446,7 @@ typedef struct xtensa_args {
 #define ASM_OUTPUT_POOL_PROLOGUE(FILE, FUNNAME, FUNDECL, SIZE)          \
   do {                                                                 \
     tree fnsection;                                                    \
-    resolve_unique_section ((FUNDECL), 0);                             \
+    resolve_unique_section ((FUNDECL), 0, flag_function_sections);     \
     fnsection = DECL_SECTION_NAME (FUNDECL);                           \
     if (fnsection != NULL_TREE)                                                \
       {                                                                        \
@@ -1668,7 +1455,10 @@ typedef struct xtensa_args {
                 strcmp (fnsectname, ".text") ? fnsectname : "");       \
       }                                                                        \
     if ((SIZE) > 0)                                                    \
-      function_section (FUNDECL);                                      \
+      {                                                                        \
+       function_section (FUNDECL);                                     \
+       fprintf (FILE, "\t.literal_position\n");                        \
+      }                                                                        \
   } while (0)
 
 
@@ -1687,15 +1477,6 @@ typedef struct xtensa_args {
     goto JUMPTO;                                                       \
   } while (0)
 
-/* Store in OUTPUT a string (made with alloca) containing
-   an assembler-name for a local static variable named NAME.
-   LABELNO is an integer which is different for each call.  */
-#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)                 \
-  do {                                                                 \
-    (OUTPUT) = (char *) alloca (strlen (NAME) + 10);                   \
-    sprintf ((OUTPUT), "%s.%u", (NAME), (LABELNO));                    \
-  } while (0)
-
 /* How to start an assembler comment. */
 #define ASM_COMMENT_START "#"