OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / config / arm / arm.h
index 3f34954..c3dc3b9 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
    Free Software Foundation, Inc.
    Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
    and Martin Simmons (@harleqn.co.uk).
@@ -94,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.  */
@@ -120,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,
@@ -264,6 +288,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
@@ -397,6 +435,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 +450,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 +494,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 +556,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 +563,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 +605,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
@@ -771,12 +801,11 @@ extern int arm_structure_size_boundary;
        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.  */                                              \
-      /* ??? Is this still true for thumb2?  */                        \
+  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;          \
@@ -913,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)
 
@@ -957,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.  */
@@ -1088,6 +1117,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
@@ -1122,7 +1154,11 @@ extern int arm_structure_size_boundary;
 }
 
 /* Use different register alloc ordering for Thumb.  */
-#define ORDER_REGS_FOR_LOCAL_ALLOC arm_order_regs_for_local_alloc ()
+#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
@@ -1203,8 +1239,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 */   \
 }
 
@@ -1242,13 +1278,6 @@ 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_THUMB1 ? LO_REGS : GENERAL_REGS)
 #define BASE_REG_CLASS   (TARGET_THUMB1 ? LO_REGS : CORE_REGS)
@@ -1264,18 +1293,19 @@ enum reg_class
    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_THUMB1
+#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 core registers and
    immediate constants we prefer a LO_REGS class or a subset.  */
 #define PREFERRED_RELOAD_CLASS(X, CLASS)               \
-  (TARGET_ARM ? (CLASS) :                              \
+  (TARGET_32BIT ? (CLASS) :                            \
    ((CLASS) == GENERAL_REGS || (CLASS) == HI_REGS      \
     || (CLASS) == NO_REGS || (CLASS) == STACK_REG      \
    ? LO_REGS : (CLASS)))
@@ -1494,17 +1524,6 @@ do {                                                                           \
 /* 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)                                            \
@@ -1594,6 +1613,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
@@ -1624,8 +1644,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.  */
@@ -1648,6 +1676,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
@@ -1682,27 +1713,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)
 
@@ -1721,12 +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)   \
-  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.  */
@@ -1810,10 +1814,8 @@ typedef struct
 
 /* Determine if the epilogue should be output as RTL.
    You should override this if you define FUNCTION_EXTRA_EPILOGUE.  */
-/* This is disabled for Thumb-2 because it will confuse the
-   conditional insn counter.  */
 #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.
 
@@ -2025,13 +2027,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.
@@ -2118,11 +2113,11 @@ typedef struct
 #define CASE_VECTOR_MODE Pmode
 
 #define CASE_VECTOR_PC_RELATIVE (TARGET_THUMB2                         \
-                                || (TARGET_THUMB                       \
+                                || (TARGET_THUMB1                      \
                                     && (optimize_size || flag_pic)))
 
 #define CASE_VECTOR_SHORTEN_MODE(min, max, body)                       \
-  (TARGET_THUMB                                                                \
+  (TARGET_THUMB1                                                       \
    ? (min >= 0 && max < 512                                            \
       ? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 1, QImode)       \
       : min >= -256 && max < 256                                       \
@@ -2253,24 +2248,15 @@ 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
+#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" : "")
@@ -2412,17 +2398,6 @@ extern int making_const_table;
   else if (TARGET_THUMB1)                              \
     thumb1_final_prescan_insn (INSN)
 
-#define PRINT_OPERAND_PUNCT_VALID_P(CODE)      \
-  (CODE == '@' || CODE == '|' || CODE == '.'   \
-   || CODE == '(' || CODE == ')' || CODE == '#'        \
-   || (TARGET_32BIT && (CODE == '?'))          \
-   || (TARGET_THUMB2 && (CODE == '!'))         \
-   || (TARGET_THUMB && (CODE == '_')))
-
-/* Output an operand of an instruction.  */
-#define PRINT_OPERAND(STREAM, X, CODE)  \
-  arm_print_operand (STREAM, X, CODE)
-
 #define ARM_SIGN_EXTEND(x)  ((HOST_WIDE_INT)                   \
   (HOST_BITS_PER_WIDE_INT <= 32 ? (unsigned HOST_WIDE_INT) (x) \
    : ((((unsigned HOST_WIDE_INT)(x)) & (unsigned HOST_WIDE_INT) 0xffffffff) |\
@@ -2431,135 +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                                      \
-           || (GET_CODE (index) == REG && REGNO (index) == SP_REGNUM)) \
-         {                                                             \
-           /* Ensure that BASE is a register.  */                      \
-            /* (one of them must be).  */                              \
-           /* Also ensure the SP is not used as in index register.  */ \
-           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_32BIT)                            \
-    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.  */
 
@@ -2765,4 +2611,8 @@ enum arm_builtins
 #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 */