OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / config / arm / arm.h
index cad50a8..4332394 100644 (file)
@@ -1,6 +1,6 @@
 /* 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, 2007, 2008, 2009
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
    Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
    and Martin Simmons (@harleqn.co.uk).
@@ -94,19 +94,16 @@ 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.  */
-enum processor_type
-{
-#define ARM_CORE(NAME, IDENT, ARCH, FLAGS, COSTS) \
-  IDENT,
-#include "arm-cores.def"
-#undef ARM_CORE
-  /* Used to indicate that no processor has been specified.  */
-  arm_none
-};
+#include "config/arm/arm-opts.h"
 
 enum target_cpus
 {
@@ -120,6 +117,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,
@@ -150,8 +165,8 @@ extern void (*arm_lang_output_object_attributes_hook)(void);
 
 #undef  CPP_SPEC
 #define CPP_SPEC "%(subtarget_cpp_spec)                                        \
-%{msoft-float:%{mhard-float:                                           \
-       %e-msoft-float and -mhard_float may not be used together}}      \
+%{mfloat-abi=soft:%{mfloat-abi=hard:                                   \
+       %e-mfloat-abi=soft and -mfloat-abi=hard may not be used together}} \
 %{mbig-endian:%{mlittle-endian:                                                \
        %e-mbig-endian and -mlittle-endian may not be used together}}"
 
@@ -181,10 +196,6 @@ extern void (*arm_lang_output_object_attributes_hook)(void);
 #endif
 \f
 /* Run-time Target Specification.  */
-#ifndef TARGET_VERSION
-#define TARGET_VERSION fputs (" (ARM/generic)", stderr);
-#endif
-
 #define TARGET_SOFT_FLOAT              (arm_float_abi == ARM_FLOAT_ABI_SOFT)
 /* Use hardware floating point instructions. */
 #define TARGET_HARD_FLOAT              (arm_float_abi != ARM_FLOAT_ABI_SOFT)
@@ -264,6 +275,20 @@ extern void (*arm_lang_output_object_attributes_hook)(void);
    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
@@ -279,16 +304,14 @@ extern void (*arm_lang_output_object_attributes_hook)(void);
     by --with-arch.
    --with-tune is ignored if -mtune or -mcpu are specified (but not affected
      by -march).
-   --with-float is ignored if -mhard-float, -msoft-float or -mfloat-abi are
-   specified.
+   --with-float is ignored if -mfloat-abi is specified.
    --with-fpu is ignored if -mfpu is specified.
    --with-abi is ignored is -mabi is specified.  */
 #define OPTION_DEFAULT_SPECS \
   {"arch", "%{!march=*:%{!mcpu=*:-march=%(VALUE)}}" }, \
   {"cpu", "%{!march=*:%{!mcpu=*:-mcpu=%(VALUE)}}" }, \
   {"tune", "%{!mcpu=*:%{!mtune=*:-mtune=%(VALUE)}}" }, \
-  {"float", \
-    "%{!msoft-float:%{!mhard-float:%{!mfloat-abi=*:-mfloat-abi=%(VALUE)}}}" }, \
+  {"float", "%{!mfloat-abi=*:-mfloat-abi=%(VALUE)}" }, \
   {"fpu", "%{!mfpu=*:-mfpu=%(VALUE)}"}, \
   {"abi", "%{!mabi=*:-mabi=%(VALUE)}"}, \
   {"mode", "%{!marm:%{!mthumb:-m%(VALUE)}}"},
@@ -397,6 +420,12 @@ 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;
 
@@ -406,9 +435,12 @@ 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;
 
@@ -447,15 +479,6 @@ extern int arm_arch_hwdiv;
 #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 ()
-
-#define OPTIMIZATION_OPTIONS(LEVEL,SIZE)               \
-       arm_optimization_options ((LEVEL), (SIZE))
-
 /* 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.  */
@@ -518,14 +541,6 @@ extern int arm_arch_hwdiv;
    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.  */
@@ -533,12 +548,6 @@ extern int arm_arch_hwdiv;
 
 #define UNITS_PER_WORD 4
 
-/* Use the option -mvectorize-with-neon-quad to override the use of doubleword
-   registers when autovectorizing for Neon, at least until multiple vector
-   widths are supported properly by the middle-end.  */
-#define UNITS_PER_SIMD_WORD(MODE) \
-  (TARGET_NEON ? (TARGET_NEON_VECTORIZE_QUAD ? 16 : 8) : UNITS_PER_WORD)
-
 /* True if natural alignment is used for doubleword types.  */
 #define ARM_DOUBLEWORD_ALIGN   TARGET_AAPCS_BASED
 
@@ -581,15 +590,21 @@ extern int arm_arch_hwdiv;
 /* 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.  */
-#define DATA_ALIGNMENT(EXP, ALIGN)                                     \
-  ((((ALIGN) < BITS_PER_WORD)                                           \
+   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) DATA_ALIGNMENT(EXP, ALIGN)
+#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
@@ -668,7 +683,7 @@ extern int arm_structure_size_boundary;
                        elimination code won't get rid of sfp.  It tracks
                        fp exactly at all times.
 
-   *: See CONDITIONAL_REGISTER_USAGE  */
+   *: See TARGET_CONDITIONAL_REGISTER_USAGE  */
 
 /*
        mvf0            Cirrus floating point result
@@ -760,107 +775,6 @@ extern int arm_structure_size_boundary;
 #define SUBTARGET_CONDITIONAL_REGISTER_USAGE
 #endif
 
-#define CONDITIONAL_REGISTER_USAGE                             \
-{                                                              \
-  int regno;                                                   \
-                                                               \
-  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_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;          \
-    }                                                          \
-                                                               \
-  /* 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_THUMB1)                                           \
-    fixed_regs[LR_REGNUM] = call_used_regs[LR_REGNUM] = 1;     \
-                                                               \
-  if (TARGET_32BIT && TARGET_HARD_FLOAT)                       \
-    {                                                          \
-      if (TARGET_MAVERICK)                                     \
-       {                                                       \
-         for (regno = FIRST_FPA_REGNUM;                        \
-              regno <= LAST_FPA_REGNUM; ++ regno)              \
-           fixed_regs[regno] = call_used_regs[regno] = 1;      \
-         for (regno = FIRST_CIRRUS_FP_REGNUM;                  \
-              regno <= LAST_CIRRUS_FP_REGNUM; ++ regno)        \
-           {                                                   \
-             fixed_regs[regno] = 0;                            \
-             call_used_regs[regno] = regno < FIRST_CIRRUS_FP_REGNUM + 4; \
-           }                                                   \
-       }                                                       \
-      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 \
-               || regno >= FIRST_VFP_REGNUM + 32;              \
-           }                                                   \
-       }                                                       \
-    }                                                          \
-                                                               \
-  if (TARGET_REALLY_IWMMXT)                                    \
-    {                                                          \
-      regno = FIRST_IWMMXT_GR_REGNUM;                          \
-      /* The 2002/10/09 revision of the XScale ABI has wCG0     \
-         and wCG1 as call-preserved registers.  The 2002/11/21  \
-         revision changed this so that all wCG registers are    \
-         scratch registers.  */                                        \
-      for (regno = FIRST_IWMMXT_GR_REGNUM;                     \
-          regno <= LAST_IWMMXT_GR_REGNUM; ++ regno)            \
-       fixed_regs[regno] = 0;                                  \
-      /* The XScale ABI has wR0 - wR9 as scratch registers,     \
-        the rest as call-preserved registers.  */              \
-      for (regno = FIRST_IWMMXT_REGNUM;                                \
-          regno <= LAST_IWMMXT_REGNUM; ++ regno)               \
-       {                                                       \
-         fixed_regs[regno] = 0;                                \
-         call_used_regs[regno] = regno < FIRST_IWMMXT_REGNUM + 10; \
-       }                                                       \
-    }                                                          \
-                                                               \
-  if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)    \
-    {                                                          \
-      fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;                 \
-      call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;             \
-    }                                                          \
-  else if (TARGET_APCS_STACK)                                  \
-    {                                                          \
-      fixed_regs[10]     = 1;                                  \
-      call_used_regs[10] = 1;                                  \
-    }                                                          \
-  /* -mcaller-super-interworking reserves r11 for calls to     \
-     _interwork_r11_call_via_rN().  Making the register global \
-     is an easy way of ensuring that it remains valid for all  \
-     calls.  */                                                        \
-  if (TARGET_APCS_FRAME || TARGET_CALLER_INTERWORKING          \
-      || TARGET_TPCS_FRAME || TARGET_TPCS_LEAF_FRAME)          \
-    {                                                          \
-      fixed_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1;           \
-      call_used_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1;       \
-      if (TARGET_CALLER_INTERWORKING)                          \
-       global_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1;         \
-    }                                                          \
-  SUBTARGET_CONDITIONAL_REGISTER_USAGE                         \
-}
-
 /* These are a couple of extensions to the formats accepted
    by asm_fprintf:
      %@ prints out ASM_COMMENT_START
@@ -912,14 +826,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)
 
@@ -956,6 +867,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.  */
@@ -1087,6 +1001,9 @@ extern int arm_structure_size_boundary;
   ((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
@@ -1206,8 +1123,8 @@ enum reg_class
   { 0x0000DF00, 0x00000000, 0x00000000, 0x00000000 }, /* HI_REGS */    \
   { 0x01000000, 0x00000000, 0x00000000, 0x00000000 }, /* CC_REG */     \
   { 0x00000000, 0x00000000, 0x00000000, 0x80000000 }, /* VFPCC_REG */  \
-  { 0x0200DFFF, 0x00000000, 0x00000000, 0x00000000 }, /* GENERAL_REGS */ \
-  { 0x0200FFFF, 0x00000000, 0x00000000, 0x00000000 }, /* CORE_REGS */  \
+  { 0x0000DFFF, 0x00000000, 0x00000000, 0x00000000 }, /* GENERAL_REGS */ \
+  { 0x0000FFFF, 0x00000000, 0x00000000, 0x00000000 }, /* CORE_REGS */  \
   { 0xFAFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF }  /* ALL_REGS */   \
 }
 
@@ -1222,36 +1139,15 @@ enum reg_class
    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.  */
-#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)      \
-  (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)          \
-   ? reg_classes_intersect_p (FPA_REGS, (CLASS))       \
-     || reg_classes_intersect_p (VFP_REGS, (CLASS))    \
+   precision.  In VFPv1, VFP registers could only be accessed in the mode
+   they were set, so subregs would be invalid there too.  However, we don't
+   support VFPv1 at the moment, and the restriction was lifted in VFPv2.  */
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)              \
+  (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)                  \
+   ? reg_classes_intersect_p (FPA_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_THUMB1 ? LO_REGS : GENERAL_REGS)
 #define BASE_REG_CLASS   (TARGET_THUMB1 ? LO_REGS : CORE_REGS)
@@ -1260,7 +1156,7 @@ enum reg_class
    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_32BIT ? CORE_REGS :                                        \
+    (TARGET_ARM || (TARGET_THUMB2 && !optimize_size) ? CORE_REGS :      \
      (((MODE) == SImode) ? BASE_REGS : LO_REGS))
 
 /* For Thumb we can not support SP+reg addressing, so we return LO_REGS
@@ -1348,53 +1244,8 @@ enum reg_class
 #define ARM_LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND, WIN)     \
   do                                                                      \
     {                                                                     \
-      if (GET_CODE (X) == PLUS                                            \
-         && GET_CODE (XEXP (X, 0)) == REG                                 \
-         && REGNO (XEXP (X, 0)) < FIRST_PSEUDO_REGISTER                   \
-         && REG_MODE_OK_FOR_BASE_P (XEXP (X, 0), MODE)                    \
-         && GET_CODE (XEXP (X, 1)) == CONST_INT)                          \
-       {                                                                  \
-         HOST_WIDE_INT val = INTVAL (XEXP (X, 1));                        \
-         HOST_WIDE_INT low, high;                                         \
-                                                                          \
-         if (MODE == DImode || (MODE == DFmode && TARGET_SOFT_FLOAT))     \
-           low = ((val & 0xf) ^ 0x8) - 0x8;                               \
-         else if (TARGET_MAVERICK && TARGET_HARD_FLOAT)                   \
-           /* Need to be careful, -256 is not a valid offset.  */         \
-           low = val >= 0 ? (val & 0xff) : -((-val) & 0xff);              \
-         else if (MODE == SImode                                          \
-                  || (MODE == SFmode && TARGET_SOFT_FLOAT)                \
-                  || ((MODE == HImode || MODE == QImode) && ! arm_arch4)) \
-           /* Need to be careful, -4096 is not a valid offset.  */        \
-           low = val >= 0 ? (val & 0xfff) : -((-val) & 0xfff);            \
-         else if ((MODE == HImode || MODE == QImode) && arm_arch4)        \
-           /* Need to be careful, -256 is not a valid offset.  */         \
-           low = val >= 0 ? (val & 0xff) : -((-val) & 0xff);              \
-         else if (GET_MODE_CLASS (MODE) == MODE_FLOAT                     \
-                  && TARGET_HARD_FLOAT && TARGET_FPA)                     \
-           /* Need to be careful, -1024 is not a valid offset.  */        \
-           low = val >= 0 ? (val & 0x3ff) : -((-val) & 0x3ff);            \
-         else                                                             \
-           break;                                                         \
-                                                                          \
-         high = ((((val - low) & (unsigned HOST_WIDE_INT) 0xffffffff)     \
-                  ^ (unsigned HOST_WIDE_INT) 0x80000000)                  \
-                 - (unsigned HOST_WIDE_INT) 0x80000000);                  \
-         /* Check for overflow or zero */                                 \
-         if (low == 0 || high == 0 || (high + low != val))                \
-           break;                                                         \
-                                                                          \
-         /* Reload the high part into a base reg; leave the low part      \
-            in the mem.  */                                               \
-         X = gen_rtx_PLUS (GET_MODE (X),                                  \
-                           gen_rtx_PLUS (GET_MODE (X), XEXP (X, 0),       \
-                                         GEN_INT (high)),                 \
-                           GEN_INT (low));                                \
-         push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL,          \
-                      MODE_BASE_REG_CLASS (MODE), GET_MODE (X),           \
-                      VOIDmode, 0, 0, OPNUM, TYPE);                       \
-         goto WIN;                                                        \
-       }                                                                  \
+      if (arm_legitimize_reload_address (&X, MODE, OPNUM, TYPE, IND))     \
+       goto WIN;                                                          \
     }                                                                     \
   while (0)
 
@@ -1587,6 +1438,7 @@ typedef struct GTY(()) arm_stack_offsets
 }
 arm_stack_offsets;
 
+#ifndef GENERATOR_FILE
 /* A C structure for machine-specific, per-function data.
    This is added to the cfun structure.  */
 typedef struct GTY(()) machine_function
@@ -1617,8 +1469,16 @@ typedef struct GTY(()) machine_function
   /* 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.  */
@@ -1641,6 +1501,9 @@ enum arm_pcs
   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.  */
 typedef struct
@@ -1675,27 +1538,6 @@ typedef struct
   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)
 
@@ -1714,20 +1556,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)   \
-  arm_function_arg_advance (&(CUM), (MODE), (TYPE), (NAMED))
-
-/* 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.  */
-#define FUNCTION_ARG_BOUNDARY(MODE,TYPE) \
-   ((ARM_DOUBLEWORD_ALIGN && arm_needs_doubleword_align (MODE, TYPE)) \
-   ? DOUBLEWORD_ALIGNMENT \
-   : PARM_BOUNDARY )
-
 /* 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)                                    \
@@ -1918,27 +1746,6 @@ typedef struct
 #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.
-
-   On the ARM, allow any integer (invalid ones are removed later by insn
-   patterns), nice doubles and symbol_refs which refer to the function's
-   constant pool XXX.
-
-   When generating pic allow anything.  */
-#define ARM_LEGITIMATE_CONSTANT_P(X)   (flag_pic || ! label_mentioned_p (X))
-
-#define THUMB_LEGITIMATE_CONSTANT_P(X) \
- (   GET_CODE (X) == CONST_INT         \
-  || GET_CODE (X) == CONST_DOUBLE      \
-  || CONSTANT_ADDRESS_P (X)            \
-  || flag_pic)
-
-#define LEGITIMATE_CONSTANT_P(X)                       \
-  (!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
 #endif
@@ -2016,13 +1823,6 @@ typedef struct
 
 #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.
@@ -2101,9 +1901,6 @@ typedef struct
 #define ARM_INDEX_REGISTER_RTX_P(X)  \
   (GET_CODE (X) == REG && ARM_REG_OK_FOR_INDEX_P (X))
 \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
@@ -2192,7 +1989,8 @@ typedef struct
 /* Try to generate sequences that don't involve branches, we can then use
    conditional instructions */
 #define BRANCH_COST(speed_p, predictable_p) \
-  (TARGET_32BIT ? 4 : (optimize > 0 ? 2 : 0))
+  (TARGET_32BIT ? (TARGET_THUMB2 && !speed_p ? 1 : 4) \
+               : (optimize > 0 ? 2 : 0))
 \f
 /* Position Independent Code.  */
 /* We decide which register to use based on the compilation options and
@@ -2250,6 +2048,9 @@ extern int making_const_table;
 #define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE)  ((VALUE) = 32, 1)
 #define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE)  ((VALUE) = 32, 1)
 \f
+#define CC_STATUS_INIT \
+  do { cfun->machine->thumb1_cc_insn = NULL_RTX; } while (0)
+
 #undef  ASM_APP_OFF
 #define ASM_APP_OFF (TARGET_THUMB1 ? "\t.code\t16\n" : \
                     TARGET_THUMB2 ? "\t.thumb\n" : "")
@@ -2399,10 +2200,6 @@ extern int making_const_table;
          & ~ (unsigned HOST_WIDE_INT) 0xffffffff)              \
        : 0))))
 
-#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.  */
 
@@ -2431,178 +2228,6 @@ 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,
-  ARM_BUILTIN_SETWCX,
-
-  ARM_BUILTIN_WZERO,
-
-  ARM_BUILTIN_WAVG2BR,
-  ARM_BUILTIN_WAVG2HR,
-  ARM_BUILTIN_WAVG2B,
-  ARM_BUILTIN_WAVG2H,
-
-  ARM_BUILTIN_WACCB,
-  ARM_BUILTIN_WACCH,
-  ARM_BUILTIN_WACCW,
-
-  ARM_BUILTIN_WMACS,
-  ARM_BUILTIN_WMACSZ,
-  ARM_BUILTIN_WMACU,
-  ARM_BUILTIN_WMACUZ,
-
-  ARM_BUILTIN_WSADB,
-  ARM_BUILTIN_WSADBZ,
-  ARM_BUILTIN_WSADH,
-  ARM_BUILTIN_WSADHZ,
-
-  ARM_BUILTIN_WALIGN,
-
-  ARM_BUILTIN_TMIA,
-  ARM_BUILTIN_TMIAPH,
-  ARM_BUILTIN_TMIABB,
-  ARM_BUILTIN_TMIABT,
-  ARM_BUILTIN_TMIATB,
-  ARM_BUILTIN_TMIATT,
-
-  ARM_BUILTIN_TMOVMSKB,
-  ARM_BUILTIN_TMOVMSKH,
-  ARM_BUILTIN_TMOVMSKW,
-
-  ARM_BUILTIN_TBCSTB,
-  ARM_BUILTIN_TBCSTH,
-  ARM_BUILTIN_TBCSTW,
-
-  ARM_BUILTIN_WMADDS,
-  ARM_BUILTIN_WMADDU,
-
-  ARM_BUILTIN_WPACKHSS,
-  ARM_BUILTIN_WPACKWSS,
-  ARM_BUILTIN_WPACKDSS,
-  ARM_BUILTIN_WPACKHUS,
-  ARM_BUILTIN_WPACKWUS,
-  ARM_BUILTIN_WPACKDUS,
-
-  ARM_BUILTIN_WADDB,
-  ARM_BUILTIN_WADDH,
-  ARM_BUILTIN_WADDW,
-  ARM_BUILTIN_WADDSSB,
-  ARM_BUILTIN_WADDSSH,
-  ARM_BUILTIN_WADDSSW,
-  ARM_BUILTIN_WADDUSB,
-  ARM_BUILTIN_WADDUSH,
-  ARM_BUILTIN_WADDUSW,
-  ARM_BUILTIN_WSUBB,
-  ARM_BUILTIN_WSUBH,
-  ARM_BUILTIN_WSUBW,
-  ARM_BUILTIN_WSUBSSB,
-  ARM_BUILTIN_WSUBSSH,
-  ARM_BUILTIN_WSUBSSW,
-  ARM_BUILTIN_WSUBUSB,
-  ARM_BUILTIN_WSUBUSH,
-  ARM_BUILTIN_WSUBUSW,
-
-  ARM_BUILTIN_WAND,
-  ARM_BUILTIN_WANDN,
-  ARM_BUILTIN_WOR,
-  ARM_BUILTIN_WXOR,
-
-  ARM_BUILTIN_WCMPEQB,
-  ARM_BUILTIN_WCMPEQH,
-  ARM_BUILTIN_WCMPEQW,
-  ARM_BUILTIN_WCMPGTUB,
-  ARM_BUILTIN_WCMPGTUH,
-  ARM_BUILTIN_WCMPGTUW,
-  ARM_BUILTIN_WCMPGTSB,
-  ARM_BUILTIN_WCMPGTSH,
-  ARM_BUILTIN_WCMPGTSW,
-
-  ARM_BUILTIN_TEXTRMSB,
-  ARM_BUILTIN_TEXTRMSH,
-  ARM_BUILTIN_TEXTRMSW,
-  ARM_BUILTIN_TEXTRMUB,
-  ARM_BUILTIN_TEXTRMUH,
-  ARM_BUILTIN_TEXTRMUW,
-  ARM_BUILTIN_TINSRB,
-  ARM_BUILTIN_TINSRH,
-  ARM_BUILTIN_TINSRW,
-
-  ARM_BUILTIN_WMAXSW,
-  ARM_BUILTIN_WMAXSH,
-  ARM_BUILTIN_WMAXSB,
-  ARM_BUILTIN_WMAXUW,
-  ARM_BUILTIN_WMAXUH,
-  ARM_BUILTIN_WMAXUB,
-  ARM_BUILTIN_WMINSW,
-  ARM_BUILTIN_WMINSH,
-  ARM_BUILTIN_WMINSB,
-  ARM_BUILTIN_WMINUW,
-  ARM_BUILTIN_WMINUH,
-  ARM_BUILTIN_WMINUB,
-
-  ARM_BUILTIN_WMULUM,
-  ARM_BUILTIN_WMULSM,
-  ARM_BUILTIN_WMULUL,
-
-  ARM_BUILTIN_PSADBH,
-  ARM_BUILTIN_WSHUFH,
-
-  ARM_BUILTIN_WSLLH,
-  ARM_BUILTIN_WSLLW,
-  ARM_BUILTIN_WSLLD,
-  ARM_BUILTIN_WSRAH,
-  ARM_BUILTIN_WSRAW,
-  ARM_BUILTIN_WSRAD,
-  ARM_BUILTIN_WSRLH,
-  ARM_BUILTIN_WSRLW,
-  ARM_BUILTIN_WSRLD,
-  ARM_BUILTIN_WRORH,
-  ARM_BUILTIN_WRORW,
-  ARM_BUILTIN_WRORD,
-  ARM_BUILTIN_WSLLHI,
-  ARM_BUILTIN_WSLLWI,
-  ARM_BUILTIN_WSLLDI,
-  ARM_BUILTIN_WSRAHI,
-  ARM_BUILTIN_WSRAWI,
-  ARM_BUILTIN_WSRADI,
-  ARM_BUILTIN_WSRLHI,
-  ARM_BUILTIN_WSRLWI,
-  ARM_BUILTIN_WSRLDI,
-  ARM_BUILTIN_WRORHI,
-  ARM_BUILTIN_WRORWI,
-  ARM_BUILTIN_WRORDI,
-
-  ARM_BUILTIN_WUNPCKIHB,
-  ARM_BUILTIN_WUNPCKIHH,
-  ARM_BUILTIN_WUNPCKIHW,
-  ARM_BUILTIN_WUNPCKILB,
-  ARM_BUILTIN_WUNPCKILH,
-  ARM_BUILTIN_WUNPCKILW,
-
-  ARM_BUILTIN_WUNPCKEHSB,
-  ARM_BUILTIN_WUNPCKEHSH,
-  ARM_BUILTIN_WUNPCKEHSW,
-  ARM_BUILTIN_WUNPCKEHUB,
-  ARM_BUILTIN_WUNPCKEHUH,
-  ARM_BUILTIN_WUNPCKEHUW,
-  ARM_BUILTIN_WUNPCKELSB,
-  ARM_BUILTIN_WUNPCKELSH,
-  ARM_BUILTIN_WUNPCKELSW,
-  ARM_BUILTIN_WUNPCKELUB,
-  ARM_BUILTIN_WUNPCKELUH,
-  ARM_BUILTIN_WUNPCKELUW,
-
-  ARM_BUILTIN_THREAD_POINTER,
-
-  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