OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / config / arm / arm.h
index 6cc612b..c3dc3b9 100644 (file)
@@ -1,6 +1,7 @@
 /* Definitions of target machine for GNU compiler, for ARM.
    Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   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)
@@ -10,7 +11,7 @@
 
    GCC is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published
-   by the Free Software Foundation; either version 2, or (at your
+   by the Free Software Foundation; either version 3, or (at your
    option) any later version.
 
    GCC is distributed in the hope that it will be useful, but WITHOUT
    License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with GCC; see the file COPYING.  If not, write to
-   the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
-   MA 02110-1301, USA.  */
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
 
 #ifndef GCC_ARM_H
 #define GCC_ARM_H
 
+/* We can't use enum machine_mode inside a generator file because it
+   hasn't been created yet; we shouldn't be using any code that
+   needs the real definition though, so this ought to be safe.  */
+#ifdef GENERATOR_FILE
+#define MACHMODE int
+#else
+#include "insn-modes.h"
+#define MACHMODE enum machine_mode
+#endif
+
+#include "config/vxworks-dummy.h"
+
 /* The architecture define.  */
 extern char arm_arch_name[];
 
@@ -39,6 +51,8 @@ extern char arm_arch_name[];
        builtin_define ("__APCS_32__");                 \
        if (TARGET_THUMB)                               \
          builtin_define ("__thumb__");                 \
+       if (TARGET_THUMB2)                              \
+         builtin_define ("__thumb2__");                \
                                                        \
        if (TARGET_BIG_END)                             \
          {                                             \
@@ -61,6 +75,9 @@ extern char arm_arch_name[];
        if (TARGET_VFP)                                 \
          builtin_define ("__VFP_FP__");                \
                                                        \
+       if (TARGET_NEON)                                \
+         builtin_define ("__ARM_NEON__");              \
+                                                       \
        /* Add a define for interworking.               \
           Needed when building libgcc.a.  */           \
        if (arm_cpp_interwork)                          \
@@ -77,7 +94,13 @@ extern char arm_arch_name[];
        if (arm_arch_iwmmxt)                            \
          builtin_define ("__IWMMXT__");                \
        if (TARGET_AAPCS_BASED)                         \
-         builtin_define ("__ARM_EABI__");              \
+         {                                             \
+           if (arm_pcs_default == ARM_PCS_AAPCS_VFP)   \
+             builtin_define ("__ARM_PCS_VFP");         \
+           else if (arm_pcs_default == ARM_PCS_AAPCS)  \
+             builtin_define ("__ARM_PCS");             \
+           builtin_define ("__ARM_EABI__");            \
+         }                                             \
     } while (0)
 
 /* The various ARM cores.  */
@@ -103,6 +126,24 @@ enum target_cpus
 /* The processor for which instructions should be scheduled.  */
 extern enum processor_type arm_tune;
 
+enum arm_sync_generator_tag
+  {
+    arm_sync_generator_omn,
+    arm_sync_generator_omrn
+  };
+
+/* Wrapper to pass around a polymorphic pointer to a sync instruction
+   generator and.  */
+struct arm_sync_generator
+{
+  enum arm_sync_generator_tag op;
+  union
+  {
+    rtx (* omn) (rtx, rtx, rtx);
+    rtx (* omrn) (rtx, rtx, rtx, rtx);
+  } u;
+};
+
 typedef enum arm_cond_code
 {
   ARM_EQ = 0, ARM_NE, ARM_CS, ARM_CC, ARM_MI, ARM_PL, ARM_VS, ARM_VC,
@@ -117,17 +158,13 @@ extern arm_cc arm_current_cc;
 extern int arm_target_label;
 extern int arm_ccfsm_state;
 extern GTY(()) rtx arm_target_insn;
-/* Define the information needed to generate branch insns.  This is
-   stored from the compare operation.  */
-extern GTY(()) rtx arm_compare_op0;
-extern GTY(()) rtx arm_compare_op1;
 /* The label of the current constant pool.  */
 extern rtx 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;
-/* Used to produce AOF syntax assembler.  */
-extern GTY(()) rtx aof_pic_label;
+/* Callback to output language specific object attributes.  */
+extern void (*arm_lang_output_object_attributes_hook)(void);
 \f
 /* Just in case configure has failed to define anything.  */
 #ifndef TARGET_CPU_DEFAULT
@@ -177,12 +214,12 @@ extern GTY(()) rtx aof_pic_label;
 #define TARGET_HARD_FLOAT              (arm_float_abi != ARM_FLOAT_ABI_SOFT)
 /* Use hardware floating point calling convention.  */
 #define TARGET_HARD_FLOAT_ABI          (arm_float_abi == ARM_FLOAT_ABI_HARD)
-#define TARGET_FPA                     (arm_fp_model == ARM_FP_MODEL_FPA)
-#define TARGET_MAVERICK                        (arm_fp_model == ARM_FP_MODEL_MAVERICK)
-#define TARGET_VFP                     (arm_fp_model == ARM_FP_MODEL_VFP)
+#define TARGET_FPA             (arm_fpu_desc->model == ARM_FP_MODEL_FPA)
+#define TARGET_MAVERICK                (arm_fpu_desc->model == ARM_FP_MODEL_MAVERICK)
+#define TARGET_VFP             (arm_fpu_desc->model == ARM_FP_MODEL_VFP)
 #define TARGET_IWMMXT                  (arm_arch_iwmmxt)
-#define TARGET_REALLY_IWMMXT           (TARGET_IWMMXT && TARGET_ARM)
-#define TARGET_IWMMXT_ABI (TARGET_ARM && arm_abi == ARM_ABI_IWMMXT)
+#define TARGET_REALLY_IWMMXT           (TARGET_IWMMXT && TARGET_32BIT)
+#define TARGET_IWMMXT_ABI (TARGET_32BIT && arm_abi == ARM_ABI_IWMMXT)
 #define TARGET_ARM                      (! TARGET_THUMB)
 #define TARGET_EITHER                  1 /* (TARGET_ARM | TARGET_THUMB) */
 #define TARGET_BACKTRACE               (leaf_function_p () \
@@ -195,6 +232,77 @@ extern GTY(()) rtx aof_pic_label;
 #define TARGET_HARD_TP                 (target_thread_pointer == TP_CP15)
 #define TARGET_SOFT_TP                 (target_thread_pointer == TP_SOFT)
 
+/* Only 16-bit thumb code.  */
+#define TARGET_THUMB1                  (TARGET_THUMB && !arm_arch_thumb2)
+/* Arm or Thumb-2 32-bit code.  */
+#define TARGET_32BIT                   (TARGET_ARM || arm_arch_thumb2)
+/* 32-bit Thumb-2 code.  */
+#define TARGET_THUMB2                  (TARGET_THUMB && arm_arch_thumb2)
+/* Thumb-1 only.  */
+#define TARGET_THUMB1_ONLY             (TARGET_THUMB1 && !arm_arch_notm)
+/* FPA emulator without LFM.  */
+#define TARGET_FPA_EMU2                        (TARGET_FPA && arm_fpu_desc->rev == 2)
+
+/* The following two macros concern the ability to execute coprocessor
+   instructions for VFPv3 or NEON.  TARGET_VFP3/TARGET_VFPD32 are currently
+   only ever tested when we know we are generating for VFP hardware; we need
+   to be more careful with TARGET_NEON as noted below.  */
+
+/* FPU is has the full VFPv3/NEON register file of 32 D registers.  */
+#define TARGET_VFPD32 (TARGET_VFP && arm_fpu_desc->regs == VFP_REG_D32)
+
+/* FPU supports VFPv3 instructions.  */
+#define TARGET_VFP3 (TARGET_VFP && arm_fpu_desc->rev >= 3)
+
+/* FPU only supports VFP single-precision instructions.  */
+#define TARGET_VFP_SINGLE (TARGET_VFP && arm_fpu_desc->regs == VFP_REG_SINGLE)
+
+/* FPU supports VFP double-precision instructions.  */
+#define TARGET_VFP_DOUBLE (TARGET_VFP && arm_fpu_desc->regs != VFP_REG_SINGLE)
+
+/* FPU supports half-precision floating-point with NEON element load/store.  */
+#define TARGET_NEON_FP16 \
+  (TARGET_VFP && arm_fpu_desc->neon && arm_fpu_desc->fp16)
+
+/* FPU supports VFP half-precision floating-point.  */
+#define TARGET_FP16 (TARGET_VFP && arm_fpu_desc->fp16)
+
+/* FPU supports Neon instructions.  The setting of this macro gets
+   revealed via __ARM_NEON__ so we add extra guards upon TARGET_32BIT
+   and TARGET_HARD_FLOAT to ensure that NEON instructions are
+   available.  */
+#define TARGET_NEON (TARGET_32BIT && TARGET_HARD_FLOAT \
+                    && TARGET_VFP && arm_fpu_desc->neon)
+
+/* "DSP" multiply instructions, eg. SMULxy.  */
+#define TARGET_DSP_MULTIPLY \
+  (TARGET_32BIT && arm_arch5e && (arm_arch_notm || arm_arch7em))
+/* Integer SIMD instructions, and extend-accumulate instructions.  */
+#define TARGET_INT_SIMD \
+  (TARGET_32BIT && arm_arch6 && (arm_arch_notm || arm_arch7em))
+
+/* Should MOVW/MOVT be used in preference to a constant pool.  */
+#define TARGET_USE_MOVT (arm_arch_thumb2 && !optimize_size)
+
+/* We could use unified syntax for arm mode, but for now we just use it
+   for Thumb-2.  */
+#define TARGET_UNIFIED_ASM TARGET_THUMB2
+
+/* Nonzero if this chip provides the DMB instruction.  */
+#define TARGET_HAVE_DMB                (arm_arch7)
+
+/* Nonzero if this chip implements a memory barrier via CP15.  */
+#define TARGET_HAVE_DMB_MCR    (arm_arch6k && ! TARGET_HAVE_DMB)
+
+/* Nonzero if this chip implements a memory barrier instruction.  */
+#define TARGET_HAVE_MEMORY_BARRIER (TARGET_HAVE_DMB || TARGET_HAVE_DMB_MCR)
+
+/* Nonzero if this chip supports ldrex and strex */
+#define TARGET_HAVE_LDREX      ((arm_arch6 && TARGET_ARM) || arm_arch7)
+
+/* Nonzero if this chip supports ldrex{bhd} and strex{bhd}.  */
+#define TARGET_HAVE_LDREXBHD   ((arm_arch6k && TARGET_ARM) || arm_arch7)
+
 /* True iff the full BPABI is being used.  If TARGET_BPABI is true,
    then TARGET_AAPCS_BASED must be true -- but the converse does not
    hold.  TARGET_BPABI implies the use of the BPABI runtime library,
@@ -235,34 +343,26 @@ enum arm_fp_model
   ARM_FP_MODEL_VFP
 };
 
-extern enum arm_fp_model arm_fp_model;
-
-/* Which floating point hardware is available.  Also update
-   fp_model_for_fpu in arm.c when adding entries to this list.  */
-enum fputype
+enum vfp_reg_type
 {
-  /* No FP hardware.  */
-  FPUTYPE_NONE,
-  /* Full FPA support.  */
-  FPUTYPE_FPA,
-  /* Emulated FPA hardware, Issue 2 emulator (no LFM/SFM).  */
-  FPUTYPE_FPA_EMU2,
-  /* Emulated FPA hardware, Issue 3 emulator.  */
-  FPUTYPE_FPA_EMU3,
-  /* Cirrus Maverick floating point co-processor.  */
-  FPUTYPE_MAVERICK,
-  /* VFP.  */
-  FPUTYPE_VFP
+  VFP_NONE = 0,
+  VFP_REG_D16,
+  VFP_REG_D32,
+  VFP_REG_SINGLE
 };
 
-/* Recast the floating point class to be the floating point attribute.  */
-#define arm_fpu_attr ((enum attr_fpu) arm_fpu_tune)
-
-/* What type of floating point to tune for */
-extern enum fputype arm_fpu_tune;
+extern const struct arm_fpu_desc
+{
+  const char *name;
+  enum arm_fp_model model;
+  int rev;
+  enum vfp_reg_type regs;
+  int neon;
+  int fp16;
+} *arm_fpu_desc;
 
-/* What type of floating point instructions are available */
-extern enum fputype arm_fpu_arch;
+/* Which floating point hardware to schedule for.  */
+extern int arm_fpu_attr;
 
 enum float_abi_type
 {
@@ -277,6 +377,21 @@ extern enum float_abi_type arm_float_abi;
 #define TARGET_DEFAULT_FLOAT_ABI ARM_FLOAT_ABI_SOFT
 #endif
 
+/* Which __fp16 format to use.
+   The enumeration values correspond to the numbering for the
+   Tag_ABI_FP_16bit_format attribute.
+ */
+enum arm_fp16_format_type
+{
+  ARM_FP16_FORMAT_NONE = 0,
+  ARM_FP16_FORMAT_IEEE = 1,
+  ARM_FP16_FORMAT_ALTERNATIVE = 2
+};
+
+extern enum arm_fp16_format_type arm_fp16_format;
+#define LARGEST_EXPONENT_IS_NORMAL(bits) \
+    ((bits) == 16 && arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE)
+
 /* Which ABI to use.  */
 enum arm_abi_type
 {
@@ -320,12 +435,27 @@ extern int arm_arch5e;
 /* Nonzero if this chip supports the ARM Architecture 6 extensions.  */
 extern int arm_arch6;
 
+/* Nonzero if this chip supports the ARM Architecture 6k extensions.  */
+extern int arm_arch6k;
+
+/* Nonzero if this chip supports the ARM Architecture 7 extensions.  */
+extern int arm_arch7;
+
+/* Nonzero if instructions not present in the 'M' profile can be used.  */
+extern int arm_arch_notm;
+
+/* Nonzero if instructions present in ARMv7E-M can be used.  */
+extern int arm_arch7em;
+
 /* Nonzero if this chip can benefit from load scheduling.  */
 extern int arm_ld_sched;
 
-/* Nonzero if generating thumb code.  */
+/* Nonzero if generating Thumb code, either Thumb-1 or Thumb-2.  */
 extern int thumb_code;
 
+/* Nonzero if generating Thumb-1 code.  */
+extern int thumb1_code;
+
 /* Nonzero if this chip is a StrongARM.  */
 extern int arm_tune_strongarm;
 
@@ -344,6 +474,9 @@ extern int arm_tune_xscale;
 /* Nonzero if tuning for stores via the write buffer.  */
 extern int arm_tune_wbuf;
 
+/* Nonzero if tuning for Cortex-A9.  */
+extern int arm_tune_cortex_a9;
+
 /* Nonzero if we should define __THUMB_INTERWORK__ in the
    preprocessor.
    XXX This is a bit of a hack, it's intended to help work around
@@ -351,16 +484,16 @@ extern int arm_tune_wbuf;
    interworking clean.  */
 extern int arm_cpp_interwork;
 
+/* Nonzero if chip supports Thumb 2.  */
+extern int arm_arch_thumb2;
+
+/* Nonzero if chip supports integer division instruction.  */
+extern int arm_arch_hwdiv;
+
 #ifndef TARGET_DEFAULT
 #define TARGET_DEFAULT  (MASK_APCS_FRAME)
 #endif
 
-/* The frame pointer register used in gcc has nothing to do with debugging;
-   that is controlled by the APCS-FRAME option.  */
-#define CAN_DEBUG_WITHOUT_FP
-
-#define OVERRIDE_OPTIONS  arm_override_options ()
-
 /* Nonzero if PIC code requires explicit qualifiers to generate
    PLT and GOT relocs rather than the assembler doing so implicitly.
    Subtargets can override these if required.  */
@@ -408,12 +541,6 @@ extern int arm_cpp_interwork;
       (MODE) = SImode;                         \
     }
 
-#define PROMOTE_FUNCTION_MODE(MODE, UNSIGNEDP, TYPE)   \
-  if ((GET_MODE_CLASS (MODE) == MODE_INT               \
-       || GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT)    \
-      && GET_MODE_SIZE (MODE) < 4)                      \
-    (MODE) = SImode;                                   \
-
 /* Define this if most significant bit is lowest numbered
    in instructions that operate on numbered bit-fields.  */
 #define BITS_BIG_ENDIAN  0
@@ -429,14 +556,6 @@ extern int arm_cpp_interwork;
    This is always false, even when in big-endian mode.  */
 #define WORDS_BIG_ENDIAN  (BYTES_BIG_ENDIAN && ! TARGET_LITTLE_WORDS)
 
-/* LIBGCC2_WORDS_BIG_ENDIAN has to be a constant, so we define this based
-   on processor pre-defineds when compiling libgcc2.c.  */
-#if defined(__ARMEB__) && !defined(__ARMWEL__)
-#define LIBGCC2_WORDS_BIG_ENDIAN 1
-#else
-#define LIBGCC2_WORDS_BIG_ENDIAN 0
-#endif
-
 /* Define this if most significant word of doubles is the lowest numbered.
    The rules are different based on whether or not we use FPA-format,
    VFP-format or some other floating point co-processor's format doubles.  */
@@ -456,7 +575,7 @@ extern int arm_cpp_interwork;
 #define PREFERRED_STACK_BOUNDARY \
     (arm_abi == ARM_ABI_ATPCS ? 64 : STACK_BOUNDARY)
 
-#define FUNCTION_BOUNDARY  32
+#define FUNCTION_BOUNDARY  ((TARGET_THUMB && optimize_size) ? 16 : 32)
 
 /* The lowest bit is used to indicate Thumb-mode functions, so the
    vbit must go into the delta field of pointers to member
@@ -479,9 +598,29 @@ extern int arm_cpp_interwork;
 
 #define CONSTANT_ALIGNMENT(EXP, ALIGN)                         \
    ((TREE_CODE (EXP) == STRING_CST                             \
+     && !optimize_size                                         \
      && (ALIGN) < BITS_PER_WORD * CONSTANT_ALIGNMENT_FACTOR)   \
     ? BITS_PER_WORD * CONSTANT_ALIGNMENT_FACTOR : (ALIGN))
 
+/* Align definitions of arrays, unions and structures so that
+   initializations and copies can be made more efficient.  This is not
+   ABI-changing, so it only affects places where we can see the
+   definition. Increasing the alignment tends to introduce padding,
+   so don't do this when optimizing for size/conserving stack space. */
+#define ARM_EXPAND_ALIGNMENT(COND, EXP, ALIGN)                         \
+  (((COND) && ((ALIGN) < BITS_PER_WORD)                                        \
+    && (TREE_CODE (EXP) == ARRAY_TYPE                                  \
+       || TREE_CODE (EXP) == UNION_TYPE                                \
+       || TREE_CODE (EXP) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
+
+/* Align global data. */
+#define DATA_ALIGNMENT(EXP, ALIGN)                     \
+  ARM_EXPAND_ALIGNMENT(!optimize_size, EXP, ALIGN)
+
+/* Similarly, make sure that objects on the stack are sensibly aligned.  */
+#define LOCAL_ALIGNMENT(EXP, ALIGN)                            \
+  ARM_EXPAND_ALIGNMENT(!flag_conserve_stack, EXP, 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>
@@ -610,6 +749,10 @@ extern int arm_structure_size_boundary;
   1,1,1,1,1,1,1,1,     \
   1,1,1,1,1,1,1,1,     \
   1,1,1,1,1,1,1,1,     \
+  1,1,1,1,1,1,1,1,     \
+  1,1,1,1,1,1,1,1,     \
+  1,1,1,1,1,1,1,1,     \
+  1,1,1,1,1,1,1,1,     \
   1                    \
 }
 
@@ -636,6 +779,10 @@ extern int arm_structure_size_boundary;
   1,1,1,1,1,1,1,1,          \
   1,1,1,1,1,1,1,1,          \
   1,1,1,1,1,1,1,1,          \
+  1,1,1,1,1,1,1,1,          \
+  1,1,1,1,1,1,1,1,          \
+  1,1,1,1,1,1,1,1,          \
+  1,1,1,1,1,1,1,1,          \
   1                         \
 }
 
@@ -647,18 +794,18 @@ extern int arm_structure_size_boundary;
 {                                                              \
   int regno;                                                   \
                                                                \
-  if (TARGET_SOFT_FLOAT || TARGET_THUMB || !TARGET_FPA)                \
+  if (TARGET_SOFT_FLOAT || TARGET_THUMB1 || !TARGET_FPA)       \
     {                                                          \
       for (regno = FIRST_FPA_REGNUM;                           \
           regno <= LAST_FPA_REGNUM; ++regno)                   \
        fixed_regs[regno] = call_used_regs[regno] = 1;          \
     }                                                          \
                                                                \
-  if (TARGET_THUMB && optimize_size)                           \
-    {                                                          \
-      /* When optimizing for size, it's better not to use      \
-        the HI regs, because of the overhead of stacking       \
-        them.  */                                              \
+  if (TARGET_THUMB1 && optimize_size)                          \
+    {                                                           \
+      /* When optimizing for size on Thumb-1, it's better not  \
+        to use the HI regs, because of the overhead of         \
+        stacking them.  */                                      \
       for (regno = FIRST_HI_REGNUM;                            \
           regno <= LAST_HI_REGNUM; ++regno)                    \
        fixed_regs[regno] = call_used_regs[regno] = 1;          \
@@ -667,10 +814,10 @@ extern int arm_structure_size_boundary;
   /* The link register can be clobbered by any branch insn,    \
      but we have no way to track that at present, so mark      \
      it as unavailable.  */                                    \
-  if (TARGET_THUMB                                           \
+  if (TARGET_THUMB1)                                           \
     fixed_regs[LR_REGNUM] = call_used_regs[LR_REGNUM] = 1;     \
                                                                \
-  if (TARGET_ARM && TARGET_HARD_FLOAT)                         \
+  if (TARGET_32BIT && TARGET_HARD_FLOAT)                       \
     {                                                          \
       if (TARGET_MAVERICK)                                     \
        {                                                       \
@@ -686,11 +833,15 @@ extern int arm_structure_size_boundary;
        }                                                       \
       if (TARGET_VFP)                                          \
        {                                                       \
+         /* VFPv3 registers are disabled when earlier VFP      \
+            versions are selected due to the definition of     \
+            LAST_VFP_REGNUM.  */                               \
          for (regno = FIRST_VFP_REGNUM;                        \
               regno <= LAST_VFP_REGNUM; ++ regno)              \
            {                                                   \
              fixed_regs[regno] = 0;                            \
-             call_used_regs[regno] = regno < FIRST_VFP_REGNUM + 16; \
+             call_used_regs[regno] = regno < FIRST_VFP_REGNUM + 16 \
+               || regno >= FIRST_VFP_REGNUM + 32;              \
            }                                                   \
        }                                                       \
     }                                                          \
@@ -773,6 +924,9 @@ extern int arm_structure_size_boundary;
 /* The number of (integer) argument register available.  */
 #define NUM_ARG_REGS           4
 
+/* And similarly for the VFP.  */
+#define NUM_VFP_ARG_REGS       16
+
 /* Return the register number of the N'th (integer) argument.  */
 #define ARG_REGISTER(N)        (N - 1)
 
@@ -788,14 +942,11 @@ extern int arm_structure_size_boundary;
 #define FIRST_HI_REGNUM                8
 #define LAST_HI_REGNUM         11
 
-#ifndef TARGET_UNWIND_INFO
-/* We use sjlj exceptions for backwards compatibility.  */
-#define MUST_USE_SJLJ_EXCEPTIONS 1
+/* Overridden by config/arm/bpabi.h.  */
+#ifndef ARM_UNWIND_INFO
+#define ARM_UNWIND_INFO  0
 #endif
 
-/* We can generate DWARF2 Unwind info, even though we don't use it.  */
-#define DWARF2_UNWIND_INFO 1
-
 /* Use r0 and r1 to pass exception handling information.  */
 #define EH_RETURN_DATA_REGNO(N) (((N) < 2) ? N : INVALID_REGNUM)
 
@@ -806,7 +957,7 @@ extern int arm_structure_size_boundary;
 /* 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 ? 12 : 9)
+#define STATIC_CHAIN_REGNUM    12
 
 /* 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
@@ -832,6 +983,9 @@ extern int arm_structure_size_boundary;
    ? ARM_HARD_FRAME_POINTER_REGNUM             \
    : THUMB_HARD_FRAME_POINTER_REGNUM)
 
+#define HARD_FRAME_POINTER_IS_FRAME_POINTER 0
+#define HARD_FRAME_POINTER_IS_ARG_POINTER 0
+
 #define FP_REGNUM                      HARD_FRAME_POINTER_REGNUM
 
 /* Register to use for pushing function arguments.  */
@@ -864,15 +1018,47 @@ extern int arm_structure_size_boundary;
   (((REGNUM) >= FIRST_CIRRUS_FP_REGNUM) && ((REGNUM) <= LAST_CIRRUS_FP_REGNUM))
 
 #define FIRST_VFP_REGNUM       63
-#define LAST_VFP_REGNUM                94
+#define D7_VFP_REGNUM          78  /* Registers 77 and 78 == VFP reg D7.  */
+#define LAST_VFP_REGNUM        \
+  (TARGET_VFPD32 ? LAST_HI_VFP_REGNUM : LAST_LO_VFP_REGNUM)
+
 #define IS_VFP_REGNUM(REGNUM) \
   (((REGNUM) >= FIRST_VFP_REGNUM) && ((REGNUM) <= LAST_VFP_REGNUM))
 
+/* VFP registers are split into two types: those defined by VFP versions < 3
+   have D registers overlaid on consecutive pairs of S registers. VFP version 3
+   defines 16 new D registers (d16-d31) which, for simplicity and correctness
+   in various parts of the backend, we implement as "fake" single-precision
+   registers (which would be S32-S63, but cannot be used in that way).  The
+   following macros define these ranges of registers.  */
+#define LAST_LO_VFP_REGNUM     94
+#define FIRST_HI_VFP_REGNUM    95
+#define LAST_HI_VFP_REGNUM     126
+
+#define VFP_REGNO_OK_FOR_SINGLE(REGNUM) \
+  ((REGNUM) <= LAST_LO_VFP_REGNUM)
+
+/* DFmode values are only valid in even register pairs.  */
+#define VFP_REGNO_OK_FOR_DOUBLE(REGNUM) \
+  ((((REGNUM) - FIRST_VFP_REGNUM) & 1) == 0)
+
+/* Neon Quad values must start at a multiple of four registers.  */
+#define NEON_REGNO_OK_FOR_QUAD(REGNUM) \
+  ((((REGNUM) - FIRST_VFP_REGNUM) & 3) == 0)
+
+/* Neon structures of vectors must be in even register pairs and there
+   must be enough registers available.  Because of various patterns
+   requiring quad registers, we require them to start at a multiple of
+   four.  */
+#define NEON_REGNO_OK_FOR_NREGS(REGNUM, N) \
+  ((((REGNUM) - FIRST_VFP_REGNUM) & 3) == 0 \
+   && (LAST_VFP_REGNUM - (REGNUM) >= 2 * (N) - 1))
+
 /* The number of hard registers is 16 ARM + 8 FPA + 1 CC + 1 SFP + 1 AFP.  */
 /* + 16 Cirrus registers take us up to 43.  */
 /* Intel Wireless MMX Technology registers add 16 + 4 more.  */
-/* VFP adds 32 + 1 more.  */
-#define FIRST_PSEUDO_REGISTER   96
+/* VFP (VFP3) adds 32 (64) + 1 more.  */
+#define FIRST_PSEUDO_REGISTER   128
 
 #define DBX_REGISTER_NUMBER(REGNO) arm_dbx_register_number (REGNO)
 
@@ -887,11 +1073,6 @@ extern int arm_structure_size_boundary;
 #define SUBTARGET_FRAME_POINTER_REQUIRED 0
 #endif
 
-#define FRAME_POINTER_REQUIRED                                 \
-  (current_function_has_nonlocal_label                         \
-   || SUBTARGET_FRAME_POINTER_REQUIRED                         \
-   || (TARGET_ARM && TARGET_APCS_FRAME && ! leaf_function_p ()))
-
 /* Return number of consecutive hard regs needed starting at reg REGNO
    to hold something of mode MODE.
    This is ordinarily the length in words of a value of mode MODE
@@ -900,7 +1081,7 @@ extern int arm_structure_size_boundary;
    On the ARM regs are UNITS_PER_WORD bits wide; FPA regs can hold any FP
    mode.  */
 #define HARD_REGNO_NREGS(REGNO, MODE)          \
-  ((TARGET_ARM                                 \
+  ((TARGET_32BIT                       \
     && REGNO >= FIRST_FPA_REGNUM       \
     && REGNO != FRAME_POINTER_REGNUM   \
     && REGNO != ARG_POINTER_REGNUM)    \
@@ -921,37 +1102,70 @@ extern int arm_structure_size_boundary;
 #define VALID_IWMMXT_REG_MODE(MODE) \
  (arm_vector_mode_supported_p (MODE) || (MODE) == DImode)
 
+/* Modes valid for Neon D registers.  */
+#define VALID_NEON_DREG_MODE(MODE) \
+  ((MODE) == V2SImode || (MODE) == V4HImode || (MODE) == V8QImode \
+   || (MODE) == V2SFmode || (MODE) == DImode)
+
+/* Modes valid for Neon Q registers.  */
+#define VALID_NEON_QREG_MODE(MODE) \
+  ((MODE) == V4SImode || (MODE) == V8HImode || (MODE) == V16QImode \
+   || (MODE) == V4SFmode || (MODE) == V2DImode)
+
+/* Structure modes valid for Neon registers.  */
+#define VALID_NEON_STRUCT_MODE(MODE) \
+  ((MODE) == TImode || (MODE) == EImode || (MODE) == OImode \
+   || (MODE) == CImode || (MODE) == XImode)
+
+/* The register numbers in sequence, for passing to arm_gen_load_multiple.  */
+extern int arm_regs_in_sequence[];
+
 /* The order in which register should be allocated.  It is good to use ip
    since no saving is required (though calls clobber it) and it never contains
    function parameters.  It is quite good to use lr since other calls may
    clobber it anyway.  Allocate r0 through r3 in reverse order since r3 is
    least likely to contain a function parameter; in addition results are
-   returned in r0.  */
-
-#define REG_ALLOC_ORDER            \
-{                                   \
-     3,  2,  1,  0, 12, 14,  4,  5, \
-     6,  7,  8, 10,  9, 11, 13, 15, \
-    16, 17, 18, 19, 20, 21, 22, 23, \
-    27, 28, 29, 30, 31, 32, 33, 34, \
-    35, 36, 37, 38, 39, 40, 41, 42, \
-    43, 44, 45, 46, 47, 48, 49, 50, \
-    51, 52, 53, 54, 55, 56, 57, 58, \
-    59, 60, 61, 62,                \
-    24, 25, 26,                            \
-    78, 77, 76, 75, 74, 73, 72, 71, \
-    70, 69, 68, 67, 66, 65, 64, 63, \
-    79, 80, 81, 82, 83, 84, 85, 86, \
-    87, 88, 89, 90, 91, 92, 93, 94, \
-    95                             \
+   returned in r0.
+   For VFP/VFPv3, allocate D16-D31 first, then caller-saved registers (D0-D7),
+   then D8-D15.  The reason for doing this is to attempt to reduce register
+   pressure when both single- and double-precision registers are used in a
+   function.  */
+
+#define REG_ALLOC_ORDER                                \
+{                                              \
+     3,  2,  1,  0, 12, 14,  4,  5,            \
+     6,  7,  8, 10,  9, 11, 13, 15,            \
+    16, 17, 18, 19, 20, 21, 22, 23,            \
+    27, 28, 29, 30, 31, 32, 33, 34,            \
+    35, 36, 37, 38, 39, 40, 41, 42,            \
+    43, 44, 45, 46, 47, 48, 49, 50,            \
+    51, 52, 53, 54, 55, 56, 57, 58,            \
+    59, 60, 61, 62,                            \
+    24, 25, 26,                                        \
+    95,  96,  97,  98,  99, 100, 101, 102,     \
+   103, 104, 105, 106, 107, 108, 109, 110,     \
+   111, 112, 113, 114, 115, 116, 117, 118,     \
+   119, 120, 121, 122, 123, 124, 125, 126,     \
+    78,  77,  76,  75,  74,  73,  72,  71,     \
+    70,  69,  68,  67,  66,  65,  64,  63,     \
+    79,  80,  81,  82,  83,  84,  85,  86,     \
+    87,  88,  89,  90,  91,  92,  93,  94,     \
+   127                                         \
 }
 
+/* Use different register alloc ordering for Thumb.  */
+#define ADJUST_REG_ALLOC_ORDER arm_order_regs_for_local_alloc ()
+
+/* Tell IRA to use the order we define rather than messing it up with its
+   own cost calculations.  */
+#define HONOR_REG_ALLOC_ORDER
+
 /* 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])
+        df_regs_ever_live_p (DST))
 \f
 /* Register and constant classes.  */
 
@@ -962,6 +1176,9 @@ enum reg_class
   NO_REGS,
   FPA_REGS,
   CIRRUS_REGS,
+  VFP_D0_D7_REGS,
+  VFP_LO_REGS,
+  VFP_HI_REGS,
   VFP_REGS,
   IWMMXT_GR_REGS,
   IWMMXT_REGS,
@@ -972,6 +1189,7 @@ enum reg_class
   CC_REG,
   VFPCC_REG,
   GENERAL_REGS,
+  CORE_REGS,
   ALL_REGS,
   LIM_REG_CLASSES
 };
@@ -984,6 +1202,9 @@ enum reg_class
   "NO_REGS",           \
   "FPA_REGS",          \
   "CIRRUS_REGS",       \
+  "VFP_D0_D7_REGS",    \
+  "VFP_LO_REGS",       \
+  "VFP_HI_REGS",       \
   "VFP_REGS",          \
   "IWMMXT_GR_REGS",    \
   "IWMMXT_REGS",       \
@@ -994,36 +1215,60 @@ enum reg_class
   "CC_REG",            \
   "VFPCC_REG",         \
   "GENERAL_REGS",      \
+  "CORE_REGS",         \
   "ALL_REGS",          \
 }
 
 /* Define which registers fit in which classes.
    This is an initializer for a vector of HARD_REG_SET
    of length N_REG_CLASSES.  */
-#define REG_CLASS_CONTENTS                                     \
-{                                                              \
-  { 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS  */       \
-  { 0x00FF0000, 0x00000000, 0x00000000 }, /* FPA_REGS */       \
-  { 0xF8000000, 0x000007FF, 0x00000000 }, /* CIRRUS_REGS */    \
-  { 0x00000000, 0x80000000, 0x7FFFFFFF }, /* VFP_REGS  */      \
-  { 0x00000000, 0x00007800, 0x00000000 }, /* IWMMXT_GR_REGS */ \
-  { 0x00000000, 0x7FFF8000, 0x00000000 }, /* IWMMXT_REGS */    \
-  { 0x000000FF, 0x00000000, 0x00000000 }, /* LO_REGS */                \
-  { 0x00002000, 0x00000000, 0x00000000 }, /* STACK_REG */      \
-  { 0x000020FF, 0x00000000, 0x00000000 }, /* BASE_REGS */      \
-  { 0x0000FF00, 0x00000000, 0x00000000 }, /* HI_REGS */                \
-  { 0x01000000, 0x00000000, 0x00000000 }, /* CC_REG */         \
-  { 0x00000000, 0x00000000, 0x80000000 }, /* VFPCC_REG */      \
-  { 0x0200FFFF, 0x00000000, 0x00000000 }, /* GENERAL_REGS */   \
-  { 0xFAFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF }  /* ALL_REGS */       \
+#define REG_CLASS_CONTENTS                                             \
+{                                                                      \
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS  */   \
+  { 0x00FF0000, 0x00000000, 0x00000000, 0x00000000 }, /* FPA_REGS */   \
+  { 0xF8000000, 0x000007FF, 0x00000000, 0x00000000 }, /* CIRRUS_REGS */        \
+  { 0x00000000, 0x80000000, 0x00007FFF, 0x00000000 }, /* VFP_D0_D7_REGS  */ \
+  { 0x00000000, 0x80000000, 0x7FFFFFFF, 0x00000000 }, /* VFP_LO_REGS  */ \
+  { 0x00000000, 0x00000000, 0x80000000, 0x7FFFFFFF }, /* VFP_HI_REGS  */ \
+  { 0x00000000, 0x80000000, 0xFFFFFFFF, 0x7FFFFFFF }, /* VFP_REGS  */  \
+  { 0x00000000, 0x00007800, 0x00000000, 0x00000000 }, /* IWMMXT_GR_REGS */ \
+  { 0x00000000, 0x7FFF8000, 0x00000000, 0x00000000 }, /* IWMMXT_REGS */        \
+  { 0x000000FF, 0x00000000, 0x00000000, 0x00000000 }, /* LO_REGS */    \
+  { 0x00002000, 0x00000000, 0x00000000, 0x00000000 }, /* STACK_REG */  \
+  { 0x000020FF, 0x00000000, 0x00000000, 0x00000000 }, /* BASE_REGS */  \
+  { 0x0000DF00, 0x00000000, 0x00000000, 0x00000000 }, /* HI_REGS */    \
+  { 0x01000000, 0x00000000, 0x00000000, 0x00000000 }, /* CC_REG */     \
+  { 0x00000000, 0x00000000, 0x00000000, 0x80000000 }, /* VFPCC_REG */  \
+  { 0x0000DFFF, 0x00000000, 0x00000000, 0x00000000 }, /* GENERAL_REGS */ \
+  { 0x0000FFFF, 0x00000000, 0x00000000, 0x00000000 }, /* CORE_REGS */  \
+  { 0xFAFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF }  /* ALL_REGS */   \
 }
 
+/* Any of the VFP register classes.  */
+#define IS_VFP_CLASS(X) \
+  ((X) == VFP_D0_D7_REGS || (X) == VFP_LO_REGS \
+   || (X) == VFP_HI_REGS || (X) == VFP_REGS)
+
 /* The same information, inverted:
    Return the class number of the smallest class containing
    reg number REGNO.  This could be a conditional expression
    or could index an array.  */
 #define REGNO_REG_CLASS(REGNO)  arm_regno_class (REGNO)
 
+/* The following macro defines cover classes for Integrated Register
+   Allocator.  Cover classes is a set of non-intersected register
+   classes covering all hard registers used for register allocation
+   purpose.  Any move between two registers of a cover class should be
+   cheaper than load or store of the registers.  The macro value is
+   array of register classes with LIM_REG_CLASSES used as the end
+   marker.  */
+
+#define IRA_COVER_CLASSES                                                   \
+{                                                                           \
+  GENERAL_REGS, FPA_REGS, CIRRUS_REGS, VFP_REGS, IWMMXT_GR_REGS, IWMMXT_REGS,\
+  LIM_REG_CLASSES                                                           \
+}
+
 /* FPA registers can't do subreg as all values are reformatted to internal
    precision.  VFP registers may only be accessed in the mode they
    were set.  */
@@ -1033,154 +1278,37 @@ enum reg_class
      || reg_classes_intersect_p (VFP_REGS, (CLASS))    \
    : 0)
 
-/* We need to define this for LO_REGS on thumb.  Otherwise we can end up
-   using r0-r4 for function arguments, r7 for the stack frame and don't
-   have enough left over to do doubleword arithmetic.  */
-#define CLASS_LIKELY_SPILLED_P(CLASS)  \
-    ((TARGET_THUMB && (CLASS) == LO_REGS)      \
-     || (CLASS) == CC_REG)
-
 /* The class value for index registers, and the one for base regs.  */
-#define INDEX_REG_CLASS  (TARGET_THUMB ? LO_REGS : GENERAL_REGS)
-#define BASE_REG_CLASS   (TARGET_THUMB ? LO_REGS : GENERAL_REGS)
+#define INDEX_REG_CLASS  (TARGET_THUMB1 ? LO_REGS : GENERAL_REGS)
+#define BASE_REG_CLASS   (TARGET_THUMB1 ? LO_REGS : CORE_REGS)
 
 /* For the Thumb the high registers cannot be used as base registers
    when addressing quantities in QI or HI mode; if we don't know the
    mode, then we must be conservative.  */
 #define MODE_BASE_REG_CLASS(MODE)                                      \
-    (TARGET_ARM ? GENERAL_REGS :                                       \
+    (TARGET_32BIT ? CORE_REGS :                                        \
      (((MODE) == SImode) ? BASE_REGS : LO_REGS))
 
 /* For Thumb we can not support SP+reg addressing, so we return LO_REGS
    instead of BASE_REGS.  */
 #define MODE_BASE_REG_REG_CLASS(MODE) BASE_REG_CLASS
 
-/* When SMALL_REGISTER_CLASSES is nonzero, the compiler allows
+/* When this hook returns true for MODE, 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
    registers.  */
-#define SMALL_REGISTER_CLASSES   TARGET_THUMB
-
-/* Get reg_class from a letter such as appears in the machine description.
-   We only need constraint `f' for FPA_REGS (`r' == GENERAL_REGS) for the
-   ARM, but several more letters for the Thumb.  */
-#define REG_CLASS_FROM_LETTER(C)       \
-  (  (C) == 'f' ? FPA_REGS             \
-   : (C) == 'v' ? CIRRUS_REGS          \
-   : (C) == 'w' ? VFP_REGS             \
-   : (C) == 'y' ? IWMMXT_REGS          \
-   : (C) == 'z' ? IWMMXT_GR_REGS       \
-   : (C) == 'l' ? (TARGET_ARM ? GENERAL_REGS : LO_REGS)        \
-   : TARGET_ARM ? NO_REGS              \
-   : (C) == 'h' ? HI_REGS              \
-   : (C) == 'b' ? BASE_REGS            \
-   : (C) == 'k' ? STACK_REG            \
-   : (C) == 'c' ? CC_REG               \
-   : NO_REGS)
-
-/* The letters I, J, K, L and M in a register constraint string
-   can be used to stand for particular ranges of immediate operands.
-   This macro defines what the ranges are.
-   C is the letter, and VALUE is a constant value.
-   Return 1 if VALUE is in the range specified by C.
-       I: immediate arithmetic operand (i.e. 8 bits shifted as required).
-       J: valid indexing constants.
-       K: ~value ok in rhs argument of data operand.
-       L: -value ok in rhs argument of data operand.
-        M: 0..32, or a power of 2  (for shifts, or mult done by shift).  */
-#define CONST_OK_FOR_ARM_LETTER(VALUE, C)              \
-  ((C) == 'I' ? const_ok_for_arm (VALUE) :             \
-   (C) == 'J' ? ((VALUE) < 4096 && (VALUE) > -4096) :  \
-   (C) == 'K' ? (const_ok_for_arm (~(VALUE))) :                \
-   (C) == 'L' ? (const_ok_for_arm (-(VALUE))) :                \
-   (C) == 'M' ? (((VALUE >= 0 && VALUE <= 32))         \
-                || (((VALUE) & ((VALUE) - 1)) == 0))   \
-   : 0)
-
-#define CONST_OK_FOR_THUMB_LETTER(VAL, C)              \
-  ((C) == 'I' ? (unsigned HOST_WIDE_INT) (VAL) < 256 : \
-   (C) == 'J' ? (VAL) > -256 && (VAL) < 0 :            \
-   (C) == 'K' ? thumb_shiftable_const (VAL) :          \
-   (C) == 'L' ? (VAL) > -8 && (VAL) < 8        :               \
-   (C) == 'M' ? ((unsigned HOST_WIDE_INT) (VAL) < 1024 \
-                  && ((VAL) & 3) == 0) :               \
-   (C) == 'N' ? ((unsigned HOST_WIDE_INT) (VAL) < 32) :        \
-   (C) == 'O' ? ((VAL) >= -508 && (VAL) <= 508)                \
-   : 0)
-
-#define CONST_OK_FOR_LETTER_P(VALUE, C)                                        \
-  (TARGET_ARM ?                                                                \
-   CONST_OK_FOR_ARM_LETTER (VALUE, C) : CONST_OK_FOR_THUMB_LETTER (VALUE, C))
-
-/* Constant letter 'G' for the FP immediate constants.
-   'H' means the same constant negated.  */
-#define CONST_DOUBLE_OK_FOR_ARM_LETTER(X, C)                   \
-    ((C) == 'G' ? arm_const_double_rtx (X) :                   \
-     (C) == 'H' ? neg_const_double_rtx_ok_for_fpa (X) : 0)
-
-#define CONST_DOUBLE_OK_FOR_LETTER_P(X, C)                     \
-  (TARGET_ARM ?                                                        \
-   CONST_DOUBLE_OK_FOR_ARM_LETTER (X, C) : 0)
-
-/* For the ARM, `Q' means that this is a memory operand that is just
-   an offset from a register.
-   `S' means any symbol that has the SYMBOL_REF_FLAG set or a CONSTANT_POOL
-   address.  This means that the symbol is in the text segment and can be
-   accessed without using a load.
-   'D' Prefixes a number of const_double operands where:
-   'Da' is a constant that takes two ARM insns to load.
-   'Db' takes three ARM insns.
-   'Dc' takes four ARM insns, if we allow that in this compilation.
-   'U' Prefixes an extended memory constraint where:
-   'Uv' is an address valid for VFP load/store insns.
-   'Uy' is an address valid for iwmmxt load/store insns.
-   'Uq' is an address valid for ldrsb.  */
-
-#define EXTRA_CONSTRAINT_STR_ARM(OP, C, STR)                           \
-  (((C) == 'D') ? ((GET_CODE (OP) == CONST_DOUBLE                      \
-                   || GET_CODE (OP) == CONST_INT                       \
-                   || GET_CODE (OP) == CONST_VECTOR)                   \
-                  && (((STR)[1] == 'a'                                 \
-                       && arm_const_double_inline_cost (OP) == 2)      \
-                      || ((STR)[1] == 'b'                              \
-                          && arm_const_double_inline_cost (OP) == 3)   \
-                      || ((STR)[1] == 'c'                              \
-                          && arm_const_double_inline_cost (OP) == 4    \
-                          && !(optimize_size || arm_ld_sched)))) :     \
-   ((C) == 'Q') ? (GET_CODE (OP) == MEM                                        \
-                && GET_CODE (XEXP (OP, 0)) == REG) :                   \
-   ((C) == 'R') ? (GET_CODE (OP) == MEM                                        \
-                  && GET_CODE (XEXP (OP, 0)) == SYMBOL_REF             \
-                  && CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0))) :         \
-   ((C) == 'S') ? (optimize > 0 && CONSTANT_ADDRESS_P (OP)) :          \
-   ((C) == 'T') ? cirrus_memory_offset (OP) :                          \
-   ((C) == 'U' && (STR)[1] == 'v') ? arm_coproc_mem_operand (OP, FALSE) : \
-   ((C) == 'U' && (STR)[1] == 'y') ? arm_coproc_mem_operand (OP, TRUE) : \
-   ((C) == 'U' && (STR)[1] == 'q')                                     \
-    ? arm_extendqisi_mem_op (OP, GET_MODE (OP))                                \
-   : 0)
-
-#define CONSTRAINT_LEN(C,STR)                          \
-  (((C) == 'U' || (C) == 'D') ? 2 : DEFAULT_CONSTRAINT_LEN (C, STR))
-
-#define EXTRA_CONSTRAINT_THUMB(X, C)                                   \
-  ((C) == 'Q' ? (GET_CODE (X) == MEM                                   \
-                && GET_CODE (XEXP (X, 0)) == LABEL_REF) : 0)
-
-#define EXTRA_CONSTRAINT_STR(X, C, STR)                \
-  (TARGET_ARM                                  \
-   ? EXTRA_CONSTRAINT_STR_ARM (X, C, STR)      \
-   : EXTRA_CONSTRAINT_THUMB (X, C))
-
-#define EXTRA_MEMORY_CONSTRAINT(C, STR) ((C) == 'U')
+#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P \
+  arm_small_register_classes_for_mode_p 
 
 /* Given an rtx X being reloaded into a reg required to be
    in class CLASS, return the class of reg to actually use.
-   In general this is just CLASS, but for the Thumb we prefer
-   a LO_REGS class or a subset.  */
-#define PREFERRED_RELOAD_CLASS(X, CLASS)       \
-  (TARGET_ARM ? (CLASS) :                      \
-   ((CLASS) == BASE_REGS ? (CLASS) : LO_REGS))
+   In general this is just CLASS, but for the Thumb core registers and
+   immediate constants we prefer a LO_REGS class or a subset.  */
+#define PREFERRED_RELOAD_CLASS(X, CLASS)               \
+  (TARGET_32BIT ? (CLASS) :                            \
+   ((CLASS) == GENERAL_REGS || (CLASS) == HI_REGS      \
+    || (CLASS) == NO_REGS || (CLASS) == STACK_REG      \
+   ? LO_REGS : (CLASS)))
 
 /* Must leave BASE_REGS reloads alone */
 #define THUMB_SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X)             \
@@ -1201,27 +1329,31 @@ enum reg_class
    or out of a register in CLASS in MODE.  If it can be done directly,
    NO_REGS is returned.  */
 #define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X)          \
-  /* Restrict which direct reloads are allowed for VFP regs.  */ \
+  /* Restrict which direct reloads are allowed for VFP/iWMMXt regs.  */ \
   ((TARGET_VFP && TARGET_HARD_FLOAT                            \
-    && (CLASS) == VFP_REGS)                                    \
-   ? vfp_secondary_reload_class (MODE, X)                      \
-   : TARGET_ARM                                                        \
+    && IS_VFP_CLASS (CLASS))                                   \
+   ? coproc_secondary_reload_class (MODE, X, FALSE)            \
+   : (TARGET_IWMMXT && (CLASS) == IWMMXT_REGS)                 \
+   ? coproc_secondary_reload_class (MODE, X, TRUE)             \
+   : TARGET_32BIT                                              \
    ? (((MODE) == HImode && ! arm_arch4 && true_regnum (X) == -1) \
     ? GENERAL_REGS : NO_REGS)                                  \
    : THUMB_SECONDARY_OUTPUT_RELOAD_CLASS (CLASS, MODE, X))
 
 /* If we need to load shorts byte-at-a-time, then we need a scratch.  */
 #define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X)           \
-  /* Restrict which direct reloads are allowed for VFP regs.  */ \
+  /* Restrict which direct reloads are allowed for VFP/iWMMXt regs.  */ \
   ((TARGET_VFP && TARGET_HARD_FLOAT                            \
-    && (CLASS) == VFP_REGS)                                    \
-    ? vfp_secondary_reload_class (MODE, X) :                   \
+    && IS_VFP_CLASS (CLASS))                                   \
+    ? coproc_secondary_reload_class (MODE, X, FALSE) :         \
+    (TARGET_IWMMXT && (CLASS) == IWMMXT_REGS) ?                        \
+    coproc_secondary_reload_class (MODE, X, TRUE) :            \
   /* Cannot load constants into Cirrus registers.  */          \
    (TARGET_MAVERICK && TARGET_HARD_FLOAT                       \
      && (CLASS) == CIRRUS_REGS                                 \
      && (CONSTANT_P (X) || GET_CODE (X) == SYMBOL_REF))                \
     ? GENERAL_REGS :                                           \
-  (TARGET_ARM ?                                                        \
+  (TARGET_32BIT ?                                              \
    (((CLASS) == IWMMXT_REGS || (CLASS) == IWMMXT_GR_REGS)      \
       && CONSTANT_P (X))                                       \
    ? GENERAL_REGS :                                            \
@@ -1300,6 +1432,7 @@ enum reg_class
 /* We could probably achieve better results by defining PROMOTE_MODE to help
    cope with the variances between the Thumb's signed and unsigned byte and
    halfword load instructions.  */
+/* ??? This should be safe for thumb2, but we may be able to do better.  */
 #define THUMB_LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND_L, WIN)     \
 do {                                                                         \
   rtx new_x = thumb_legitimize_reload_address (&X, MODE, OPNUM, TYPE, IND_L); \
@@ -1325,13 +1458,17 @@ do {                                                                          \
 /* If defined, gives a class of registers that cannot be used as the
    operand of a SUBREG that changes the mode of the object illegally.  */
 
-/* Moves between FPA_REGS and GENERAL_REGS are two memory insns.  */
+/* Moves between FPA_REGS and GENERAL_REGS are two memory insns.
+   Moves between VFP_REGS and GENERAL_REGS are a single insn, but
+   it is typically more expensive than a single memory access.  We set
+   the cost to less than two memory accesses so that floating
+   point to integer conversion does not go through memory.  */
 #define REGISTER_MOVE_COST(MODE, FROM, TO)             \
-  (TARGET_ARM ?                                                \
+  (TARGET_32BIT ?                                              \
    ((FROM) == FPA_REGS && (TO) != FPA_REGS ? 20 :      \
     (FROM) != FPA_REGS && (TO) == FPA_REGS ? 20 :      \
-    (FROM) == VFP_REGS && (TO) != VFP_REGS ? 10 :  \
-    (FROM) != VFP_REGS && (TO) == VFP_REGS ? 10 :  \
+    IS_VFP_CLASS (FROM) && !IS_VFP_CLASS (TO) ? 15 :   \
+    !IS_VFP_CLASS (FROM) && IS_VFP_CLASS (TO) ? 15 :   \
     (FROM) == IWMMXT_REGS && (TO) != IWMMXT_REGS ? 4 :  \
     (FROM) != IWMMXT_REGS && (TO) == IWMMXT_REGS ? 4 :  \
     (FROM) == IWMMXT_GR_REGS || (TO) == IWMMXT_GR_REGS ? 20 :  \
@@ -1364,7 +1501,7 @@ do {                                                                            \
    couldn't convert a direct call into an indirect one.  */
 #define CALLER_INTERWORKING_SLOT_SIZE                  \
   (TARGET_CALLER_INTERWORKING                          \
-   && current_function_outgoing_args_size != 0         \
+   && crtl->outgoing_args_size != 0            \
    ? UNITS_PER_WORD : 0)
 
 /* Offset within stack frame to start allocating local variables at.
@@ -1381,73 +1518,47 @@ do {                                                                          \
 
 /* Define this if the maximum size of all the outgoing args is to be
    accumulated and pushed during the prologue.  The amount can be
-   found in the variable current_function_outgoing_args_size.  */
+   found in the variable crtl->outgoing_args_size.  */
 #define ACCUMULATE_OUTGOING_ARGS 1
 
 /* Offset of first parameter from the argument pointer register value.  */
 #define FIRST_PARM_OFFSET(FNDECL)  (TARGET_ARM ? 4 : 0)
 
-/* Value is the number of byte of arguments automatically
-   popped when returning from a subroutine call.
-   FUNDECL is the declaration node of the function (as a tree),
-   FUNTYPE is the data type of the function (as a tree),
-   or for a library call it is an identifier node for the subroutine name.
-   SIZE is the number of bytes of arguments passed on the stack.
-
-   On the ARM, the caller does not pop any of its arguments that were passed
-   on the stack.  */
-#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE)  0
-
 /* Define how to find the value returned by a library function
    assuming the value has mode MODE.  */
-#define LIBCALL_VALUE(MODE)  \
-  (TARGET_ARM && TARGET_HARD_FLOAT_ABI && TARGET_FPA                   \
-   && GET_MODE_CLASS (MODE) == MODE_FLOAT                              \
+#define LIBCALL_VALUE(MODE)                                            \
+  (TARGET_AAPCS_BASED ? aapcs_libcall_value (MODE)                     \
+   : (TARGET_32BIT && TARGET_HARD_FLOAT_ABI && TARGET_FPA              \
+      && GET_MODE_CLASS (MODE) == MODE_FLOAT)                          \
    ? gen_rtx_REG (MODE, FIRST_FPA_REGNUM)                              \
-   : TARGET_ARM && TARGET_HARD_FLOAT_ABI && TARGET_MAVERICK            \
+   : TARGET_32BIT && TARGET_HARD_FLOAT_ABI && TARGET_MAVERICK          \
      && GET_MODE_CLASS (MODE) == MODE_FLOAT                            \
    ? gen_rtx_REG (MODE, FIRST_CIRRUS_FP_REGNUM)                        \
    : TARGET_IWMMXT_ABI && arm_vector_mode_supported_p (MODE)           \
    ? gen_rtx_REG (MODE, FIRST_IWMMXT_REGNUM)                           \
    : gen_rtx_REG (MODE, ARG_REGISTER (1)))
 
-/* Define how to find the value returned by a function.
-   VALTYPE is the data type of the value (as a tree).
-   If the precise function being called is known, FUNC is its FUNCTION_DECL;
-   otherwise, FUNC is 0.  */
-#define FUNCTION_VALUE(VALTYPE, FUNC) \
-  arm_function_value (VALTYPE, FUNC);
-
-/* 1 if N is a possible register number for a function value.
-   On the ARM, only r0 and f0 can return results.  */
-/* On a Cirrus chip, mvf0 can return results.  */
-#define FUNCTION_VALUE_REGNO_P(REGNO)  \
-  ((REGNO) == ARG_REGISTER (1) \
-   || (TARGET_ARM && ((REGNO) == FIRST_CIRRUS_FP_REGNUM)               \
-       && TARGET_HARD_FLOAT_ABI && TARGET_MAVERICK)                    \
-   || ((REGNO) == FIRST_IWMMXT_REGNUM && TARGET_IWMMXT_ABI) \
-   || (TARGET_ARM && ((REGNO) == FIRST_FPA_REGNUM)                     \
+/* 1 if REGNO is a possible register number for a function value.  */
+#define FUNCTION_VALUE_REGNO_P(REGNO)                          \
+  ((REGNO) == ARG_REGISTER (1)                                 \
+   || (TARGET_AAPCS_BASED && TARGET_32BIT                      \
+       && TARGET_VFP && TARGET_HARD_FLOAT                      \
+       && (REGNO) == FIRST_VFP_REGNUM)                         \
+   || (TARGET_32BIT && ((REGNO) == FIRST_CIRRUS_FP_REGNUM)     \
+       && TARGET_HARD_FLOAT_ABI && TARGET_MAVERICK)            \
+   || ((REGNO) == FIRST_IWMMXT_REGNUM && TARGET_IWMMXT_ABI)    \
+   || (TARGET_32BIT && ((REGNO) == FIRST_FPA_REGNUM)           \
        && TARGET_HARD_FLOAT_ABI && TARGET_FPA))
 
 /* Amount of memory needed for an untyped call to save all possible return
    registers.  */
 #define APPLY_RESULT_SIZE arm_apply_result_size()
 
-/* How large values are returned */
-/* A C expression which can inhibit the returning of certain function values
-   in registers, based on the type of value.  */
-#define RETURN_IN_MEMORY(TYPE) arm_return_in_memory (TYPE)
-
 /* Define DEFAULT_PCC_STRUCT_RETURN to 1 if all structure and union return
    values must be in memory.  On the ARM, they need only do so if larger
    than a word, or if they contain elements offset from zero in the struct.  */
 #define DEFAULT_PCC_STRUCT_RETURN 0
 
-/* Flags for the call/call_value rtl operations set up by function_arg.  */
-#define CALL_NORMAL            0x00000000      /* No special processing.  */
-#define CALL_LONG              0x00000001      /* Always call indirect.  */
-#define CALL_SHORT             0x00000002      /* Never call indirect.  */
-
 /* These bits describe the different types of function supported
    by the ARM backend.  They are exclusive.  i.e. a function cannot be both a
    normal function and an interworked function, for example.  Knowing the
@@ -1474,6 +1585,7 @@ do {                                                                            \
 #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.  */
+#define ARM_FT_STACKALIGN      (1 << 6) /* Called with misaligned stack.  */
 
 /* Some macros to test these flags.  */
 #define ARM_FUNC_TYPE(t)       (t & ARM_FT_TYPE_MASK)
@@ -1481,6 +1593,7 @@ do {                                                                            \
 #define IS_VOLATILE(t)         (t & ARM_FT_VOLATILE)
 #define IS_NAKED(t)            (t & ARM_FT_NAKED)
 #define IS_NESTED(t)           (t & ARM_FT_NESTED)
+#define IS_STACKALIGN(t)               (t & ARM_FT_STACKALIGN)
 
 
 /* Structure used to hold the function stack frame layout.  Offsets are
@@ -1488,7 +1601,7 @@ do {                                                                            \
    in the direction of stack growth.
    Only soft_frame is used in thumb mode.  */
 
-typedef struct arm_stack_offsets GTY(())
+typedef struct GTY(()) arm_stack_offsets
 {
   int saved_args;      /* ARG_POINTER_REGNUM.  */
   int frame;           /* ARM_HARD_FRAME_POINTER_REGNUM.  */
@@ -1496,12 +1609,14 @@ typedef struct arm_stack_offsets GTY(())
   int soft_frame;      /* FRAME_POINTER_REGNUM.  */
   int locals_base;     /* THUMB_HARD_FRAME_POINTER_REGNUM.  */
   int outgoing_args;   /* STACK_POINTER_REGNUM.  */
+  unsigned int saved_regs_mask;
 }
 arm_stack_offsets;
 
+#ifndef GENERATOR_FILE
 /* A C structure for machine-specific, per-function data.
    This is added to the cfun structure.  */
-typedef struct machine_function GTY(())
+typedef struct GTY(()) machine_function
 {
   /* Additional stack adjustment in __builtin_eh_throw.  */
   rtx eh_epilogue_sp_ofs;
@@ -1526,16 +1641,46 @@ typedef struct machine_function GTY(())
      register.  We can never call via LR or PC.  We can call via SP if a
      trampoline happens to be on the top of the stack.  */
   rtx call_via[14];
+  /* Set to 1 when a return insn is output, this means that the epilogue
+     is not needed.  */
+  int return_used_this_function;
+  /* When outputting Thumb-1 code, record the last insn that provides
+     information about condition codes, and the comparison operands.  */
+  rtx thumb1_cc_insn;
+  rtx thumb1_cc_op0;
+  rtx thumb1_cc_op1;
+  /* Also record the CC mode that is supported.  */
+  enum machine_mode thumb1_cc_mode;
 }
 machine_function;
+#endif
 
 /* As in the machine_function, a global set of call-via labels, for code 
    that is in text_section.  */
 extern GTY(()) rtx thumb_call_via_label[14];
 
+/* The number of potential ways of assigning to a co-processor.  */
+#define ARM_NUM_COPROC_SLOTS 1
+
+/* Enumeration of procedure calling standard variants.  We don't really 
+   support all of these yet.  */
+enum arm_pcs
+{
+  ARM_PCS_AAPCS,       /* Base standard AAPCS.  */
+  ARM_PCS_AAPCS_VFP,   /* Use VFP registers for floating point values.  */
+  ARM_PCS_AAPCS_IWMMXT, /* Use iWMMXT registers for vectors.  */
+  /* This must be the last AAPCS variant.  */
+  ARM_PCS_AAPCS_LOCAL, /* Private call within this compilation unit.  */
+  ARM_PCS_ATPCS,       /* ATPCS.  */
+  ARM_PCS_APCS,                /* APCS (legacy Linux etc).  */
+  ARM_PCS_UNKNOWN
+};
+
+/* Default procedure calling standard of current compilation unit. */
+extern enum arm_pcs arm_pcs_default;
+
 /* 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
-   type `int' suffices and can hold the number of bytes of argument so far.  */
+   `FUNCTION_ARG' and other related values.  */
 typedef struct
 {
   /* This is the number of registers of arguments scanned so far.  */
@@ -1544,32 +1689,30 @@ typedef struct
   int iwmmxt_nregs;
   int named_count;
   int nargs;
-  /* One of CALL_NORMAL, CALL_LONG or CALL_SHORT.  */
-  int call_cookie;
-  int can_split;
+  /* Which procedure call variant to use for this call.  */
+  enum arm_pcs pcs_variant;
+
+  /* AAPCS related state tracking.  */
+  int aapcs_arg_processed;  /* No need to lay out this argument again.  */
+  int aapcs_cprc_slot;      /* Index of co-processor rules to handle
+                              this argument, or -1 if using core
+                              registers.  */
+  int aapcs_ncrn;
+  int aapcs_next_ncrn;
+  rtx aapcs_reg;           /* Register assigned to this argument.  */
+  int aapcs_partial;       /* How many bytes are passed in regs (if
+                              split between core regs and stack.
+                              Zero otherwise.  */
+  int aapcs_cprc_failed[ARM_NUM_COPROC_SLOTS];
+  int can_split;           /* Argument can be split between core regs
+                              and the stack.  */
+  /* Private data for tracking VFP register allocation */
+  unsigned aapcs_vfp_regs_free;
+  unsigned aapcs_vfp_reg_alloc;
+  int aapcs_vfp_rcount;
+  MACHMODE aapcs_vfp_rmode;
 } CUMULATIVE_ARGS;
 
-/* Define where to put the arguments to a function.
-   Value is zero to push the argument on the stack,
-   or a hard register in which to store the argument.
-
-   MODE is the argument's machine mode.
-   TYPE is the data type of the argument (as a tree).
-    This is null for libcalls where that information may
-    not be available.
-   CUM is a variable of type CUMULATIVE_ARGS which gives info about
-    the preceding args and about the function being called.
-   NAMED is nonzero if this argument is a named parameter
-    (otherwise it is an extra parameter matching an ellipsis).
-
-   On the ARM, normally the first 16 bytes are passed in registers r0-r3; all
-   other arguments are passed on the stack.  If (NAMED == 0) (which happens
-   only in assign_parms, since TARGET_SETUP_INCOMING_VARARGS is
-   defined), say it is passed in the stack (function_prologue will
-   indeed make it pass in the stack if necessary).  */
-#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
-  arm_function_arg (&(CUM), (MODE), (TYPE), (NAMED))
-
 #define FUNCTION_ARG_PADDING(MODE, TYPE) \
   (arm_pad_arg_upward (MODE, TYPE) ? upward : downward)
 
@@ -1588,17 +1731,6 @@ typedef struct
 #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
   arm_init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME), (FNDECL))
 
-/* Update the data in CUM to advance over an argument
-   of mode MODE and data type TYPE.
-   (TYPE is null for libcalls where that information may not be available.)  */
-#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)   \
-  (CUM).nargs += 1;                                    \
-  if (arm_vector_mode_supported_p (MODE)               \
-      && (CUM).named_count > (CUM).nargs)              \
-    (CUM).iwmmxt_nregs += 1;                           \
-  else                                                 \
-    (CUM).nregs += ARM_NUM_REGS2 (MODE, TYPE)
-
 /* If defined, a C expression that gives the alignment boundary, in bits, of an
    argument with the specified mode and type.  If it is not defined,
    `PARM_BOUNDARY' is used for all arguments.  */
@@ -1609,15 +1741,16 @@ 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)    \
-   (IN_RANGE ((REGNO), 0, 3)           \
-    || (TARGET_IWMMXT_ABI              \
+#define FUNCTION_ARG_REGNO_P(REGNO)                                    \
+   (IN_RANGE ((REGNO), 0, 3)                                           \
+    || (TARGET_AAPCS_BASED && TARGET_VFP && TARGET_HARD_FLOAT          \
+       && IN_RANGE ((REGNO), FIRST_VFP_REGNUM, FIRST_VFP_REGNUM + 15)) \
+    || (TARGET_IWMMXT_ABI                                              \
        && IN_RANGE ((REGNO), FIRST_IWMMXT_REGNUM, FIRST_IWMMXT_REGNUM + 9)))
 
 \f
 /* 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.  */
+   underscore, you may wish to re-define this to prevent any conflicts.  */
 #ifndef ARM_MCOUNT_NAME
 #define ARM_MCOUNT_NAME "*mcount"
 #endif
@@ -1677,12 +1810,12 @@ typedef struct
    frame.  */
 #define EXIT_IGNORE_STACK 1
 
-#define EPILOGUE_USES(REGNO) (reload_completed && (REGNO) == LR_REGNUM)
+#define EPILOGUE_USES(REGNO) ((REGNO) == LR_REGNUM)
 
 /* Determine if the epilogue should be output as RTL.
    You should override this if you define FUNCTION_EXTRA_EPILOGUE.  */
 #define USE_RETURN_INSN(ISCOND)                                \
-  (TARGET_ARM ? use_return_insn (ISCOND, NULL) : 0)
+  (TARGET_32BIT ? use_return_insn (ISCOND, NULL) : 0)
 
 /* Definitions for register eliminations.
 
@@ -1707,21 +1840,6 @@ typedef struct
  { FRAME_POINTER_REGNUM,      ARM_HARD_FRAME_POINTER_REGNUM   },\
  { FRAME_POINTER_REGNUM,      THUMB_HARD_FRAME_POINTER_REGNUM }}
 
-/* Given FROM and TO register numbers, say whether this elimination is
-   allowed.  Frame pointer elimination is automatically handled.
-
-   All eliminations are permissible.  Note that ARG_POINTER_REGNUM and
-   HARD_FRAME_POINTER_REGNUM are in fact the same thing.  If we need a frame
-   pointer, we must eliminate FRAME_POINTER_REGNUM into
-   HARD_FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM or
-   ARG_POINTER_REGNUM.  */
-#define CAN_ELIMINATE(FROM, TO)                                                \
-  (((TO) == FRAME_POINTER_REGNUM && (FROM) == ARG_POINTER_REGNUM) ? 0 :        \
-   ((TO) == STACK_POINTER_REGNUM && frame_pointer_needed) ? 0 :                \
-   ((TO) == ARM_HARD_FRAME_POINTER_REGNUM && TARGET_THUMB) ? 0 :       \
-   ((TO) == THUMB_HARD_FRAME_POINTER_REGNUM && TARGET_ARM) ? 0 :       \
-   1)
-
 /* Define the offset between two registers, one to be eliminated, and the
    other its replacement, at the start of a routine.  */
 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)                   \
@@ -1737,92 +1855,21 @@ typedef struct
    once for every function before code is generated.  */
 #define INIT_EXPANDERS  arm_init_expanders ()
 
-/* Output assembler code for a block containing the constant parts
-   of a trampoline, leaving space for the variable parts.
-
-   On the ARM, (if r8 is the static chain regnum, and remembering that
-   referencing pc adds an offset of 8) the trampoline looks like:
-          ldr          r8, [pc, #0]
-          ldr          pc, [pc]
-          .word        static chain value
-          .word        function's address
-   XXX 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);                           \
-  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.
-   Why - because it is easier.  This code will always be branched to via
-   a BX instruction and since the compiler magically generates the address
-   of the function the linker has no opportunity to ensure that the
-   bottom bit is set.  Thus the processor will be in ARM mode when it
-   reaches this code.  So we duplicate the ARM trampoline code and add
-   a switch into Thumb mode as well.  */
-#define THUMB_TRAMPOLINE_TEMPLATE(FILE)                \
-{                                              \
-  fprintf (FILE, "\t.code 32\n");              \
-  fprintf (FILE, ".Ltrampoline_start:\n");     \
-  asm_fprintf (FILE, "\tldr\t%r, [%r, #8]\n",  \
-              STATIC_CHAIN_REGNUM, PC_REGNUM); \
-  asm_fprintf (FILE, "\tldr\t%r, [%r, #8]\n",  \
-              IP_REGNUM, PC_REGNUM);           \
-  asm_fprintf (FILE, "\torr\t%r, %r, #1\n",     \
-              IP_REGNUM, IP_REGNUM);           \
-  asm_fprintf (FILE, "\tbx\t%r\n", IP_REGNUM); \
-  fprintf (FILE, "\t.word\t0\n");              \
-  fprintf (FILE, "\t.word\t0\n");              \
-  fprintf (FILE, "\t.code 16\n");              \
-}
-
-#define TRAMPOLINE_TEMPLATE(FILE)              \
-  if (TARGET_ARM)                              \
-    ARM_TRAMPOLINE_TEMPLATE (FILE)             \
-  else                                         \
-    THUMB_TRAMPOLINE_TEMPLATE (FILE)
-
 /* Length in units of the trampoline for entering a nested function.  */
-#define TRAMPOLINE_SIZE  (TARGET_ARM ? 16 : 24)
+#define TRAMPOLINE_SIZE  (TARGET_32BIT ? 16 : 20)
 
 /* 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.
-   CXT is an RTX for the static chain value for the function.  */
-#ifndef INITIALIZE_TRAMPOLINE
-#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT)                      \
-{                                                                      \
-  emit_move_insn (gen_rtx_MEM (SImode,                                 \
-                              plus_constant (TRAMP,                    \
-                                             TARGET_ARM ? 8 : 16)),    \
-                 CXT);                                                 \
-  emit_move_insn (gen_rtx_MEM (SImode,                                 \
-                              plus_constant (TRAMP,                    \
-                                             TARGET_ARM ? 12 : 20)),   \
-                 FNADDR);                                              \
-  emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"),      \
-                    0, VOIDmode, 2, TRAMP, Pmode,                      \
-                    plus_constant (TRAMP, TRAMPOLINE_SIZE), Pmode);    \
-}
-#endif
-
 \f
 /* Addressing modes, and classification of registers for them.  */
 #define HAVE_POST_INCREMENT   1
-#define HAVE_PRE_INCREMENT    TARGET_ARM
-#define HAVE_POST_DECREMENT   TARGET_ARM
-#define HAVE_PRE_DECREMENT    TARGET_ARM
-#define HAVE_PRE_MODIFY_DISP  TARGET_ARM
-#define HAVE_POST_MODIFY_DISP TARGET_ARM
-#define HAVE_PRE_MODIFY_REG   TARGET_ARM
-#define HAVE_POST_MODIFY_REG  TARGET_ARM
+#define HAVE_PRE_INCREMENT    TARGET_32BIT
+#define HAVE_POST_DECREMENT   TARGET_32BIT
+#define HAVE_PRE_DECREMENT    TARGET_32BIT
+#define HAVE_PRE_MODIFY_DISP  TARGET_32BIT
+#define HAVE_POST_MODIFY_DISP TARGET_32BIT
+#define HAVE_PRE_MODIFY_REG   TARGET_32BIT
+#define HAVE_POST_MODIFY_REG  TARGET_32BIT
 
 /* Macros to check register numbers against specific register classes.  */
 
@@ -1834,31 +1881,32 @@ typedef struct
 #define TEST_REGNO(R, TEST, VALUE) \
   ((R TEST VALUE) || ((unsigned) reg_renumber[R] TEST VALUE))
 
-/*   On the ARM, don't allow the pc to be used.  */
+/* Don't allow the pc to be used.  */
 #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)            \
+#define THUMB1_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)      \
+  (TARGET_THUMB1                                       \
+   ? THUMB1_REGNO_MODE_OK_FOR_BASE_P (REGNO, MODE)     \
    : ARM_REGNO_OK_FOR_BASE_P (REGNO))
 
 /* Nonzero if X can be the base register in a reg+reg addressing mode.
    For Thumb, we can not use SP + reg, so reject SP.  */
 #define REGNO_MODE_OK_FOR_REG_BASE_P(X, MODE)  \
-  REGNO_OK_FOR_INDEX_P (X)
+  REGNO_MODE_OK_FOR_BASE_P (X, QImode)
 
 /* 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)
+  (REGNO_MODE_OK_FOR_BASE_P (REGNO, QImode) \
+   && !TEST_REGNO (REGNO, ==, STACK_POINTER_REGNUM))
 
 /* Maximum number of registers that can appear in a valid memory address.
    Shifts in addresses can't be by a register.  */
@@ -1866,20 +1914,20 @@ typedef struct
 
 /* Recognize any constant value that is a valid address.  */
 /* XXX We can address any constant, eventually...  */
-
-#ifdef AOF_ASSEMBLER
-
-#define CONSTANT_ADDRESS_P(X)          \
-  (GET_CODE (X) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (X))
-
-#else
-
+/* ??? Should the TARGET_ARM here also apply to thumb2?  */
 #define CONSTANT_ADDRESS_P(X)                          \
   (GET_CODE (X) == SYMBOL_REF                  \
    && (CONSTANT_POOL_ADDRESS_P (X)             \
        || (TARGET_ARM && optimize > 0 && SYMBOL_REF_FLAG (X))))
 
-#endif /* AOF_ASSEMBLER */
+/* True if SYMBOL + OFFSET constants must refer to something within
+   SYMBOL's section.  */
+#define ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P 0
+
+/* Nonzero if all target requires all absolute relocations be R_ARM_ABS32.  */
+#ifndef TARGET_DEFAULT_WORD_RELOCATIONS
+#define TARGET_DEFAULT_WORD_RELOCATIONS 0
+#endif
 
 /* Nonzero if the constant value X is a legitimate general operand.
    It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.
@@ -1898,21 +1946,9 @@ typedef struct
   || flag_pic)
 
 #define LEGITIMATE_CONSTANT_P(X)                       \
-  (!arm_tls_referenced_p (X)                           \
-   && (TARGET_ARM ? ARM_LEGITIMATE_CONSTANT_P (X)      \
-                 : THUMB_LEGITIMATE_CONSTANT_P (X)))
-
-/* Special characters prefixed to function names
-   in order to encode attribute like information.
-   Note, '@' and '*' have already been taken.  */
-#define SHORT_CALL_FLAG_CHAR   '^'
-#define LONG_CALL_FLAG_CHAR    '#'
-
-#define ENCODED_SHORT_CALL_ATTR_P(SYMBOL_NAME) \
-  (*(SYMBOL_NAME) == SHORT_CALL_FLAG_CHAR)
-
-#define ENCODED_LONG_CALL_ATTR_P(SYMBOL_NAME)  \
-  (*(SYMBOL_NAME) == LONG_CALL_FLAG_CHAR)
+  (!arm_cannot_force_const_mem (X)                     \
+   && (TARGET_32BIT ? ARM_LEGITIMATE_CONSTANT_P (X)    \
+                   : THUMB_LEGITIMATE_CONSTANT_P (X)))
 
 #ifndef SUBTARGET_NAME_ENCODING_LENGTHS
 #define SUBTARGET_NAME_ENCODING_LENGTHS
@@ -1923,8 +1959,6 @@ typedef struct
    be stripped from the start of a function's name, if that
    name starts with the indicated character.  */
 #define ARM_NAME_ENCODING_LENGTHS              \
-  case SHORT_CALL_FLAG_CHAR: return 1;         \
-  case LONG_CALL_FLAG_CHAR:  return 1;         \
   case '*':  return 1;                         \
   SUBTARGET_NAME_ENCODING_LENGTHS
 
@@ -1934,6 +1968,11 @@ typedef struct
 #define ASM_OUTPUT_LABELREF(FILE, NAME)                \
    arm_asm_output_labelref (FILE, NAME)
 
+/* Output IT instructions for conditionally executed Thumb-2 instructions.  */
+#define ASM_OUTPUT_OPCODE(STREAM, PTR) \
+  if (TARGET_THUMB2)                   \
+    thumb2_asm_output_opcode (STREAM);
+
 /* The EABI specifies that constructors should go in .init_array.
    Other targets use .ctors for compatibility.  */
 #ifndef ARM_EABI_CTORS_SECTION_OP
@@ -1986,30 +2025,15 @@ typedef struct
 #define TARGET_ARM_DYNAMIC_VAGUE_LINKAGE_P true
 #endif
 
-/* Set the short-call flag for any function compiled in the current
-   compilation unit.  We skip this for functions with the section
-   attribute when long-calls are in effect as this tells the compiler
-   that the section might be placed a long way from the caller.
-   See arm_is_longcall_p() for more information.  */
-#define ARM_DECLARE_FUNCTION_SIZE(STREAM, NAME, DECL)  \
-  if (!TARGET_LONG_CALLS || ! DECL_SECTION_NAME (DECL)) \
-    arm_encode_call_attribute (DECL, SHORT_CALL_FLAG_CHAR)
-
 #define ARM_OUTPUT_FN_UNWIND(F, PROLOGUE) arm_output_fn_unwind (F, PROLOGUE)
 
-#ifdef TARGET_UNWIND_INFO
-#define ARM_EABI_UNWIND_TABLES \
-  ((!USING_SJLJ_EXCEPTIONS && flag_exceptions) || flag_unwind_tables)
-#else
-#define ARM_EABI_UNWIND_TABLES 0
-#endif
-
 /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
    and check its validity for a certain class.
    We have two alternate definitions for each of them.
    The usual definition accepts all pseudo regs; the other rejects
    them unless they have been allocated suitable hard regs.
-   The symbol REG_OK_STRICT causes the latter definition to be used.  */
+   The symbol REG_OK_STRICT causes the latter definition to be used.
+   Thumb-2 has the same restrictions as arm.  */
 #ifndef REG_OK_STRICT
 
 #define ARM_REG_OK_FOR_BASE_P(X)               \
@@ -2018,7 +2042,14 @@ typedef struct
    || REGNO (X) == FRAME_POINTER_REGNUM                \
    || REGNO (X) == ARG_POINTER_REGNUM)
 
-#define THUMB_REG_MODE_OK_FOR_BASE_P(X, MODE)  \
+#define ARM_REG_OK_FOR_INDEX_P(X)              \
+  ((REGNO (X) <= LAST_ARM_REGNUM               \
+    && REGNO (X) != STACK_POINTER_REGNUM)      \
+   || REGNO (X) >= FIRST_PSEUDO_REGISTER       \
+   || REGNO (X) == FRAME_POINTER_REGNUM                \
+   || REGNO (X) == ARG_POINTER_REGNUM)
+
+#define THUMB1_REG_MODE_OK_FOR_BASE_P(X, MODE) \
   (REGNO (X) <= LAST_LO_REGNUM                 \
    || REGNO (X) >= FIRST_PSEUDO_REGISTER       \
    || (GET_MODE_SIZE (MODE) >= 4               \
@@ -2033,8 +2064,11 @@ typedef struct
 #define ARM_REG_OK_FOR_BASE_P(X)               \
   ARM_REGNO_OK_FOR_BASE_P (REGNO (X))
 
-#define THUMB_REG_MODE_OK_FOR_BASE_P(X, MODE)  \
-  THUMB_REGNO_MODE_OK_FOR_BASE_P (REGNO (X), MODE)
+#define ARM_REG_OK_FOR_INDEX_P(X)              \
+  ARM_REGNO_OK_FOR_INDEX_P (REGNO (X))
+
+#define THUMB1_REG_MODE_OK_FOR_BASE_P(X, MODE) \
+  THUMB1_REGNO_MODE_OK_FOR_BASE_P (REGNO (X), MODE)
 
 #define REG_STRICT_P 1
 
@@ -2043,22 +2077,21 @@ typedef struct
 /* 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)    \
+  (TARGET_THUMB1                               \
+   ? THUMB1_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
+/* For 16-bit 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)
+#define THUMB1_REG_OK_FOR_INDEX_P(X) \
+  THUMB1_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)              \
+  (TARGET_THUMB1                               \
+   ? THUMB1_REG_OK_FOR_INDEX_P (X)             \
    : ARM_REG_OK_FOR_INDEX_P (X))
 
 /* Nonzero if X can be the base register in a reg+reg addressing mode.
@@ -2066,78 +2099,38 @@ typedef struct
 #define REG_MODE_OK_FOR_REG_BASE_P(X, MODE)    \
   REG_OK_FOR_INDEX_P (X)
 \f
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
-   that is a valid memory address for an instruction.
-   The MODE argument is the machine mode for the MEM expression
-   that wants to use this address.  */
-
 #define ARM_BASE_REGISTER_RTX_P(X)  \
   (GET_CODE (X) == REG && ARM_REG_OK_FOR_BASE_P (X))
 
 #define ARM_INDEX_REGISTER_RTX_P(X)  \
   (GET_CODE (X) == REG && ARM_REG_OK_FOR_INDEX_P (X))
-
-#define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE,X,WIN)               \
-  {                                                            \
-    if (arm_legitimate_address_p (MODE, X, SET, REG_STRICT_P)) \
-      goto WIN;                                                        \
-  }
-
-#define THUMB_GO_IF_LEGITIMATE_ADDRESS(MODE,X,WIN)             \
-  {                                                            \
-    if (thumb_legitimate_address_p (MODE, X, REG_STRICT_P))    \
-      goto WIN;                                                        \
-  }
-
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN)                         \
-  if (TARGET_ARM)                                                      \
-    ARM_GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN)                        \
-  else /* if (TARGET_THUMB) */                                         \
-    THUMB_GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN)
-
-\f
-/* Try machine-dependent ways of modifying an illegitimate address
-   to be legitimate.  If we find one, return the new, valid address.  */
-#define ARM_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)     \
-do {                                                   \
-  X = arm_legitimize_address (X, OLDX, MODE);          \
-} while (0)
-
-#define THUMB_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)   \
-do {                                                   \
-  X = thumb_legitimize_address (X, OLDX, MODE);                \
-} while (0)
-
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)         \
-do {                                                   \
-  if (TARGET_ARM)                                      \
-    ARM_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN);       \
-  else                                                 \
-    THUMB_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN);     \
-                                                       \
-  if (memory_address_p (MODE, X))                      \
-    goto WIN;                                          \
-} while (0)
-
-/* Go to LABEL if ADDR (a legitimate address expression)
-   has an effect that depends on the machine mode it is used for.  */
-#define ARM_GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)                          \
-{                                                                      \
-  if (   GET_CODE (ADDR) == PRE_DEC || GET_CODE (ADDR) == POST_DEC     \
-      || GET_CODE (ADDR) == PRE_INC || GET_CODE (ADDR) == POST_INC)    \
-    goto LABEL;                                                                \
-}
-
-/* Nothing helpful to do for the Thumb */
-#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)      \
-  if (TARGET_ARM)                                      \
-    ARM_GO_IF_MODE_DEPENDENT_ADDRESS (ADDR, LABEL)
 \f
+/* Define this for compatibility reasons. */
+#define HANDLE_PRAGMA_PACK_PUSH_POP
 
 /* Specify the machine mode that this machine uses
    for the index in the tablejump instruction.  */
 #define CASE_VECTOR_MODE Pmode
 
+#define CASE_VECTOR_PC_RELATIVE (TARGET_THUMB2                         \
+                                || (TARGET_THUMB1                      \
+                                    && (optimize_size || flag_pic)))
+
+#define CASE_VECTOR_SHORTEN_MODE(min, max, body)                       \
+  (TARGET_THUMB1                                                       \
+   ? (min >= 0 && max < 512                                            \
+      ? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 1, QImode)       \
+      : min >= -256 && max < 256                                       \
+      ? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 0, QImode)       \
+      : min >= 0 && max < 8192                                         \
+      ? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 1, HImode)       \
+      : min >= -4096 && max < 4096                                     \
+      ? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 0, HImode)       \
+      : SImode)                                                                \
+   : ((min < 0 || max >= 0x2000 || !TARGET_THUMB2) ? SImode            \
+      : (max >= 0x200) ? HImode                                                \
+      : QImode))
+
 /* signed 'char' is most compatible, but RISC OS wants it unsigned.
    unsigned is probably best, but may break some code.  */
 #ifndef DEFAULT_SIGNED_CHAR
@@ -2149,7 +2142,7 @@ do {                                                      \
 #define MOVE_MAX 4
 
 #undef  MOVE_RATIO
-#define MOVE_RATIO (arm_tune_xscale ? 4 : 2)
+#define MOVE_RATIO(speed) (arm_tune_xscale ? 4 : 2)
 
 /* Define if operations between registers always perform the operation
    on the full register even if a narrower mode is specified.  */
@@ -2196,14 +2189,14 @@ do {                                                    \
 
 /* Moves to and from memory are quite expensive */
 #define MEMORY_MOVE_COST(M, CLASS, IN)                 \
-  (TARGET_ARM ? 10 :                                   \
+  (TARGET_32BIT ? 10 :                                 \
    ((GET_MODE_SIZE (M) < 4 ? 8 : 2 * GET_MODE_SIZE (M))        \
     * (CLASS == LO_REGS ? 1 : 2)))
 
 /* Try to generate sequences that don't involve branches, we can then use
    conditional instructions */
-#define BRANCH_COST \
-  (TARGET_ARM ? 4 : (optimize > 1 ? 1 : 0))
+#define BRANCH_COST(speed_p, predictable_p) \
+  (TARGET_32BIT ? 4 : (optimize > 0 ? 2 : 0))
 \f
 /* Position Independent Code.  */
 /* We decide which register to use based on the compilation options and
@@ -2233,10 +2226,12 @@ extern unsigned arm_pic_register;
 extern int making_const_table;
 \f
 /* Handle pragmas for compatibility with Intel's compilers.  */
+/* Also abuse this to register additional C specific EABI attributes.  */
 #define REGISTER_TARGET_PRAGMAS() do {                                 \
   c_register_pragma (0, "long_calls", arm_pr_long_calls);              \
   c_register_pragma (0, "no_long_calls", arm_pr_no_long_calls);                \
   c_register_pragma (0, "long_calls_off", arm_pr_long_calls_off);      \
+  arm_lang_object_attributes_init(); \
 } while (0)
 
 /* Condition code information.  */
@@ -2253,58 +2248,83 @@ extern int making_const_table;
    : reverse_condition (code))
 
 #define CANONICALIZE_COMPARISON(CODE, OP0, OP1)                                \
-  do                                                                   \
-    {                                                                  \
-      if (GET_CODE (OP1) == CONST_INT                                  \
-          && ! (const_ok_for_arm (INTVAL (OP1))                                \
-               || (const_ok_for_arm (- INTVAL (OP1)))))                \
-        {                                                              \
-          rtx const_op = OP1;                                          \
-          CODE = arm_canonicalize_comparison ((CODE), GET_MODE (OP0),  \
-                                             &const_op);               \
-          OP1 = const_op;                                              \
-        }                                                              \
-    }                                                                  \
-  while (0)
+  (CODE) = arm_canonicalize_comparison (CODE, &(OP0), &(OP1))
 
 /* The arm5 clz instruction returns 32.  */
 #define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE)  ((VALUE) = 32, 1)
+#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE)  ((VALUE) = 32, 1)
 \f
-#undef  ASM_APP_OFF
-#define ASM_APP_OFF (TARGET_THUMB ? "\t.code\t16\n" : "")
+#define CC_STATUS_INIT \
+  do { cfun->machine->thumb1_cc_insn = NULL_RTX; } while (0)
 
-/* Output a push or a pop instruction (only used when profiling).  */
+#undef  ASM_APP_OFF
+#define ASM_APP_OFF (TARGET_THUMB1 ? "\t.code\t16\n" : \
+                    TARGET_THUMB2 ? "\t.thumb\n" : "")
+
+/* Output a push or a pop instruction (only used when profiling).
+   We can't push STATIC_CHAIN_REGNUM (r12) directly with Thumb-1.  We know
+   that ASM_OUTPUT_REG_PUSH will be matched with ASM_OUTPUT_REG_POP, and
+   that r7 isn't used by the function profiler, so we can use it as a
+   scratch reg.  WARNING: This isn't safe in the general case!  It may be
+   sensitive to future changes in final.c:profile_function.  */
 #define ASM_OUTPUT_REG_PUSH(STREAM, REGNO)             \
   do                                                   \
     {                                                  \
       if (TARGET_ARM)                                  \
        asm_fprintf (STREAM,"\tstmfd\t%r!,{%r}\n",      \
                     STACK_POINTER_REGNUM, REGNO);      \
+      else if (TARGET_THUMB1                           \
+              && (REGNO) == STATIC_CHAIN_REGNUM)       \
+       {                                               \
+         asm_fprintf (STREAM, "\tpush\t{r7}\n");       \
+         asm_fprintf (STREAM, "\tmov\tr7, %r\n", REGNO);\
+         asm_fprintf (STREAM, "\tpush\t{r7}\n");       \
+       }                                               \
       else                                             \
        asm_fprintf (STREAM, "\tpush {%r}\n", REGNO);   \
     } while (0)
 
 
+/* See comment for ASM_OUTPUT_REG_PUSH concerning Thumb-1 issue.  */
 #define ASM_OUTPUT_REG_POP(STREAM, REGNO)              \
   do                                                   \
     {                                                  \
       if (TARGET_ARM)                                  \
        asm_fprintf (STREAM, "\tldmfd\t%r!,{%r}\n",     \
                     STACK_POINTER_REGNUM, REGNO);      \
+      else if (TARGET_THUMB1                           \
+              && (REGNO) == STATIC_CHAIN_REGNUM)       \
+       {                                               \
+         asm_fprintf (STREAM, "\tpop\t{r7}\n");        \
+         asm_fprintf (STREAM, "\tmov\t%r, r7\n", REGNO);\
+         asm_fprintf (STREAM, "\tpop\t{r7}\n");        \
+       }                                               \
       else                                             \
        asm_fprintf (STREAM, "\tpop {%r}\n", REGNO);    \
     } while (0)
 
+/* Jump table alignment is explicit in ASM_OUTPUT_CASE_LABEL.  */
+#define ADDR_VEC_ALIGN(JUMPTABLE) 0
+
 /* 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                                                           \
-    {                                                          \
-      if (TARGET_THUMB)                                                \
-        ASM_OUTPUT_ALIGN (FILE, 2);                            \
-      (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM);   \
-    }                                                          \
+#define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, JUMPTABLE)            \
+  do                                                                   \
+    {                                                                  \
+      if (TARGET_THUMB && GET_MODE (PATTERN (JUMPTABLE)) == SImode)    \
+        ASM_OUTPUT_ALIGN (FILE, 2);                                    \
+      (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM);           \
+    }                                                                  \
+  while (0)
+
+/* Make sure subsequent insns are aligned after a TBB.  */
+#define ASM_OUTPUT_CASE_END(FILE, NUM, JUMPTABLE)      \
+  do                                                   \
+    {                                                  \
+      if (GET_MODE (PATTERN (JUMPTABLE)) == QImode)    \
+       ASM_OUTPUT_ALIGN (FILE, 1);                     \
+    }                                                  \
   while (0)
 
 #define ARM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL)  \
@@ -2312,14 +2332,17 @@ extern int making_const_table;
     {                                                  \
       if (TARGET_THUMB)                                \
         {                                              \
-          if (is_called_in_ARM_mode (DECL)      \
-                         || current_function_is_thunk)         \
+          if (is_called_in_ARM_mode (DECL)             \
+             || (TARGET_THUMB1 && !TARGET_THUMB1_ONLY  \
+                 && cfun->is_thunk))   \
             fprintf (STREAM, "\t.code 32\n") ;         \
+          else if (TARGET_THUMB1)                      \
+           fprintf (STREAM, "\t.code\t16\n\t.thumb_func\n") ;  \
           else                                         \
-           fprintf (STREAM, "\t.code 16\n\t.thumb_func\n") ;   \
+           fprintf (STREAM, "\t.thumb\n\t.thumb_func\n") ;     \
         }                                              \
       if (TARGET_POKE_FUNCTION_NAME)                   \
-        arm_poke_function_name (STREAM, (char *) NAME);        \
+        arm_poke_function_name (STREAM, (const char *) NAME);  \
     }                                                  \
   while (0)
 
@@ -2358,22 +2381,22 @@ extern int making_const_table;
     }
 #endif
 \f
+/* Add two bytes to the length of conditionally executed Thumb-2
+   instructions for the IT instruction.  */
+#define ADJUST_INSN_LENGTH(insn, length) \
+  if (TARGET_THUMB2 && GET_CODE (PATTERN (insn)) == COND_EXEC) \
+    length += 2;
+
 /* Only perform branch elimination (by making instructions conditional) if
-   we're optimizing.  Otherwise it's of no use anyway.  */
+   we're optimizing.  For Thumb-2 check if any IT instructions need
+   outputting.  */
 #define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS)     \
   if (TARGET_ARM && optimize)                          \
     arm_final_prescan_insn (INSN);                     \
-  else if (TARGET_THUMB)                               \
-    thumb_final_prescan_insn (INSN)
-
-#define PRINT_OPERAND_PUNCT_VALID_P(CODE)      \
-  (CODE == '@' || CODE == '|'                  \
-   || (TARGET_ARM   && (CODE == '?'))          \
-   || (TARGET_THUMB && (CODE == '_')))
-
-/* Output an operand of an instruction.  */
-#define PRINT_OPERAND(STREAM, X, CODE)  \
-  arm_print_operand (STREAM, X, CODE)
+  else if (TARGET_THUMB2)                              \
+    thumb2_final_prescan_insn (INSN);                  \
+  else if (TARGET_THUMB1)                              \
+    thumb1_final_prescan_insn (INSN)
 
 #define ARM_SIGN_EXTEND(x)  ((HOST_WIDE_INT)                   \
   (HOST_BITS_PER_WIDE_INT <= 32 ? (unsigned HOST_WIDE_INT) (x) \
@@ -2383,133 +2406,6 @@ extern int making_const_table;
          & ~ (unsigned HOST_WIDE_INT) 0xffffffff)              \
        : 0))))
 
-/* Output the address of an operand.  */
-#define ARM_PRINT_OPERAND_ADDRESS(STREAM, X)                           \
-{                                                                      \
-    int is_minus = GET_CODE (X) == MINUS;                              \
-                                                                       \
-    if (GET_CODE (X) == REG)                                           \
-      asm_fprintf (STREAM, "[%r, #0]", REGNO (X));                     \
-    else if (GET_CODE (X) == PLUS || is_minus)                         \
-      {                                                                        \
-       rtx base = XEXP (X, 0);                                         \
-       rtx index = XEXP (X, 1);                                        \
-       HOST_WIDE_INT offset = 0;                                       \
-       if (GET_CODE (base) != REG)                                     \
-         {                                                             \
-           /* Ensure that BASE is a register.  */                      \
-            /* (one of them must be).  */                              \
-           rtx temp = base;                                            \
-           base = index;                                               \
-           index = temp;                                               \
-         }                                                             \
-       switch (GET_CODE (index))                                       \
-         {                                                             \
-         case CONST_INT:                                               \
-           offset = INTVAL (index);                                    \
-           if (is_minus)                                               \
-             offset = -offset;                                         \
-           asm_fprintf (STREAM, "[%r, #%wd]",                          \
-                        REGNO (base), offset);                         \
-           break;                                                      \
-                                                                       \
-         case REG:                                                     \
-           asm_fprintf (STREAM, "[%r, %s%r]",                          \
-                    REGNO (base), is_minus ? "-" : "",                 \
-                    REGNO (index));                                    \
-           break;                                                      \
-                                                                       \
-         case MULT:                                                    \
-         case ASHIFTRT:                                                \
-         case LSHIFTRT:                                                \
-         case ASHIFT:                                                  \
-         case ROTATERT:                                                \
-         {                                                             \
-           asm_fprintf (STREAM, "[%r, %s%r",                           \
-                        REGNO (base), is_minus ? "-" : "",             \
-                         REGNO (XEXP (index, 0)));                     \
-           arm_print_operand (STREAM, index, 'S');                     \
-           fputs ("]", STREAM);                                        \
-           break;                                                      \
-         }                                                             \
-                                                                       \
-         default:                                                      \
-           gcc_unreachable ();                                         \
-       }                                                               \
-    }                                                                  \
-  else if (GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_INC         \
-          || GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_DEC)      \
-    {                                                                  \
-      extern enum machine_mode output_memory_reference_mode;           \
-                                                                       \
-      gcc_assert (GET_CODE (XEXP (X, 0)) == REG);                      \
-                                                                       \
-      if (GET_CODE (X) == PRE_DEC || GET_CODE (X) == PRE_INC)          \
-       asm_fprintf (STREAM, "[%r, #%s%d]!",                            \
-                    REGNO (XEXP (X, 0)),                               \
-                    GET_CODE (X) == PRE_DEC ? "-" : "",                \
-                    GET_MODE_SIZE (output_memory_reference_mode));     \
-      else                                                             \
-       asm_fprintf (STREAM, "[%r], #%s%d",                             \
-                    REGNO (XEXP (X, 0)),                               \
-                    GET_CODE (X) == POST_DEC ? "-" : "",               \
-                    GET_MODE_SIZE (output_memory_reference_mode));     \
-    }                                                                  \
-  else if (GET_CODE (X) == PRE_MODIFY)                                 \
-    {                                                                  \
-      asm_fprintf (STREAM, "[%r, ", REGNO (XEXP (X, 0)));              \
-      if (GET_CODE (XEXP (XEXP (X, 1), 1)) == CONST_INT)               \
-       asm_fprintf (STREAM, "#%wd]!",                                  \
-                    INTVAL (XEXP (XEXP (X, 1), 1)));                   \
-      else                                                             \
-       asm_fprintf (STREAM, "%r]!",                                    \
-                    REGNO (XEXP (XEXP (X, 1), 1)));                    \
-    }                                                                  \
-  else if (GET_CODE (X) == POST_MODIFY)                                        \
-    {                                                                  \
-      asm_fprintf (STREAM, "[%r], ", REGNO (XEXP (X, 0)));             \
-      if (GET_CODE (XEXP (XEXP (X, 1), 1)) == CONST_INT)               \
-       asm_fprintf (STREAM, "#%wd",                                    \
-                    INTVAL (XEXP (XEXP (X, 1), 1)));                   \
-      else                                                             \
-       asm_fprintf (STREAM, "%r",                                      \
-                    REGNO (XEXP (XEXP (X, 1), 1)));                    \
-    }                                                                  \
-  else output_addr_const (STREAM, X);                                  \
-}
-
-#define THUMB_PRINT_OPERAND_ADDRESS(STREAM, X)         \
-{                                                      \
-  if (GET_CODE (X) == REG)                             \
-    asm_fprintf (STREAM, "[%r]", REGNO (X));           \
-  else if (GET_CODE (X) == POST_INC)                   \
-    asm_fprintf (STREAM, "%r!", REGNO (XEXP (X, 0)));  \
-  else if (GET_CODE (X) == PLUS)                       \
-    {                                                  \
-      gcc_assert (GET_CODE (XEXP (X, 0)) == REG);      \
-      if (GET_CODE (XEXP (X, 1)) == CONST_INT)         \
-       asm_fprintf (STREAM, "[%r, #%wd]",              \
-                    REGNO (XEXP (X, 0)),               \
-                    INTVAL (XEXP (X, 1)));             \
-      else                                             \
-       asm_fprintf (STREAM, "[%r, %r]",                \
-                    REGNO (XEXP (X, 0)),               \
-                    REGNO (XEXP (X, 1)));              \
-    }                                                  \
-  else                                                 \
-    output_addr_const (STREAM, X);                     \
-}
-
-#define PRINT_OPERAND_ADDRESS(STREAM, X)       \
-  if (TARGET_ARM)                              \
-    ARM_PRINT_OPERAND_ADDRESS (STREAM, X)      \
-  else                                         \
-    THUMB_PRINT_OPERAND_ADDRESS (STREAM, X)
-
-#define OUTPUT_ADDR_CONST_EXTRA(file, x, fail)         \
-  if (arm_output_addr_const_extra (file, x) == FALSE)  \
-    goto fail
-
 /* A C expression whose value is RTL representing the value of the return
    address for the frame COUNT steps up from the current frame.  */
 
@@ -2538,6 +2434,9 @@ extern int making_const_table;
    : arm_gen_return_addr_mask ())
 
 \f
+/* Neon defines builtins from ARM_BUILTIN_MAX upwards, though they don't have
+   symbolic names defined here (which would require too much duplication).
+   FIXME?  */
 enum arm_builtins
 {
   ARM_BUILTIN_GETWCX,
@@ -2702,6 +2601,18 @@ enum arm_builtins
 
   ARM_BUILTIN_THREAD_POINTER,
 
-  ARM_BUILTIN_MAX
+  ARM_BUILTIN_NEON_BASE,
+
+  ARM_BUILTIN_MAX = ARM_BUILTIN_NEON_BASE  /* FIXME: Wrong!  */
 };
+
+/* Do not emit .note.GNU-stack by default.  */
+#ifndef NEED_INDICATE_EXEC_STACK
+#define NEED_INDICATE_EXEC_STACK       0
+#endif
+
+/* The maximum number of parallel loads or stores we support in an ldm/stm
+   instruction.  */
+#define MAX_LDM_STM_OPS 4
+
 #endif /* ! GCC_ARM_H */