OSDN Git Service

* varasm.c (make_decl_rtl): Remove call to REDO_SECTION_INFO_P;
[pf3gnuchains/gcc-fork.git] / gcc / config / arm / arm.h
index 4f2692a..853db6d 100644 (file)
@@ -1,5 +1,6 @@
 /* Definitions of target machine for GNU compiler, for ARM.
-   Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+   2001, 2002 Free Software Foundation, Inc.
    Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
    and Martin Simmons (@harleqn.co.uk).
    More major hacks by Richard Earnshaw (rearnsha@arm.com)
@@ -22,8 +23,8 @@ along with GNU CC; see the file COPYING.  If not, write to
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
-#ifndef __ARM_H__
-#define __ARM_H__
+#ifndef GCC_ARM_H
+#define GCC_ARM_H
 
 #define TARGET_CPU_arm2                0x0000
 #define TARGET_CPU_arm250      0x0000
@@ -48,6 +49,7 @@ Boston, MA 02111-1307, USA.  */
 #define TARGET_CPU_strongarm1100 0x0040
 #define TARGET_CPU_arm9                0x0080
 #define TARGET_CPU_arm9tdmi    0x0080
+#define TARGET_CPU_xscale       0x0100
 /* Configure didn't specify.  */
 #define TARGET_CPU_generic     0x8000
 
@@ -59,7 +61,6 @@ typedef enum arm_cond_code
 arm_cc;
 
 extern arm_cc arm_current_cc;
-extern const char * arm_condition_codes[];
 
 #define ARM_INVERSE_CONDITION_CODE(X)  ((arm_cc) (((int)X) ^ 1))
 
@@ -80,8 +81,6 @@ extern struct rtx_def * pool_vector_label;
 /* Set to 1 when a return insn is output, this means that the epilogue
    is not needed. */
 extern int return_used_this_function;
-/* Nonzero if the prologue must setup `fp'.  */
-extern int current_function_anonymous_args;
 \f
 /* Just in case configure has failed to define anything. */
 #ifndef TARGET_CPU_DEFAULT
@@ -89,9 +88,10 @@ extern int current_function_anonymous_args;
 #endif
 
 /* If the configuration file doesn't specify the cpu, the subtarget may
-   override it.  If it doesn't, then default to an ARM6. */
+   override it.  If it doesn't, then default to an ARM6.  */
 #if TARGET_CPU_DEFAULT == TARGET_CPU_generic
 #undef TARGET_CPU_DEFAULT
+
 #ifdef SUBTARGET_CPU_DEFAULT
 #define TARGET_CPU_DEFAULT SUBTARGET_CPU_DEFAULT
 #else
@@ -108,32 +108,34 @@ extern int current_function_anonymous_args;
 #if TARGET_CPU_DEFAULT == TARGET_CPU_arm7m
 #define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_3M__"
 #else
-#if TARGET_CPU_DEFAULT == TARGET_CPU_arm7tdmi || TARGET_CPU_DEFAULT == TARGET_CPU_arm9
+#if TARGET_CPU_DEFAULT == TARGET_CPU_arm7tdmi || TARGET_CPU_DEFAULT == TARGET_CPU_arm9 || TARGET_CPU_DEFAULT == TARGET_CPU_arm9tdmi
 #define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_4T__"
 #else
-#if TARGET_CPU_DEFAULT == TARGET_CPU_arm8 || TARGET_CPU_DEFAULT == TARGET_CPU_arm810 || TARGET_CPU_DEFAULT == TARGET_CPU_strongarm
+#if TARGET_CPU_DEFAULT == TARGET_CPU_arm8 || TARGET_CPU_DEFAULT == TARGET_CPU_arm810 || TARGET_CPU_DEFAULT == TARGET_CPU_strongarm || TARGET_CPU_DEFAULT == TARGET_CPU_strongarm110 || TARGET_CPU_DEFAULT == TARGET_CPU_strongarm1100 
 #define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_4__"
 #else
+#if TARGET_CPU_DEFAULT == TARGET_CPU_xscale
+#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_5TE__ -D__XSCALE__"
+#else
 Unrecognized value in TARGET_CPU_DEFAULT.
 #endif
 #endif
 #endif
 #endif
 #endif
-
-#ifndef CPP_PREDEFINES
-#define CPP_PREDEFINES  "-Acpu(arm) -Amachine(arm)"
 #endif
 
+#undef  CPP_SPEC
 #define CPP_SPEC "\
 %(cpp_cpu_arch) %(cpp_apcs_pc) %(cpp_float) \
 %(cpp_endian) %(subtarget_cpp_spec) %(cpp_isa) %(cpp_interwork)"
 
-#define CPP_ISA_SPEC "%{mthumb:-Dthumb -D__thumb__} %{!mthumb:-Darm -D__arm__}"
+#define CPP_ISA_SPEC "%{mthumb:-D__thumb__} %{!mthumb:-D__arm__}"
 
 /* Set the architecture define -- if -march= is set, then it overrides
    the -mcpu= setting.  */
 #define CPP_CPU_ARCH_SPEC "\
+-Acpu=arm -Amachine=arm \
 %{march=arm2:-D__ARM_ARCH_2__} \
 %{march=arm250:-D__ARM_ARCH_2__} \
 %{march=arm3:-D__ARM_ARCH_2__} \
@@ -160,6 +162,8 @@ Unrecognized value in TARGET_CPU_DEFAULT.
 %{march=strongarm:-D__ARM_ARCH_4__} \
 %{march=strongarm110:-D__ARM_ARCH_4__} \
 %{march=strongarm1100:-D__ARM_ARCH_4__} \
+%{march=xscale:-D__ARM_ARCH_5TE__} \
+%{march=xscale:-D__XSCALE__} \
 %{march=armv2:-D__ARM_ARCH_2__} \
 %{march=armv2a:-D__ARM_ARCH_2__} \
 %{march=armv3:-D__ARM_ARCH_3__} \
@@ -197,6 +201,8 @@ Unrecognized value in TARGET_CPU_DEFAULT.
  %{mcpu=strongarm:-D__ARM_ARCH_4__} \
  %{mcpu=strongarm110:-D__ARM_ARCH_4__} \
  %{mcpu=strongarm1100:-D__ARM_ARCH_4__} \
+ %{mcpu=xscale:-D__ARM_ARCH_5TE__} \
+ %{mcpu=xscale:-D__XSCALE__} \
  %{!mcpu*:%(cpp_cpu_arch_default)}} \
 "
 
@@ -243,12 +249,18 @@ Unrecognized value in TARGET_CPU_DEFAULT.
 
 #define CPP_INTERWORK_SPEC "                                           \
 %{mthumb-interwork:                                                    \
-  %{mno-thumb-interwork: %eIncompatible interworking options}          \
+  %{mno-thumb-interwork: %eincompatible interworking options}          \
   -D__THUMB_INTERWORK__}                                               \
 %{!mthumb-interwork:%{!mno-thumb-interwork:%(cpp_interwork_default)}}  \
 "
 
+#ifndef CPP_PREDEFINES
+#define CPP_PREDEFINES ""
+#endif
+
+#ifndef CC1_SPEC
 #define CC1_SPEC ""
+#endif
 
 /* This macro defines names of additional specifications to put in the specs
    that can be used in various specifications like CC1_SPEC.  Its definition
@@ -414,9 +426,9 @@ Unrecognized value in TARGET_CPU_DEFAULT.
   {"no-poke-function-name",    -ARM_FLAG_POKE, "" },                   \
   {"fpe",                      ARM_FLAG_FPE,  "" },                    \
   {"apcs-32",                  ARM_FLAG_APCS_32,                       \
-   N_("Use the 32bit version of the APCS") },                          \
+   N_("Use the 32-bit version of the APCS") },                         \
   {"apcs-26",                 -ARM_FLAG_APCS_32,                       \
-   N_("Use the 26bit version of the APCS") },                          \
+   N_("Use the 26-bit version of the APCS") },                         \
   {"apcs-stack-check",         ARM_FLAG_APCS_STACK, "" },              \
   {"no-apcs-stack-check",      -ARM_FLAG_APCS_STACK, "" },             \
   {"apcs-float",               ARM_FLAG_APCS_FLOAT,                    \
@@ -443,14 +455,14 @@ Unrecognized value in TARGET_CPU_DEFAULT.
   {"words-little-endian",       ARM_FLAG_LITTLE_WORDS,                 \
    N_("Assume big endian bytes, little endian words") },               \
   {"thumb-interwork",          ARM_FLAG_INTERWORK,                     \
-   N_("Support calls between THUMB and ARM instructions sets") },      \
+   N_("Support calls between Thumb and ARM instruction sets") },       \
   {"no-thumb-interwork",       -ARM_FLAG_INTERWORK, "" },              \
   {"abort-on-noreturn",         ARM_FLAG_ABORT_NORETURN,               \
    N_("Generate a call to abort if a noreturn function returns")},     \
   {"no-abort-on-noreturn",     -ARM_FLAG_ABORT_NORETURN, "" },         \
-  {"sched-prolog",             -ARM_FLAG_NO_SCHED_PRO,                 \
+  {"no-sched-prolog",           ARM_FLAG_NO_SCHED_PRO,                 \
    N_("Do not move instructions into a function's prologue") },                \
-  {"no-sched-prolog",           ARM_FLAG_NO_SCHED_PRO, "" },           \
+  {"sched-prolog",             -ARM_FLAG_NO_SCHED_PRO, "" },           \
   {"single-pic-base",          ARM_FLAG_SINGLE_PIC_BASE,               \
    N_("Do not load the PIC register in function prologues") },         \
   {"no-single-pic-base",       -ARM_FLAG_SINGLE_PIC_BASE, "" },                \
@@ -538,7 +550,9 @@ extern enum floating_point_type arm_fpu_arch;
 
 /* Default floating point architecture.  Override in sub-target if
    necessary.  */
+#ifndef FP_DEFAULT
 #define FP_DEFAULT FP_SOFT2
+#endif
 
 /* Nonzero if the processor has a fast multiply insn, and one that does
    a 64-bit multiply of two 32-bit values.  */
@@ -550,6 +564,9 @@ extern int arm_arch4;
 /* Nonzero if this chip supports the ARM Architecture 5 extensions */
 extern int arm_arch5;
 
+/* Nonzero if this chip supports the ARM Architecture 5E extensions */
+extern int arm_arch5e;
+
 /* Nonzero if this chip can benefit from load scheduling.  */
 extern int arm_ld_sched;
 
@@ -559,7 +576,10 @@ extern int thumb_code;
 /* Nonzero if this chip is a StrongARM.  */
 extern int arm_is_strong;
 
-/* Nonzero if this chip is a an ARM6 or an ARM7.  */
+/* Nonzero if this chip is an XScale.  */
+extern int arm_is_xscale;
+
+/* Nonzero if this chip is an ARM6 or an ARM7.  */
 extern int arm_is_6_or_7;
 
 #ifndef TARGET_DEFAULT
@@ -570,6 +590,7 @@ extern int arm_is_6_or_7;
    that is controlled by the APCS-FRAME option.  */
 #define CAN_DEBUG_WITHOUT_FP
 
+#undef  TARGET_MEM_FUNCTIONS
 #define TARGET_MEM_FUNCTIONS 1
 
 #define OVERRIDE_OPTIONS  arm_override_options ()
@@ -675,9 +696,6 @@ extern int arm_is_6_or_7;
    This is always true, even when in little-endian mode.  */
 #define FLOAT_WORDS_BIG_ENDIAN 1
 
-/* Number of bits in an addressable storage unit */
-#define BITS_PER_UNIT  8
-
 #define BITS_PER_WORD  32
 
 #define UNITS_PER_WORD 4
@@ -690,19 +708,27 @@ extern int arm_is_6_or_7;
 
 #define FUNCTION_BOUNDARY  32
 
+/* The lowest bit is used to indicate Thumb-mode functions, so the
+   vbit must go into the delta field of pointers to member
+   functions.  */
+#define TARGET_PTRMEMFUNC_VBIT_LOCATION ptrmemfunc_vbit_in_delta
+
 #define EMPTY_FIELD_BOUNDARY  32
 
 #define BIGGEST_ALIGNMENT  32
 
 /* Make strings word-aligned so strcpy from constants will be faster.  */
-#define CONSTANT_ALIGNMENT(EXP, ALIGN)  \
-  (TREE_CODE (EXP) == STRING_CST        \
-   && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
+#define CONSTANT_ALIGNMENT_FACTOR (TARGET_THUMB || ! arm_is_xscale ? 1 : 2)
+    
+#define CONSTANT_ALIGNMENT(EXP, ALIGN)                         \
+  ((TREE_CODE (EXP) == STRING_CST                              \
+    && (ALIGN) < BITS_PER_WORD * CONSTANT_ALIGNMENT_FACTOR)    \
+   ? BITS_PER_WORD * CONSTANT_ALIGNMENT_FACTOR : (ALIGN))
 
 /* Setting STRUCTURE_SIZE_BOUNDARY to 32 produces more efficient code, but the
    value set in previous versions of this toolchain was 8, which produces more
    compact structures.  The command line option -mstructure_size_boundary=<n>
-   can be used to change this value.  For compatability with the ARM SDK
+   can be used to change this value.  For compatibility with the ARM SDK
    however the value should be left at 32.  ARM SDT Reference Manual (ARM DUI
    0020D) page 2-20 says "Structures are aligned on word boundaries".  */
 #define STRUCTURE_SIZE_BOUNDARY arm_structure_size_boundary
@@ -816,9 +842,10 @@ extern const char * structure_size_string;
 
 #define CONDITIONAL_REGISTER_USAGE                             \
 {                                                              \
+  int regno;                                                   \
+                                                               \
   if (TARGET_SOFT_FLOAT || TARGET_THUMB)                       \
     {                                                          \
-      int regno;                                               \
       for (regno = FIRST_ARM_FP_REGNUM;                                \
           regno <= LAST_ARM_FP_REGNUM; ++regno)                \
        fixed_regs[regno] = call_used_regs[regno] = 1;          \
@@ -876,8 +903,19 @@ extern const char * structure_size_string;
 /* Return the regiser number of the N'th (integer) argument.  */
 #define ARG_REGISTER(N)        (N - 1)
 
+#if 0 /* FIXME: The ARM backend has special code to handle structure
+        returns, and will reserve its own hidden first argument.  So
+        if this macro is enabled a *second* hidden argument will be
+        reserved, which will break binary compatibility with old
+        toolchains and also thunk handling.  One day this should be
+        fixed.  */
 /* RTX for structure returns.  NULL means use a hidden first argument.  */
 #define STRUCT_VALUE           0
+#else
+/* Register in which address to store a structure value
+   is passed to a function.  */
+#define STRUCT_VALUE_REGNUM    ARG_REGISTER (1)
+#endif
 
 /* Specify the registers used for certain standard purposes.
    The values of these macros are register numbers.  */
@@ -886,12 +924,15 @@ extern const char * structure_size_string;
 #define LAST_ARG_REGNUM        ARG_REGISTER (NUM_ARG_REGS)
 
 /* The number of the last "lo" register (thumb).  */
-#define LAST_LO_REGNUM          7
+#define LAST_LO_REGNUM         7
+
+/* The register that holds the return address in exception handlers.  */
+#define EXCEPTION_LR_REGNUM    2
 
 /* The native (Norcroft) Pascal compiler for the ARM passes the static chain
    as an invisible last argument (possible since varargs don't exist in
    Pascal), so the following is not true.  */
-#define STATIC_CHAIN_REGNUM    (TARGET_ARM ? 8 : 9)
+#define STATIC_CHAIN_REGNUM    (TARGET_ARM ? 12 : 9)
 
 /* Define this to be where the real frame pointer is if it is not possible to
    work out the offset between the frame pointer and the automatic variables
@@ -911,32 +952,21 @@ extern const char * structure_size_string;
    pointer.  */
 #define ARM_HARD_FRAME_POINTER_REGNUM  11
 #define THUMB_HARD_FRAME_POINTER_REGNUM         7
-#define HARD_FRAME_POINTER_REGNUM       (TARGET_ARM ? ARM_HARD_FRAME_POINTER_REGNUM : THUMB_HARD_FRAME_POINTER_REGNUM)
-#define FP_REGNUM                      HARD_FRAME_POINTER_REGNUM
 
-/* Scratch register - used in all kinds of places, eg trampolines.  */
-#define IP_REGNUM              12
+#define HARD_FRAME_POINTER_REGNUM              \
+  (TARGET_ARM                                  \
+   ? ARM_HARD_FRAME_POINTER_REGNUM             \
+   : THUMB_HARD_FRAME_POINTER_REGNUM)
 
-/* Register to use for pushing function arguments.  */
-#define STACK_POINTER_REGNUM   13
-#define SP_REGNUM              STACK_POINTER_REGNUM
-
-/* Register which holds return address from a subroutine call.  */
-#define LR_REGNUM              14
-
-/* Define this if the program counter is overloaded on a register.  */
-#define PC_REGNUM              15
+#define FP_REGNUM                      HARD_FRAME_POINTER_REGNUM
 
-/* The number of the last ARM (integer) register.  */
-#define LAST_ARM_REGNUM        15
+/* Register to use for pushing function arguments.  */
+#define STACK_POINTER_REGNUM   SP_REGNUM
 
 /* ARM floating pointer registers.  */
 #define FIRST_ARM_FP_REGNUM    16
 #define LAST_ARM_FP_REGNUM     23
 
-/* Internal, so that we don't need to refer to a raw number */
-#define CC_REGNUM              24
-
 /* Base register for access to local variables of the function.  */
 #define FRAME_POINTER_REGNUM   25
 
@@ -952,8 +982,8 @@ extern const char * structure_size_string;
    If we have to have a frame pointer we might as well make use of it.
    APCS says that the frame pointer does not need to be pushed in leaf
    functions, or simple tail call functions.  */
-#define FRAME_POINTER_REQUIRED                                         \
-  (current_function_has_nonlocal_label                                 \
+#define FRAME_POINTER_REQUIRED                                 \
+  (current_function_has_nonlocal_label                         \
    || (TARGET_ARM && TARGET_APCS_FRAME && ! leaf_function_p ()))
 
 /* Return number of consecutive hard regs needed starting at reg REGNO
@@ -970,23 +1000,9 @@ extern const char * structure_size_string;
     && REGNO != ARG_POINTER_REGNUM)    \
    ? 1 : NUM_REGS (MODE))
 
-/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
-   This is TRUE for ARM regs since they can hold anything, and TRUE for FPU
-   regs holding FP.
-   For the Thumb we only allow values bigger than SImode in registers 0 - 6,
-   so that there is always a second lo register available to hold the upper
-   part of the value.  Probably we ought to ensure that the register is the
-   start of an even numbered register pair.  */
+/* Return true if REGNO is suitable for holding a quantity of type MODE.  */
 #define HARD_REGNO_MODE_OK(REGNO, MODE)                                        \
-  (TARGET_ARM ?                                                                \
-   ((GET_MODE_CLASS (MODE) == MODE_CC) ? (REGNO == CC_REGNUM) :                \
-    (   REGNO <= LAST_ARM_REGNUM                                       \
-     || REGNO == FRAME_POINTER_REGNUM                                  \
-     || REGNO == ARG_POINTER_REGNUM                                    \
-     || GET_MODE_CLASS (MODE) == MODE_FLOAT))                          \
-   :                                                                   \
-   ((GET_MODE_CLASS (MODE) == MODE_CC) ? (REGNO == CC_REGNUM) :                \
-    (NUM_REGS (MODE) < 2 || REGNO < LAST_LO_REGNUM)))
+  arm_hard_regno_mode_ok ((REGNO), (MODE))
 
 /* Value is 1 if it is a good idea to tie two pseudo registers
    when one has mode MODE1 and one has mode MODE2.
@@ -1008,11 +1024,18 @@ extern const char * structure_size_string;
     16, 17, 18, 19, 20, 21, 22, 23, \
     24, 25, 26                     \
 }
+
+/* Interrupt functions can only use registers that have already been
+   saved by the prologue, even if they would normally be
+   call-clobbered.  */
+#define HARD_REGNO_RENAME_OK(SRC, DST)                                 \
+       (! IS_INTERRUPT (cfun->machine->func_type) ||                   \
+               regs_ever_live[DST])
 \f
 /* Register and constant classes.  */
 
 /* Register classes: used to be simple, just all ARM regs or all FPU regs
-   Now that the Thumb is involved it has become more compilcated.  */
+   Now that the Thumb is involved it has become more complicated.  */
 enum reg_class
 {
   NO_REGS,
@@ -1058,7 +1081,7 @@ enum reg_class
   { 0x200FFFF }, /* GENERAL_REGS */    \
   { 0x2FFFFFF }  /* ALL_REGS */                \
 }
-  
+
 /* The same information, inverted:
    Return the class number of the smallest class containing
    reg number REGNO.  This could be a conditional expression
@@ -1069,6 +1092,13 @@ enum reg_class
 #define INDEX_REG_CLASS  (TARGET_THUMB ? LO_REGS : GENERAL_REGS)
 #define BASE_REG_CLASS   (TARGET_THUMB ? BASE_REGS : GENERAL_REGS)
 
+/* For the Thumb the high registers cannot be used as base
+   registers when addressing quanitities in QI or HI mode.  */
+#define MODE_BASE_REG_CLASS(MODE)                                      \
+    (TARGET_ARM ? BASE_REGS :                                          \
+     (((MODE) == QImode || (MODE) == HImode || (MODE) == VOIDmode)     \
+     ? LO_REGS : BASE_REGS))
+
 /* When SMALL_REGISTER_CLASSES is nonzero, the compiler allows
    registers explicitly used in the rtl to be used as spill registers
    but prevents the compiler from extending the lifetime of these
@@ -1232,9 +1262,9 @@ enum reg_class
          else                                                             \
            break;                                                         \
                                                                           \
-         high = ((((val - low) & HOST_UINT (0xffffffff))                  \
-                  ^ HOST_UINT (0x80000000))                               \
-                 - HOST_UINT (0x80000000));                               \
+         high = ((((val - low) & (unsigned HOST_WIDE_INT) 0xffffffff)     \
+                  ^ (unsigned HOST_WIDE_INT) 0x80000000)                  \
+                 - (unsigned HOST_WIDE_INT) 0x80000000);                  \
          /* Check for overflow or zero */                                 \
          if (low == 0 || high == 0 || (high + low != val))                \
            break;                                                         \
@@ -1245,9 +1275,9 @@ enum reg_class
                            gen_rtx_PLUS (GET_MODE (X), XEXP (X, 0),       \
                                          GEN_INT (high)),                 \
                            GEN_INT (low));                                \
-         push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL_PTR,      \
-                      BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0,       \
-                      OPNUM, TYPE);                                       \
+         push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL,          \
+                      MODE_BASE_REG_CLASS (MODE), GET_MODE (X),           \
+                      VOIDmode, 0, 0, OPNUM, TYPE);                       \
          goto WIN;                                                        \
        }                                                                  \
     }                                                                     \
@@ -1268,12 +1298,12 @@ enum reg_class
       && GET_CODE (XEXP (X, 0)) == REG                                 \
       && XEXP (X, 0) == stack_pointer_rtx                              \
       && GET_CODE (XEXP (X, 1)) == CONST_INT                           \
-      && ! LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1))))             \
+      && ! THUMB_LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1))))       \
     {                                                                  \
       rtx orig_X = X;                                                  \
       X = copy_rtx (X);                                                        \
-      push_reload (orig_X, NULL_RTX, &X, NULL_PTR,                     \
-                  BASE_REG_CLASS,                                      \
+      push_reload (orig_X, NULL_RTX, &X, NULL,                         \
+                  MODE_BASE_REG_CLASS (MODE),                          \
                   Pmode, VOIDmode, 0, 0, OPNUM, TYPE);                 \
       goto WIN;                                                                \
     }                                                                  \
@@ -1292,7 +1322,7 @@ enum reg_class
   ((CLASS) == FPU_REGS ? 1 : NUM_REGS (MODE))
 
 /* Moves between FPU_REGS and GENERAL_REGS are two memory insns.  */
-#define REGISTER_MOVE_COST(FROM, TO)                   \
+#define REGISTER_MOVE_COST(MODE, FROM, TO)             \
   (TARGET_ARM ?                                                \
    ((FROM) == FPU_REGS && (TO) != FPU_REGS ? 20 :      \
     (FROM) != FPU_REGS && (TO) == FPU_REGS ? 20 : 2)   \
@@ -1377,19 +1407,59 @@ enum reg_class
 #define CALL_LONG              0x00000001      /* Always call indirect.  */
 #define CALL_SHORT             0x00000002      /* Never call indirect.  */
 
-/* A C structure for machine-specific, per-function data.  This is added
-   to the cfun structure.  */
-struct machine_function
+/* These bits describe the different types of function supported
+   by the ARM backend.  They are exclusive.  ie a function cannot be both a
+   normal function and an interworked function, for example.  Knowing the
+   type of a function is important for determining its prologue and
+   epilogue sequences.
+   Note value 7 is currently unassigned.  Also note that the interrupt
+   function types all have bit 2 set, so that they can be tested for easily.
+   Note that 0 is deliberately chosen for ARM_FT_UNKNOWN so that when the
+   machine_function structure is initialised (to zero) func_type will
+   default to unknown.  This will force the first use of arm_current_func_type
+   to call arm_compute_func_type.  */
+#define ARM_FT_UNKNOWN          0 /* Type has not yet been determined.  */
+#define ARM_FT_NORMAL           1 /* Your normal, straightforward function.  */
+#define ARM_FT_INTERWORKED      2 /* A function that supports interworking.  */
+#define ARM_FT_EXCEPTION_HANDLER 3 /* A C++ exception handler.  */
+#define ARM_FT_ISR              4 /* An interrupt service routine.  */
+#define ARM_FT_FIQ              5 /* A fast interrupt service routine.  */
+#define ARM_FT_EXCEPTION        6 /* An ARM exception handler (subcase of ISR).  */
+
+#define ARM_FT_TYPE_MASK       ((1 << 3) - 1)
+
+/* In addition functions can have several type modifiers,
+   outlined by these bit masks:  */
+#define ARM_FT_INTERRUPT       (1 << 2) /* Note overlap with FT_ISR and above.  */
+#define ARM_FT_NAKED           (1 << 3) /* No prologue or epilogue.  */
+#define ARM_FT_VOLATILE                (1 << 4) /* Does not return.  */
+#define ARM_FT_NESTED          (1 << 5) /* Embedded inside another func. */
+
+/* Some macros to test these flags.  */
+#define ARM_FUNC_TYPE(t)       (t & ARM_FT_TYPE_MASK)
+#define IS_INTERRUPT(t)                (t & ARM_FT_INTERRUPT)
+#define IS_VOLATILE(t)         (t & ARM_FT_VOLATILE)
+#define IS_NAKED(t)            (t & ARM_FT_NAKED)
+#define IS_NESTED(t)           (t & ARM_FT_NESTED)
+
+/* A C structure for machine-specific, per-function data.
+   This is added to the cfun structure.  */
+typedef struct machine_function
 {
-  /* Records __builtin_return address.  */
-  struct rtx_def *ra_rtx;
   /* Additionsl stack adjustment in __builtin_eh_throw.  */
   struct rtx_def *eh_epilogue_sp_ofs;
   /* Records if LR has to be saved for far jumps.  */
   int far_jump_used;
   /* Records if ARG_POINTER was ever live.  */
   int arg_pointer_live;
-};
+  /* Records if the save of LR has been eliminated.  */
+  int lr_save_eliminated;
+  /* Records the type of the current function.  */
+  unsigned long func_type;
+  /* Record if the function has a variable argument list.  */
+  int uses_anonymous_args;
+}
+machine_function;
 
 /* A C type for declaring a variable that is used as the first argument of
    `FUNCTION_ARG' and other related values.  For some target machines, the
@@ -1446,8 +1516,7 @@ typedef struct
 
 /* 1 if N is a possible register number for function argument passing.
    On the ARM, r0-r3 are used to pass args.  */
-#define FUNCTION_ARG_REGNO_P(REGNO)  \
-  ((REGNO) >= 0 && (REGNO) <= 3)
+#define FUNCTION_ARG_REGNO_P(REGNO)    (IN_RANGE ((REGNO), 0, 3))
 
 \f
 /* Tail calling.  */
@@ -1471,23 +1540,11 @@ typedef struct
    that way.  */
 #define SETUP_INCOMING_VARARGS(CUM, MODE, TYPE, PRETEND_SIZE, NO_RTL)  \
 {                                                                      \
-  extern int current_function_anonymous_args;                          \
-  current_function_anonymous_args = 1;                                 \
+  cfun->machine->uses_anonymous_args = 1;                              \
   if ((CUM).nregs < NUM_ARG_REGS)                                      \
     (PRETEND_SIZE) = (NUM_ARG_REGS - (CUM).nregs) * UNITS_PER_WORD;    \
 }
 
-/* Generate assembly output for the start of a function.  */
-#define FUNCTION_PROLOGUE(STREAM, SIZE)                \
-  do                                           \
-    {                                          \
-      if (TARGET_ARM)                          \
-        output_arm_prologue (STREAM, SIZE);    \
-      else                                     \
-       output_thumb_prologue (STREAM);         \
-    }                                          \
-  while (0)
-
 /* If your target environment doesn't prefix user functions with an
    underscore, you may wish to re-define this to prevent any conflicts.
    e.g. AOF may prefix mcount with an underscore.  */
@@ -1511,6 +1568,7 @@ typedef struct
 
    The ``mov ip,lr'' seems like a good idea to stick with cc convention.
    ``prof'' doesn't seem to mind about this!  */
+#ifndef ARM_FUNCTION_PROFILER
 #define ARM_FUNCTION_PROFILER(STREAM, LABELNO)         \
 {                                                      \
   char temp[20];                                       \
@@ -1522,15 +1580,18 @@ typedef struct
   fputc ('\n', STREAM);                                        \
   ASM_GENERATE_INTERNAL_LABEL (temp, "LP", LABELNO);   \
   sym = gen_rtx (SYMBOL_REF, Pmode, temp);             \
-  ASM_OUTPUT_INT (STREAM, sym);                                \
+  assemble_aligned_integer (UNITS_PER_WORD, sym);      \
 }
+#endif
 
+#ifndef THUMB_FUNCTION_PROFILER
 #define THUMB_FUNCTION_PROFILER(STREAM, LABELNO)       \
 {                                                      \
-  fprintf (STREAM, "\tmov\\tip, lr\n");                        \
+  fprintf (STREAM, "\tmov\tip, lr\n");                 \
   fprintf (STREAM, "\tbl\tmcount\n");                  \
   fprintf (STREAM, "\t.word\tLP%d\n", LABELNO);                \
 }
+#endif
 
 #define FUNCTION_PROFILER(STREAM, LABELNO)             \
   if (TARGET_ARM)                                      \
@@ -1547,9 +1608,7 @@ typedef struct
    frame.  */
 #define EXIT_IGNORE_STACK 1
 
-/* Generate the assembly code for function exit. */
-#define FUNCTION_EPILOGUE(STREAM, SIZE)        \
-  output_func_epilogue (SIZE)
+#define EPILOGUE_USES(REGNO) (reload_completed && (REGNO) == LR_REGNUM)
 
 /* Determine if the epilogue should be output as RTL.
    You should override this if you define FUNCTION_EXTRA_EPILOGUE.  */
@@ -1568,7 +1627,7 @@ typedef struct
    pointer register.  Secondly, the pseudo frame pointer register can always
    be eliminated; it is replaced with either the stack or the real frame
    pointer.  Note we have to use {ARM|THUMB}_HARD_FRAME_POINTER_REGNUM
-   because the defintion of HARD_FRAME_POINTER_REGNUM is not a constant.  */
+   because the definition of HARD_FRAME_POINTER_REGNUM is not a constant.  */
 
 #define ELIMINABLE_REGS                                                \
 {{ ARG_POINTER_REGNUM,        STACK_POINTER_REGNUM            },\
@@ -1597,52 +1656,11 @@ typedef struct
 /* Define the offset between two registers, one to be eliminated, and the
    other its replacement, at the start of a routine.  */
 #define ARM_INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)               \
-{                                                                      \
-  int volatile_func = arm_volatile_func ();                            \
-  if ((FROM) == ARG_POINTER_REGNUM && (TO) == HARD_FRAME_POINTER_REGNUM)\
-    (OFFSET) = 0;                                                      \
-  else if ((FROM) == FRAME_POINTER_REGNUM                              \
-          && (TO) == STACK_POINTER_REGNUM)                             \
-    (OFFSET) = current_function_outgoing_args_size                     \
-               + ROUND_UP (get_frame_size ());                         \
-  else                                                                 \
+  do                                                                   \
     {                                                                  \
-      int regno;                                                       \
-      int offset = 12;                                                 \
-      int saved_hard_reg = 0;                                          \
-                                                                       \
-      if (! volatile_func)                                             \
-        {                                                              \
-          for (regno = 0; regno <= 10; regno++)                                \
-           if (regs_ever_live[regno] && ! call_used_regs[regno])       \
-             saved_hard_reg = 1, offset += 4;                          \
-         if (! TARGET_APCS_FRAME                                       \
-             && ! frame_pointer_needed                                 \
-             && regs_ever_live[HARD_FRAME_POINTER_REGNUM]              \
-             && ! call_used_regs[HARD_FRAME_POINTER_REGNUM])           \
-           saved_hard_reg = 1, offset += 4;                            \
-         /* PIC register is a fixed reg, so call_used_regs set.  */    \
-         if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])      \
-           saved_hard_reg = 1, offset += 4;                            \
-          for (regno = FIRST_ARM_FP_REGNUM;                            \
-              regno <= LAST_ARM_FP_REGNUM; regno++)                    \
-           if (regs_ever_live[regno] && ! call_used_regs[regno])       \
-             offset += 12;                                             \
-       }                                                               \
-      if ((FROM) == FRAME_POINTER_REGNUM)                              \
-       (OFFSET) = - offset;                                            \
-      else                                                             \
-       {                                                               \
-          if (! frame_pointer_needed)                                  \
-            offset -= 16;                                              \
-          if (! volatile_func                                          \
-              && (regs_ever_live[LR_REGNUM] || saved_hard_reg))        \
-            offset += 4;                                               \
-          offset += current_function_outgoing_args_size;               \
-          (OFFSET) = ROUND_UP (get_frame_size ()) + offset;            \
-         }                                                             \
+      (OFFSET) = arm_compute_initial_elimination_offset (FROM, TO);    \
     }                                                                  \
-}
+  while (0)
 
 /* Note:  This macro must match the code in thumb_function_prologue().  */
 #define THUMB_INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)             \
@@ -1680,7 +1698,7 @@ typedef struct
 
 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)                   \
   if (TARGET_ARM)                                                      \
-    ARM_INITIAL_ELIMINATION_OFFSET (FROM, TO, OFFSET)                  \
+    ARM_INITIAL_ELIMINATION_OFFSET (FROM, TO, OFFSET);                 \
   else                                                                 \
     THUMB_INITIAL_ELIMINATION_OFFSET (FROM, TO, OFFSET)
      
@@ -1701,14 +1719,14 @@ typedef struct
           .word        static chain value
           .word        function's address
    ??? FIXME: When the trampoline returns, r8 will be clobbered.  */
-#define ARM_TRAMPOLINE_TEMPLATE(FILE)                  \
-{                                                      \
-  asm_fprintf (FILE, "\tldr\t%r, [%r, #0]\n",          \
-              STATIC_CHAIN_REGNUM, PC_REGNUM);         \
-  asm_fprintf (FILE, "\tldr\t%r, [%r, #0]\n",          \
-              PC_REGNUM, PC_REGNUM);                   \
-  ASM_OUTPUT_INT (FILE, const0_rtx);                   \
-  ASM_OUTPUT_INT (FILE, const0_rtx);                   \
+#define ARM_TRAMPOLINE_TEMPLATE(FILE)                          \
+{                                                              \
+  asm_fprintf (FILE, "\tldr\t%r, [%r, #0]\n",                  \
+              STATIC_CHAIN_REGNUM, PC_REGNUM);                 \
+  asm_fprintf (FILE, "\tldr\t%r, [%r, #0]\n",                  \
+              PC_REGNUM, PC_REGNUM);                           \
+  assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);       \
+  assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);       \
 }
 
 /* On the Thumb we always switch into ARM mode to execute the trampoline.
@@ -1743,8 +1761,8 @@ typedef struct
 /* Length in units of the trampoline for entering a nested function.  */
 #define TRAMPOLINE_SIZE  (TARGET_ARM ? 16 : 24)
 
-/* Alignment required for a trampoline in units.  */
-#define TRAMPOLINE_ALIGN  4
+/* Alignment required for a trampoline in bits.  */
+#define TRAMPOLINE_ALIGNMENT  32
 
 /* Emit RTL insns to initialize the variable parts of a trampoline.
    FNADDR is an RTX for the address of the function's pure code.
@@ -1775,23 +1793,23 @@ typedef struct
   ((R TEST VALUE) || ((unsigned) reg_renumber[R] TEST VALUE))
 
 /*   On the ARM, don't allow the pc to be used.  */
-#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE)                  \
-  (TARGET_THUMB ?                                              \
-    (    TEST_REGNO (REGNO, <=, LAST_LO_REGNUM)                        \
-      || (GET_MODE_SIZE (MODE) >= 4                            \
-         && TEST_REGNO (REGNO, ==, STACK_POINTER_REGNUM)))     \
-   :(                                                          \
-         TEST_REGNO (REGNO, <, PC_REGNUM)                      \
-      || TEST_REGNO (REGNO, ==, FRAME_POINTER_REGNUM)          \
-      || TEST_REGNO (REGNO, ==, ARG_POINTER_REGNUM)))
-
-/* This is like REGNO_MODE_OF_FOR_BASE_P, except that in Thumb mode
-   the stack pointer is always acceptable, hence the passing of SImode  */
-#define REGNO_OK_FOR_BASE_P(REGNO)     \
-  REGNO_MODE_OK_FOR_BASE_P (REGNO, SImode)
-
-/* We play tricks with REGNO_MODE_OK... here, so that for ARM the macros
-   are the same, but for Thumb only registers 0 - 7 are OK.  */
+#define ARM_REGNO_OK_FOR_BASE_P(REGNO)                 \
+  (TEST_REGNO (REGNO, <, PC_REGNUM)                    \
+   || TEST_REGNO (REGNO, ==, FRAME_POINTER_REGNUM)     \
+   || TEST_REGNO (REGNO, ==, ARG_POINTER_REGNUM))
+
+#define THUMB_REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE)            \
+  (TEST_REGNO (REGNO, <=, LAST_LO_REGNUM)                      \
+   || (GET_MODE_SIZE (MODE) >= 4                               \
+       && TEST_REGNO (REGNO, ==, STACK_POINTER_REGNUM)))
+
+#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE)          \
+  (TARGET_THUMB                                                \
+   ? THUMB_REGNO_MODE_OK_FOR_BASE_P (REGNO, MODE)      \
+   : ARM_REGNO_OK_FOR_BASE_P (REGNO))
+
+/* For ARM code, we don't care about the mode, but for Thumb, the index
+   must be suitable for use in a QImode load.  */
 #define REGNO_OK_FOR_INDEX_P(REGNO)    \
   REGNO_MODE_OK_FOR_BASE_P (REGNO, QImode)
 
@@ -1829,7 +1847,8 @@ typedef struct
 #define THUMB_LEGITIMATE_CONSTANT_P(X) \
  (   GET_CODE (X) == CONST_INT         \
   || GET_CODE (X) == CONST_DOUBLE      \
-  || CONSTANT_ADDRESS_P (X))
+  || CONSTANT_ADDRESS_P (X)            \
+  || flag_pic)
 
 #define LEGITIMATE_CONSTANT_P(X)       \
   (TARGET_ARM ? ARM_LEGITIMATE_CONSTANT_P (X) : THUMB_LEGITIMATE_CONSTANT_P (X))
@@ -1870,20 +1889,20 @@ typedef struct
    `assemble_name' uses this.  */
 #undef  ASM_OUTPUT_LABELREF
 #define ASM_OUTPUT_LABELREF(FILE, NAME)                \
-  fprintf (FILE, "%s%s", USER_LABEL_PREFIX, arm_strip_name_encoding (NAME))
+  asm_fprintf (FILE, "%U%s", arm_strip_name_encoding (NAME))
 
 /* If we are referencing a function that is weak then encode a long call
    flag in the function name, otherwise if the function is static or
    or known to be defined in this file then encode a short call flag.
    This macro is used inside the ENCODE_SECTION macro.  */
 #define ARM_ENCODE_CALL_TYPE(decl)                                     \
-  if (TREE_CODE (decl) == FUNCTION_DECL)                               \
+  if (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')                       \
     {                                                                  \
-      if (DECL_WEAK (decl))                                            \
+      if (TREE_CODE (decl) == FUNCTION_DECL && DECL_WEAK (decl))       \
         arm_encode_call_attribute (decl, LONG_CALL_FLAG_CHAR);         \
       else if (! TREE_PUBLIC (decl))                                   \
         arm_encode_call_attribute (decl, SHORT_CALL_FLAG_CHAR);                \
-    }                                                                  \
+    }
 
 /* Symbols in the text segment can be accessed without indirecting via the
    constant pool; it may take an extra binary operation, but this is still
@@ -1893,7 +1912,7 @@ typedef struct
 /* This doesn't work with AOF syntax, since the string table may be in
    a different AREA.  */
 #ifndef AOF_ASSEMBLER
-#define ENCODE_SECTION_INFO(decl)                                      \
+#define ENCODE_SECTION_INFO(decl, first)                               \
 {                                                                      \
   if (optimize > 0 && TREE_CONSTANT (decl)                             \
       && (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))   \
@@ -1902,12 +1921,14 @@ typedef struct
                  ? TREE_CST_RTL (decl) : DECL_RTL (decl));             \
       SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;                             \
     }                                                                  \
-  ARM_ENCODE_CALL_TYPE (decl)                                          \
+  if (first)                                                           \
+    ARM_ENCODE_CALL_TYPE (decl)                                                \
 }
 #else
-#define ENCODE_SECTION_INFO(decl)                                      \
+#define ENCODE_SECTION_INFO(decl, first)                               \
 {                                                                      \
-  ARM_ENCODE_CALL_TYPE (decl)                                          \
+  if (first)                                                           \
+    ARM_ENCODE_CALL_TYPE (decl)                                                \
 }
 #endif
 
@@ -1922,48 +1943,51 @@ typedef struct
    The symbol REG_OK_STRICT causes the latter definition to be used.  */
 #ifndef REG_OK_STRICT
 
-#define REG_MODE_OK_FOR_BASE_P(X, MODE)                \
-  (TARGET_THUMB ?                              \
-    (   REGNO (X) <= LAST_LO_REGNUM            \
-     || REGNO (X) >= FIRST_PSEUDO_REGISTER     \
-     || (GET_MODE_SIZE (MODE) >= 4             \
-        && (REGNO (X) == STACK_POINTER_REGNUM  \
-             ||   (X) == hard_frame_pointer_rtx \
-             ||   (X) == arg_pointer_rtx)))    \
-   :(                                          \
-        REGNO (X) <= LAST_ARM_REGNUM           \
-     || REGNO (X) >= FIRST_PSEUDO_REGISTER     \
-     || REGNO (X) == FRAME_POINTER_REGNUM      \
-     || REGNO (X) == ARG_POINTER_REGNUM))
-
-/* Nonzero if X is a hard reg that can be used as a base reg
-   or if it is a pseudo reg.  */
-#define REG_OK_FOR_BASE_P(X)                           \
-  REG_MODE_OK_FOR_BASE_P (X, SImode)  
+#define ARM_REG_OK_FOR_BASE_P(X)               \
+  (REGNO (X) <= LAST_ARM_REGNUM                        \
+   || REGNO (X) >= FIRST_PSEUDO_REGISTER       \
+   || REGNO (X) == FRAME_POINTER_REGNUM                \
+   || REGNO (X) == ARG_POINTER_REGNUM)
 
-/* Nonzero if X is a hard reg that can be used as an index
-   or if it is a pseudo reg.  On the Thumb, the stack pointer
-   is not suitable.  */
-#define REG_OK_FOR_INDEX_P(X)  \
-  REG_MODE_OK_FOR_BASE_P (X, QImode)  
-
-/* Just like REG_OK_FOR_BASE_P except that we also allow the PC.  */
-#define REG_OK_FOR_PRE_POST_P(X) \
-  (REG_OK_FOR_BASE_P (X) || REGNO(X) == PC_REGNUM)
+#define THUMB_REG_MODE_OK_FOR_BASE_P(X, MODE)  \
+  (REGNO (X) <= LAST_LO_REGNUM                 \
+   || REGNO (X) >= FIRST_PSEUDO_REGISTER       \
+   || (GET_MODE_SIZE (MODE) >= 4               \
+       && (REGNO (X) == STACK_POINTER_REGNUM   \
+          || (X) == hard_frame_pointer_rtx     \
+          || (X) == arg_pointer_rtx)))
 
 #else /* REG_OK_STRICT */
 
-/* Nonzero if X is a hard reg that can be used as a base reg.  */
-#define REG_OK_FOR_BASE_P(X)  REGNO_OK_FOR_BASE_P (REGNO (X))
-
-/* Nonzero if X is a hard reg that can be used as an index.  */
-#define REG_OK_FOR_INDEX_P(X)  REGNO_OK_FOR_INDEX_P (REGNO (X))
+#define ARM_REG_OK_FOR_BASE_P(X)               \
+  ARM_REGNO_OK_FOR_BASE_P (REGNO (X))
 
-/* Just like REG_OK_FOR_BASE_P except that we also allow the PC.  */
-#define REG_OK_FOR_PRE_POST_P(X) \
-  (REG_OK_FOR_BASE_P (X) || TEST_REGNO (REGNO (X), ==, PC_REGNUM))
+#define THUMB_REG_MODE_OK_FOR_BASE_P(X, MODE)  \
+  THUMB_REGNO_MODE_OK_FOR_BASE_P (REGNO (X), MODE)
 
 #endif /* REG_OK_STRICT */
+
+/* Now define some helpers in terms of the above.  */
+
+#define REG_MODE_OK_FOR_BASE_P(X, MODE)                \
+  (TARGET_THUMB                                        \
+   ? THUMB_REG_MODE_OK_FOR_BASE_P (X, MODE)    \
+   : ARM_REG_OK_FOR_BASE_P (X))
+
+#define ARM_REG_OK_FOR_INDEX_P(X) ARM_REG_OK_FOR_BASE_P (X)
+
+/* For Thumb, a valid index register is anything that can be used in
+   a byte load instruction.  */
+#define THUMB_REG_OK_FOR_INDEX_P(X) THUMB_REG_MODE_OK_FOR_BASE_P (X, QImode)
+
+/* Nonzero if X is a hard reg that can be used as an index
+   or if it is a pseudo reg.  On the Thumb, the stack pointer
+   is not suitable.  */
+#define REG_OK_FOR_INDEX_P(X)                  \
+  (TARGET_THUMB                                        \
+   ? THUMB_REG_OK_FOR_INDEX_P (X)              \
+   : ARM_REG_OK_FOR_INDEX_P (X))
+
 \f
 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
    that is a valid memory address for an instruction.
@@ -1973,78 +1997,81 @@ typedef struct
    The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS. */
      
 /* --------------------------------arm version----------------------------- */
-#define BASE_REGISTER_RTX_P(X)  \
-  (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))
+#define ARM_BASE_REGISTER_RTX_P(X)  \
+  (GET_CODE (X) == REG && ARM_REG_OK_FOR_BASE_P (X))
 
-#define INDEX_REGISTER_RTX_P(X)  \
-  (GET_CODE (X) == REG && REG_OK_FOR_INDEX_P (X))
+#define ARM_INDEX_REGISTER_RTX_P(X)  \
+  (GET_CODE (X) == REG && ARM_REG_OK_FOR_INDEX_P (X))
 
 /* A C statement (sans semicolon) to jump to LABEL for legitimate index RTXs
    used by the macro GO_IF_LEGITIMATE_ADDRESS.  Floating point indices can
    only be small constants. */
-#define GO_IF_LEGITIMATE_INDEX(MODE, BASE_REGNO, INDEX, LABEL)                         \
-  do                                                                                   \
-    {                                                                                  \
-      HOST_WIDE_INT range;                                                             \
-      enum rtx_code code = GET_CODE (INDEX);                                           \
-                                                                                       \
-      if (TARGET_HARD_FLOAT && GET_MODE_CLASS (MODE) == MODE_FLOAT)                    \
-       {                                                                               \
-         if (code == CONST_INT && INTVAL (INDEX) < 1024                                \
-             && INTVAL (INDEX) > -1024                                                 \
-             && (INTVAL (INDEX) & 3) == 0)                                             \
-           goto LABEL;                                                                 \
-       }                                                                               \
-      else                                                                             \
-       {                                                                               \
-         if (INDEX_REGISTER_RTX_P (INDEX) && GET_MODE_SIZE (MODE) <= 4)                \
-           goto LABEL;                                                                 \
-         if (GET_MODE_SIZE (MODE) <= 4  && code == MULT                                \
-             && (! arm_arch4 || (MODE) != HImode))                                     \
-           {                                                                           \
-             rtx xiop0 = XEXP (INDEX, 0);                                              \
-             rtx xiop1 = XEXP (INDEX, 1);                                              \
-             if (INDEX_REGISTER_RTX_P (xiop0)                                          \
-                 && power_of_two_operand (xiop1, SImode))                              \
-               goto LABEL;                                                             \
-             if (INDEX_REGISTER_RTX_P (xiop1)                                          \
-                 && power_of_two_operand (xiop0, SImode))                              \
-               goto LABEL;                                                             \
-           }                                                                           \
-         if (GET_MODE_SIZE (MODE) <= 4                                                 \
-             && (code == LSHIFTRT || code == ASHIFTRT                                  \
-                 || code == ASHIFT || code == ROTATERT)                                \
-             && (! arm_arch4 || (MODE) != HImode))                                     \
-           {                                                                           \
-             rtx op = XEXP (INDEX, 1);                                                 \
-             if (INDEX_REGISTER_RTX_P (XEXP (INDEX, 0))                                \
-                 && GET_CODE (op) == CONST_INT && INTVAL (op) > 0                      \
-                 && INTVAL (op) <= 31)                                                 \
-               goto LABEL;                                                             \
-           }                                                                           \
-         /* NASTY: Since this limits the addressing of unsigned byte loads */          \
-         range = ((MODE) == HImode || (MODE) == QImode)                                \
-           ? (arm_arch4 ? 256 : 4095) : 4096;                                          \
-         if (code == CONST_INT && INTVAL (INDEX) < range                               \
-             && INTVAL (INDEX) > -range)                                               \
-           goto LABEL;                                                                 \
-       }                                                                               \
-    }                                                                                  \
+#define ARM_GO_IF_LEGITIMATE_INDEX(MODE, BASE_REGNO, INDEX, LABEL)     \
+  do                                                                   \
+    {                                                                  \
+      HOST_WIDE_INT range;                                             \
+      enum rtx_code code = GET_CODE (INDEX);                           \
+                                                                       \
+      if (TARGET_HARD_FLOAT && GET_MODE_CLASS (MODE) == MODE_FLOAT)    \
+       {                                                               \
+         if (code == CONST_INT && INTVAL (INDEX) < 1024                \
+             && INTVAL (INDEX) > -1024                                 \
+             && (INTVAL (INDEX) & 3) == 0)                             \
+           goto LABEL;                                                 \
+       }                                                               \
+      else                                                             \
+       {                                                               \
+         if (ARM_INDEX_REGISTER_RTX_P (INDEX)                          \
+             && GET_MODE_SIZE (MODE) <= 4)                             \
+           goto LABEL;                                                 \
+         if (GET_MODE_SIZE (MODE) <= 4  && code == MULT                \
+             && (! arm_arch4 || (MODE) != HImode))                     \
+           {                                                           \
+             rtx xiop0 = XEXP (INDEX, 0);                              \
+             rtx xiop1 = XEXP (INDEX, 1);                              \
+             if (ARM_INDEX_REGISTER_RTX_P (xiop0)                      \
+                 && power_of_two_operand (xiop1, SImode))              \
+               goto LABEL;                                             \
+             if (ARM_INDEX_REGISTER_RTX_P (xiop1)                      \
+                 && power_of_two_operand (xiop0, SImode))              \
+               goto LABEL;                                             \
+           }                                                           \
+         if (GET_MODE_SIZE (MODE) <= 4                                 \
+             && (code == LSHIFTRT || code == ASHIFTRT                  \
+                 || code == ASHIFT || code == ROTATERT)                \
+             && (! arm_arch4 || (MODE) != HImode))                     \
+           {                                                           \
+             rtx op = XEXP (INDEX, 1);                                 \
+             if (ARM_INDEX_REGISTER_RTX_P (XEXP (INDEX, 0))            \
+                 && GET_CODE (op) == CONST_INT && INTVAL (op) > 0      \
+                 && INTVAL (op) <= 31)                                 \
+               goto LABEL;                                             \
+           }                                                           \
+         /* NASTY: Since this limits the addressing of unsigned        \
+            byte loads.  */                                            \
+         range = ((MODE) == HImode || (MODE) == QImode)                \
+           ? (arm_arch4 ? 256 : 4095) : 4096;                          \
+         if (code == CONST_INT && INTVAL (INDEX) < range               \
+             && INTVAL (INDEX) > -range)                               \
+           goto LABEL;                                                 \
+       }                                                               \
+    }                                                                  \
   while (0)
 
-/* Jump to LABEL if X is a valid address RTX.  This must also take
-   REG_OK_STRICT into account when deciding about valid registers, but it uses
-   the above macros so we are in luck.  Allow REG, REG+REG, REG+INDEX,
-   INDEX+REG, REG-INDEX, and non floating SYMBOL_REF to the constant pool.
-   Allow REG-only and AUTINC-REG if handling TImode or HImode.  Other symbol
-   refs must be forced though a static cell to ensure addressability.  */
-#define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL)                   \
+/* Jump to LABEL if X is a valid address RTX.  This must take
+   REG_OK_STRICT into account when deciding about valid registers.
+
+   Allow REG, REG+REG, REG+INDEX, INDEX+REG, REG-INDEX, and non
+   floating SYMBOL_REF to the constant pool.  Allow REG-only and
+   AUTINC-REG if handling TImode or HImode.  Other symbol refs must be
+   forced though a static cell to ensure addressability.  */
+#define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL)                   \
 {                                                                      \
-  if (BASE_REGISTER_RTX_P (X))                                         \
+  if (ARM_BASE_REGISTER_RTX_P (X))                                     \
     goto LABEL;                                                                \
   else if ((GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC)       \
           && GET_CODE (XEXP (X, 0)) == REG                             \
-          && REG_OK_FOR_PRE_POST_P (XEXP (X, 0)))                      \
+          && ARM_REG_OK_FOR_BASE_P (XEXP (X, 0)))                      \
     goto LABEL;                                                                \
   else if (GET_MODE_SIZE (MODE) >= 4 && reload_completed               \
           && (GET_CODE (X) == LABEL_REF                                \
@@ -2056,11 +2083,11 @@ typedef struct
   else if ((MODE) == TImode)                                           \
     ;                                                                  \
   else if ((MODE) == DImode || (TARGET_SOFT_FLOAT && (MODE) == DFmode))        \
-    {                                                                  \
-      if (GET_CODE (X) == PLUS && BASE_REGISTER_RTX_P (XEXP (X, 0))    \
-         && GET_CODE (XEXP (X, 1)) == CONST_INT)                       \
-       {                                                               \
-         HOST_WIDE_INT val = INTVAL (XEXP (X, 1));                     \
+    {                                                                  \
+      if (GET_CODE (X) == PLUS && ARM_BASE_REGISTER_RTX_P (XEXP (X, 0))        \
+         && GET_CODE (XEXP (X, 1)) == CONST_INT)                       \
+       {                                                               \
+         HOST_WIDE_INT val = INTVAL (XEXP (X, 1));                     \
           if (val == 4 || val == -4 || val == -8)                      \
            goto LABEL;                                                 \
        }                                                               \
@@ -2070,10 +2097,10 @@ typedef struct
       rtx xop0 = XEXP (X, 0);                                          \
       rtx xop1 = XEXP (X, 1);                                          \
                                                                        \
-      if (BASE_REGISTER_RTX_P (xop0))                                  \
-       GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop0), xop1, LABEL);       \
-      else if (BASE_REGISTER_RTX_P (xop1))                             \
-       GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop1), xop0, LABEL);       \
+      if (ARM_BASE_REGISTER_RTX_P (xop0))                              \
+       ARM_GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop0), xop1, LABEL);   \
+      else if (ARM_BASE_REGISTER_RTX_P (xop1))                         \
+       ARM_GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop1), xop0, LABEL);   \
     }                                                                  \
   /* Reload currently can't handle MINUS, so disable this for now */   \
   /* else if (GET_CODE (X) == MINUS)                                   \
@@ -2081,8 +2108,8 @@ typedef struct
       rtx xop0 = XEXP (X,0);                                           \
       rtx xop1 = XEXP (X,1);                                           \
                                                                        \
-      if (BASE_REGISTER_RTX_P (xop0))                                  \
-       GO_IF_LEGITIMATE_INDEX (MODE, -1, xop1, LABEL);                 \
+      if (ARM_BASE_REGISTER_RTX_P (xop0))                              \
+       ARM_GO_IF_LEGITIMATE_INDEX (MODE, -1, xop1, LABEL);             \
     } */                                                               \
   else if (GET_MODE_CLASS (MODE) != MODE_FLOAT                         \
           && GET_CODE (X) == SYMBOL_REF                                \
@@ -2093,12 +2120,12 @@ typedef struct
   else if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_DEC)       \
           && (GET_MODE_SIZE (MODE) <= 4)                               \
           && GET_CODE (XEXP (X, 0)) == REG                             \
-          && REG_OK_FOR_PRE_POST_P (XEXP (X, 0)))                      \
+          && ARM_REG_OK_FOR_BASE_P (XEXP (X, 0)))                      \
     goto LABEL;                                                                \
 }
      
 /* ---------------------thumb version----------------------------------*/     
-#define LEGITIMATE_OFFSET(MODE, VAL)                                   \
+#define THUMB_LEGITIMATE_OFFSET(MODE, VAL)                             \
   (GET_MODE_SIZE (MODE) == 1 ? ((unsigned HOST_WIDE_INT) (VAL) < 32)   \
    : GET_MODE_SIZE (MODE) == 2 ? ((unsigned HOST_WIDE_INT) (VAL) < 64  \
                                  && ((VAL) & 1) == 0)                  \
@@ -2117,9 +2144,9 @@ typedef struct
    better ways to solve some of these problems.  */
 
 /* Although it is not incorrect, we don't accept QImode and HImode
-   addresses based on the frame pointer or arg pointer until the reload pass starts.
-   This is so that eliminating such addresses into stack based ones
-   won't produce impossible code.  */
+   addresses based on the frame pointer or arg pointer until the
+   reload pass starts.  This is so that eliminating such addresses
+   into stack based ones won't produce impossible code.  */
 #define THUMB_GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN)                   \
 {                                                                      \
 /* ??? Not clear if this is right.  Experiment.  */                    \
@@ -2133,7 +2160,8 @@ typedef struct
          || reg_mentioned_p (virtual_stack_vars_rtx, X)))              \
     ;                                                                  \
   /* Accept any base register.  SP only in SImode or larger.  */       \
-  else if (GET_CODE (X) == REG && REG_MODE_OK_FOR_BASE_P (X, MODE))    \
+  else if (GET_CODE (X) == REG                                         \
+          && THUMB_REG_MODE_OK_FOR_BASE_P (X, MODE))                   \
     goto WIN;                                                          \
   /* This is PC relative data before MACHINE_DEPENDENT_REORG runs.  */ \
   else if (GET_MODE_SIZE (MODE) >= 4 && CONSTANT_P (X)                 \
@@ -2150,7 +2178,7 @@ typedef struct
   /* Post-inc indexing only supported for SImode and larger.  */       \
   else if (GET_CODE (X) == POST_INC && GET_MODE_SIZE (MODE) >= 4       \
           && GET_CODE (XEXP (X, 0)) == REG                             \
-          && REG_OK_FOR_INDEX_P (XEXP (X, 0)))                         \
+          && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0)))                   \
     goto WIN;                                                          \
   else if (GET_CODE (X) == PLUS)                                       \
     {                                                                  \
@@ -2165,15 +2193,15 @@ typedef struct
          && XEXP (X, 1) != frame_pointer_rtx                           \
          && XEXP (X, 0) != virtual_stack_vars_rtx                      \
          && XEXP (X, 1) != virtual_stack_vars_rtx                      \
-         && REG_OK_FOR_INDEX_P (XEXP (X, 0))                           \
-         && REG_OK_FOR_INDEX_P (XEXP (X, 1)))                          \
+         && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0))                     \
+         && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 1)))                    \
        goto WIN;                                                       \
       /* REG+const has 5-7 bit offset for non-SP registers.  */                \
       else if (GET_CODE (XEXP (X, 0)) == REG                           \
-              && (REG_OK_FOR_INDEX_P (XEXP (X, 0))                     \
+              && (THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0))               \
                   || XEXP (X, 0) == arg_pointer_rtx)                   \
               && GET_CODE (XEXP (X, 1)) == CONST_INT                   \
-              && LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1))))       \
+              && THUMB_LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \
        goto WIN;                                                       \
       /* REG+const has 10 bit offset for SP, but only SImode and       \
         larger is supported.  */                                       \
@@ -2237,7 +2265,8 @@ typedef struct
        xop0 = force_reg (SImode, xop0);                                 \
       if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1))             \
        xop1 = force_reg (SImode, xop1);                                 \
-      if (BASE_REGISTER_RTX_P (xop0) && GET_CODE (xop1) == CONST_INT)   \
+      if (ARM_BASE_REGISTER_RTX_P (xop0)                                \
+         && GET_CODE (xop1) == CONST_INT)                               \
        {                                                                \
          HOST_WIDE_INT n, low_n;                                        \
          rtx base_reg, val;                                             \
@@ -2322,12 +2351,6 @@ typedef struct
    Do not define this if the table should contain absolute addresses. */
 /* #define CASE_VECTOR_PC_RELATIVE 1 */
 
-/* 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
-
 /* signed 'char' is most compatible, but RISC OS wants it unsigned.
    unsigned is probably best, but may break some code.  */
 #ifndef DEFAULT_SIGNED_CHAR
@@ -2341,6 +2364,9 @@ typedef struct
    in one reasonably fast instruction.  */
 #define MOVE_MAX 4
 
+#undef  MOVE_RATIO
+#define MOVE_RATIO (arm_is_xscale ? 4 : 2)
+
 /* Define if operations between registers always perform the operation
    on the full register even if a narrower mode is specified.  */
 #define WORD_REGISTER_OPERATIONS
@@ -2354,11 +2380,6 @@ typedef struct
    ((arm_arch4 || (MODE) == QImode) ? ZERO_EXTEND                      \
     : ((BYTES_BIG_ENDIAN && (MODE) == HImode) ? SIGN_EXTEND : NIL)))
 
-/* Define this if zero-extension is slow (more than one real instruction).
-   On the ARM, it is more than one instruction only if not fetching from
-   memory.  */
-/* #define SLOW_ZERO_EXTEND */
-
 /* Nonzero if access to memory by bytes is slow and undesirable.  */
 #define SLOW_BYTE_ACCESS 0
 
@@ -2434,11 +2455,6 @@ typedef struct
    conditional instructions */
 #define BRANCH_COST \
   (TARGET_ARM ? 4 : (optimize > 1 ? 1 : 0))
-
-/* A C statement to update the variable COST based on the relationship
-   between INSN that is dependent on DEP through dependence LINK.  */
-#define ADJUST_COST(INSN, LINK, DEP, COST) \
-  (COST) = arm_adjust_cost (INSN, LINK, DEP, COST)
 \f
 /* Position Independent Code.  */
 /* We decide which register to use based on the compilation options and
@@ -2453,7 +2469,7 @@ extern const char * arm_pic_register_string;
    data addresses in memory.  */
 #define PIC_OFFSET_TABLE_REGNUM arm_pic_register
 
-#define FINALIZE_PIC arm_finalize_pic ()
+#define FINALIZE_PIC arm_finalize_pic (1)
 
 /* We can't directly access anything that contains a symbol,
    nor can we indirect via the constant pool.  */
@@ -2469,24 +2485,6 @@ extern const char * arm_pic_register_string;
    offset.  */
 extern int making_const_table;
 \f
-/* If defined, a C expression whose value is nonzero if IDENTIFIER
-   with arguments ARGS is a valid machine specific attribute for TYPE.
-   The attributes in ATTRIBUTES have previously been assigned to TYPE.  */
-#define VALID_MACHINE_TYPE_ATTRIBUTE(TYPE, ATTRIBUTES, NAME, ARGS) \
-  (arm_valid_type_attribute_p (TYPE, ATTRIBUTES, NAME, ARGS))
-
-/* If defined, a C expression whose value is zero if the attributes on
-   TYPE1 and TYPE2 are incompatible, one if they are compatible, and
-   two if they are nearly compatible (which causes a warning to be
-   generated).  */
-#define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \
-  (arm_comp_type_attributes (TYPE1, TYPE2))
-
-/* If defined, a C statement that assigns default attributes to newly
-   defined TYPE.  */
-#define SET_DEFAULT_TYPE_ATTRIBUTES(TYPE) \
-  arm_set_default_type_attributes (TYPE)
-
 /* Handle pragmas for compatibility with Intel's compilers.  */
 #define REGISTER_TARGET_PRAGMAS(PFILE) do { \
   cpp_register_pragma (PFILE, 0, "long_calls", arm_pr_long_calls); \
@@ -2590,6 +2588,7 @@ extern int making_const_table;
 
 /* This is how to output a label which precedes a jumptable.  Since
    Thumb instructions are 2 bytes, we may need explicit alignment here.  */
+#undef  ASM_OUTPUT_CASE_LABEL
 #define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, JUMPTABLE)    \
   do                                                           \
     {                                                          \
@@ -2618,8 +2617,8 @@ extern int making_const_table;
 #define ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL1, DECL2)          \
   do                                                           \
     {                                                          \
-      char * LABEL1 = XSTR (XEXP (DECL_RTL (decl), 0), 0);     \
-      char * LABEL2 = IDENTIFIER_POINTER (DECL2);              \
+      const char *const LABEL1 = XSTR (XEXP (DECL_RTL (decl), 0), 0); \
+      const char *const LABEL2 = IDENTIFIER_POINTER (DECL2);   \
                                                                \
       if (TARGET_THUMB && TREE_CODE (DECL1) == FUNCTION_DECL)  \
        {                                                       \
@@ -2634,14 +2633,20 @@ extern int making_const_table;
     }                                                          \
   while (0)
 
-/* Target characters.  */
-#define TARGET_BELL    007
-#define TARGET_BS      010
-#define TARGET_TAB     011
-#define TARGET_NEWLINE 012
-#define TARGET_VT      013
-#define TARGET_FF      014
-#define TARGET_CR      015
+#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
+/* To support -falign-* switches we need to use .p2align so
+   that alignment directives in code sections will be padded
+   with no-op instructions, rather than zeroes.  */
+#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP)           \
+  if ((LOG) != 0)                                              \
+    {                                                          \
+      if ((MAX_SKIP) == 0)                                     \
+        fprintf ((FILE), "\t.p2align %d\n", (LOG));            \
+      else                                                     \
+        fprintf ((FILE), "\t.p2align %d,,%d\n",                        \
+                 (LOG), (MAX_SKIP));                           \
+    }
+#endif
 \f
 /* Only perform branch elimination (by making instructions conditional) if
    we're optimising.  Otherwise it's of no use anyway.  */
@@ -2660,22 +2665,12 @@ extern int making_const_table;
 #define PRINT_OPERAND(STREAM, X, CODE)  \
   arm_print_operand (STREAM, X, CODE)
 
-/* Create an [unsigned] host sized integer declaration that
-   avoids compiler warnings.  */
-#ifdef __STDC__
-#define HOST_INT(x)  ((signed HOST_WIDE_INT) x##UL)
-#define HOST_UINT(x) ((unsigned HOST_WIDE_INT) x##UL)
-#else
-#define HOST_INT(x)  ((HOST_WIDE_INT) x)
-#define HOST_UINT(x) ((unsigned HOST_WIDE_INT) x)
-#endif
-
-#define ARM_SIGN_EXTEND(x)  ((HOST_WIDE_INT)   \
-  (HOST_BITS_PER_WIDE_INT <= 32 ? (x)          \
-   : (((x) & HOST_UINT (0xffffffff)) |         \
-      (((x) & HOST_UINT (0x80000000))          \
-       ? ((~ HOST_INT (0))                     \
-         & ~ HOST_UINT(0xffffffff))            \
+#define ARM_SIGN_EXTEND(x)  ((HOST_WIDE_INT)                   \
+  (HOST_BITS_PER_WIDE_INT <= 32 ? (unsigned HOST_WIDE_INT) (x) \
+   : ((((unsigned HOST_WIDE_INT)(x)) & (unsigned HOST_WIDE_INT) 0xffffffff) |\
+      ((((unsigned HOST_WIDE_INT)(x)) & (unsigned HOST_WIDE_INT) 0x80000000) \
+       ? ((~ (unsigned HOST_WIDE_INT) 0)                       \
+         & ~ (unsigned HOST_WIDE_INT) 0xffffffff)              \
        : 0))))
 
 /* Output the address of an operand.  */
@@ -2781,40 +2776,13 @@ extern int making_const_table;
   else                                         \
     THUMB_PRINT_OPERAND_ADDRESS (STREAM, X)
      
-/* Handles PIC addr specially */
-#define OUTPUT_INT_ADDR_CONST(STREAM, X)                               \
-  {                                                                    \
-    if (flag_pic && GET_CODE (X) == CONST && is_pic (X))               \
-      {                                                                        \
-       output_addr_const (STREAM, XEXP (XEXP (XEXP (X, 0), 0), 0));    \
-       fputs (" - (", STREAM);                                         \
-       output_addr_const (STREAM, XEXP (XEXP (XEXP (X, 0), 1), 0));    \
-       fputs (")", STREAM);                                            \
-      }                                                                        \
-    else                                                               \
-      output_addr_const (STREAM, X);                                   \
-                                                                       \
-    /* Mark symbols as position independent.  We only do this in the   \
-      .text segment, not in the .data segment. */                      \
-    if (NEED_GOT_RELOC && flag_pic && making_const_table &&            \
-       (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == LABEL_REF))      \
-     {                                                                 \
-        if (GET_CODE (X) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (X)) \
-          fprintf (STREAM, "(GOTOFF)");                                        \
-        else if (GET_CODE (X) == LABEL_REF)                            \
-          fprintf (STREAM, "(GOTOFF)");                                        \
-        else                                                           \
-          fprintf (STREAM, "(GOT)");                                   \
-     }                                                                 \
-  }
-
 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
    Used for C++ multiple inheritance.  */
 #define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION)               \
   do                                                                           \
     {                                                                          \
       int mi_delta = (DELTA);                                                  \
-      const char * mi_op = mi_delta < 0 ? "sub" : "add";                       \
+      const char *const mi_op = mi_delta < 0 ? "sub" : "add";                  \
       int shift = 0;                                                           \
       int this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (FUNCTION)))   \
                        ? 1 : 0);                                               \
@@ -2871,6 +2839,7 @@ extern int making_const_table;
 /* Define the codes that are matched by predicates in arm.c */
 #define PREDICATE_CODES                                                        \
   {"s_register_operand", {SUBREG, REG}},                               \
+  {"arm_hard_register_operand", {REG}},                                        \
   {"f_register_operand", {SUBREG, REG}},                               \
   {"arm_add_operand",    {SUBREG, REG, CONST_INT}},                    \
   {"fpu_add_operand",    {SUBREG, REG, CONST_DOUBLE}},                 \
@@ -2910,4 +2879,9 @@ extern int making_const_table;
 #define SPECIAL_MODE_PREDICATES                        \
  "cc_register", "dominant_cc_register",
 
-#endif /* __ARM_H__ */
+enum arm_builtins
+{
+  ARM_BUILTIN_CLZ,
+  ARM_BUILTIN_MAX
+};
+#endif /* ! GCC_ARM_H */