OSDN Git Service

* Makefile.in (MACHMODE_H): Add @extra_modes_file@.
[pf3gnuchains/gcc-fork.git] / gcc / config / arm / arm.h
index aa1c177..e74698a 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 Free Software Foundation, Inc.
+   2001, 2002 Free Software Foundation, Inc.
    Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
    and Martin Simmons (@harleqn.co.uk).
    More major hacks by Richard Earnshaw (rearnsha@arm.com)
@@ -26,6 +26,47 @@ Boston, MA 02111-1307, USA.  */
 #ifndef GCC_ARM_H
 #define GCC_ARM_H
 
+/* Target CPU builtins.  */
+#define TARGET_CPU_CPP_BUILTINS()                      \
+  do                                                   \
+    {                                                  \
+       if (TARGET_ARM)                                 \
+         builtin_define ("__arm__");                   \
+       else                                            \
+         builtin_define ("__thumb__");                 \
+                                                       \
+       if (TARGET_BIG_END)                             \
+         {                                             \
+           builtin_define ("__ARMEB__");               \
+           if (TARGET_THUMB)                           \
+             builtin_define ("__THUMBEB__");           \
+           if (TARGET_LITTLE_WORDS)                    \
+             builtin_define ("__ARMWEL__");            \
+         }                                             \
+        else                                           \
+         {                                             \
+           builtin_define ("__ARMEL__");               \
+           if (TARGET_THUMB)                           \
+             builtin_define ("__THUMBEL__");           \
+         }                                             \
+                                                       \
+       if (TARGET_APCS_32)                             \
+         builtin_define ("__APCS_32__");               \
+       else                                            \
+         builtin_define ("__APCS_26__");               \
+                                                       \
+       if (TARGET_SOFT_FLOAT)                          \
+         builtin_define ("__SOFTFP__");                \
+                                                       \
+       /* Add a define for interworking.               \
+          Needed when building libgcc.a.  */           \
+       if (TARGET_INTERWORK)                           \
+         builtin_define ("__THUMB_INTERWORK__");       \
+                                                       \
+       builtin_assert ("cpu=arm");                     \
+       builtin_assert ("machine=arm");                 \
+    } while (0)
+
 #define TARGET_CPU_arm2                0x0000
 #define TARGET_CPU_arm250      0x0000
 #define TARGET_CPU_arm3                0x0000
@@ -66,23 +107,22 @@ extern arm_cc arm_current_cc;
 
 extern int arm_target_label;
 extern int arm_ccfsm_state;
-extern struct rtx_def * arm_target_insn;
+extern GTY(()) rtx arm_target_insn;
 /* Run-time compilation parameters selecting different hardware subsets.  */
 extern int target_flags;
 /* The floating point instruction architecture, can be 2 or 3 */
 extern const char * target_fp_name;
 /* Define the information needed to generate branch insns.  This is
-   stored from the compare operation.  Note that we can't use "rtx" here
-   since it hasn't been defined!  */
-extern struct rtx_def * arm_compare_op0;
-extern struct rtx_def * arm_compare_op1;
+   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 struct rtx_def * pool_vector_label;
+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;
-/* Nonzero if the prologue must setup `fp'.  */
-extern int current_function_anonymous_args;
+/* Used to produce AOF syntax assembler.  */
+extern GTY(()) rtx aof_pic_label;
 \f
 /* Just in case configure has failed to define anything. */
 #ifndef TARGET_CPU_DEFAULT
@@ -127,15 +167,14 @@ Unrecognized value in TARGET_CPU_DEFAULT.
 #endif
 #endif
 
-#ifndef CPP_PREDEFINES
-#define CPP_PREDEFINES  "-Acpu=arm -Amachine=arm"
-#endif
-
-#define CPP_SPEC "\
-%(cpp_cpu_arch) %(cpp_apcs_pc) %(cpp_float) \
-%(cpp_endian) %(subtarget_cpp_spec) %(cpp_isa) %(cpp_interwork)"
-
-#define CPP_ISA_SPEC "%{mthumb:-D__thumb__} %{!mthumb:-D__arm__}"
+#undef  CPP_SPEC
+#define CPP_SPEC "%(cpp_cpu_arch) %(subtarget_cpp_spec)                        \
+%{mapcs-32:%{mapcs-26:                                                 \
+       %e-mapcs-26 and -mapcs-32 may not be used together}}            \
+%{msoft-float:%{mhard-float:                                           \
+       %e-msoft-float and -mhard_float may not be used together}}      \
+%{mbig-endian:%{mlittle-endian:                                                \
+       %e-mbig-endian and -mlittle-endian may not be used together}}"
 
 /* Set the architecture define -- if -march= is set, then it overrides
    the -mcpu= setting.  */
@@ -210,55 +249,9 @@ Unrecognized value in TARGET_CPU_DEFAULT.
  %{!mcpu*:%(cpp_cpu_arch_default)}} \
 "
 
-/* Define __APCS_26__ if the PC also contains the PSR */
-#define CPP_APCS_PC_SPEC "\
-%{mapcs-32:%{mapcs-26:%e-mapcs-26 and -mapcs-32 may not be used together} \
- -D__APCS_32__} \
-%{mapcs-26:-D__APCS_26__} \
-%{!mapcs-32: %{!mapcs-26:%(cpp_apcs_pc_default)}} \
-"
-
-#ifndef CPP_APCS_PC_DEFAULT_SPEC
-#define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_26__"
-#endif
-
-#define CPP_FLOAT_SPEC "\
-%{msoft-float:\
-  %{mhard-float:%e-msoft-float and -mhard_float may not be used together} \
-  -D__SOFTFP__} \
-%{!mhard-float:%{!msoft-float:%(cpp_float_default)}} \
-"
-
-/* Default is hard float, which doesn't define anything */
-#define CPP_FLOAT_DEFAULT_SPEC ""
-
-#define CPP_ENDIAN_SPEC "\
-%{mbig-endian:                                                         \
-  %{mlittle-endian:                                                    \
-    %e-mbig-endian and -mlittle-endian may not be used together}       \
-  -D__ARMEB__ %{mwords-little-endian:-D__ARMWEL__} %{mthumb:-D__THUMBEB__}}\
-%{mlittle-endian:-D__ARMEL__ %{mthumb:-D__THUMBEL__}}                  \
-%{!mlittle-endian:%{!mbig-endian:%(cpp_endian_default)}}               \
-"
-
-/* Default is little endian.  */
-#define CPP_ENDIAN_DEFAULT_SPEC "-D__ARMEL__ %{mthumb:-D__THUMBEL__}"
-
-/* Add a define for interworking.  Needed when building libgcc.a.  
-   This must define __THUMB_INTERWORK__ to the pre-processor if
-   interworking is enabled by default.  */
-#ifndef CPP_INTERWORK_DEFAULT_SPEC
-#define CPP_INTERWORK_DEFAULT_SPEC ""
-#endif
-
-#define CPP_INTERWORK_SPEC "                                           \
-%{mthumb-interwork:                                                    \
-  %{mno-thumb-interwork: %eIncompatible interworking options}          \
-  -D__THUMB_INTERWORK__}                                               \
-%{!mthumb-interwork:%{!mno-thumb-interwork:%(cpp_interwork_default)}}  \
-"
-
+#ifndef CC1_SPEC
 #define CC1_SPEC ""
+#endif
 
 /* This macro defines names of additional specifications to put in the specs
    that can be used in various specifications like CC1_SPEC.  Its definition
@@ -272,15 +265,6 @@ Unrecognized value in TARGET_CPU_DEFAULT.
 #define EXTRA_SPECS                                            \
   { "cpp_cpu_arch",            CPP_CPU_ARCH_SPEC },            \
   { "cpp_cpu_arch_default",    CPP_ARCH_DEFAULT_SPEC },        \
-  { "cpp_apcs_pc",             CPP_APCS_PC_SPEC },             \
-  { "cpp_apcs_pc_default",     CPP_APCS_PC_DEFAULT_SPEC },     \
-  { "cpp_float",               CPP_FLOAT_SPEC },               \
-  { "cpp_float_default",       CPP_FLOAT_DEFAULT_SPEC },       \
-  { "cpp_endian",              CPP_ENDIAN_SPEC },              \
-  { "cpp_endian_default",      CPP_ENDIAN_DEFAULT_SPEC },      \
-  { "cpp_isa",                 CPP_ISA_SPEC },                 \
-  { "cpp_interwork",           CPP_INTERWORK_SPEC },           \
-  { "cpp_interwork_default",   CPP_INTERWORK_DEFAULT_SPEC },   \
   { "subtarget_cpp_spec",      SUBTARGET_CPP_SPEC },           \
   SUBTARGET_EXTRA_SPECS
 
@@ -407,8 +391,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
                                         ? (target_flags & THUMB_FLAG_LEAF_BACKTRACE)   \
                                         : (target_flags & THUMB_FLAG_BACKTRACE))
 
-/* SUBTARGET_SWITCHES is used to add flags on a per-config basis.
-   Bit 31 is reserved.  See riscix.h.  */
+/* SUBTARGET_SWITCHES is used to add flags on a per-config basis.  */
 #ifndef SUBTARGET_SWITCHES
 #define SUBTARGET_SWITCHES
 #endif
@@ -548,7 +531,9 @@ extern enum floating_point_type arm_fpu_arch;
 
 /* Default floating point architecture.  Override in sub-target if
    necessary.  */
+#ifndef FP_DEFAULT
 #define FP_DEFAULT FP_SOFT2
+#endif
 
 /* Nonzero if the processor has a fast multiply insn, and one that does
    a 64-bit multiply of two 32-bit values.  */
@@ -575,7 +560,7 @@ extern int arm_is_strong;
 /* Nonzero if this chip is an XScale.  */
 extern int arm_is_xscale;
 
-/* Nonzero if this chip is a an ARM6 or an ARM7.  */
+/* Nonzero if this chip is an ARM6 or an ARM7.  */
 extern int arm_is_6_or_7;
 
 #ifndef TARGET_DEFAULT
@@ -586,6 +571,7 @@ extern int arm_is_6_or_7;
    that is controlled by the APCS-FRAME option.  */
 #define CAN_DEBUG_WITHOUT_FP
 
+#undef  TARGET_MEM_FUNCTIONS
 #define TARGET_MEM_FUNCTIONS 1
 
 #define OVERRIDE_OPTIONS  arm_override_options ()
@@ -642,8 +628,6 @@ extern int arm_is_6_or_7;
 /* This is required to ensure that push insns always push a word.  */
 #define PROMOTE_FUNCTION_ARGS
 
-/* Define for XFmode extended real floating point support.
-   This will automatically cause REAL_ARITHMETIC to be defined.  */
 /* For the ARM:
    I think I have added all the code to make this work.  Unfortunately,
    early releases of the floating point emulation code on RISCiX used a
@@ -658,12 +642,6 @@ extern int arm_is_6_or_7;
 /* Disable XFmode patterns in md file */
 #define ENABLE_XF_PATTERNS 0
 
-/* Define if you don't want extended real, but do want to use the
-   software floating point emulator for REAL_ARITHMETIC and
-   decimal <-> binary conversion. */
-/* See comment above */
-#define REAL_ARITHMETIC
-
 /* Define this if most significant bit is lowest numbered
    in instructions that operate on numbered bit-fields.  */
 #define BITS_BIG_ENDIAN  0
@@ -691,15 +669,8 @@ extern int arm_is_6_or_7;
    This is always true, even when in little-endian mode.  */
 #define FLOAT_WORDS_BIG_ENDIAN 1
 
-/* Number of bits in an addressable storage unit */
-#define BITS_PER_UNIT  8
-
-#define BITS_PER_WORD  32
-
 #define UNITS_PER_WORD 4
 
-#define POINTER_SIZE  32
-
 #define PARM_BOUNDARY          32
 
 #define STACK_BOUNDARY  32
@@ -726,7 +697,7 @@ extern int arm_is_6_or_7;
 /* Setting STRUCTURE_SIZE_BOUNDARY to 32 produces more efficient code, but the
    value set in previous versions of this toolchain was 8, which produces more
    compact structures.  The command line option -mstructure_size_boundary=<n>
-   can be used to change this value.  For compatability with the ARM SDK
+   can be used to change this value.  For compatibility with the ARM SDK
    however the value should be left at 32.  ARM SDT Reference Manual (ARM DUI
    0020D) page 2-20 says "Structures are aligned on word boundaries".  */
 #define STRUCTURE_SIZE_BOUNDARY arm_structure_size_boundary
@@ -840,14 +811,15 @@ extern const char * structure_size_string;
 
 #define CONDITIONAL_REGISTER_USAGE                             \
 {                                                              \
+  int regno;                                                   \
+                                                               \
   if (TARGET_SOFT_FLOAT || TARGET_THUMB)                       \
     {                                                          \
-      int regno;                                               \
       for (regno = FIRST_ARM_FP_REGNUM;                                \
           regno <= LAST_ARM_FP_REGNUM; ++regno)                \
        fixed_regs[regno] = call_used_regs[regno] = 1;          \
     }                                                          \
-  if (flag_pic)                                                        \
+  if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)               \
     {                                                          \
       fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;                 \
       call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;             \
@@ -900,8 +872,19 @@ extern const char * structure_size_string;
 /* Return the regiser number of the N'th (integer) argument.  */
 #define ARG_REGISTER(N)        (N - 1)
 
+#if 0 /* FIXME: The ARM backend has special code to handle structure
+        returns, and will reserve its own hidden first argument.  So
+        if this macro is enabled a *second* hidden argument will be
+        reserved, which will break binary compatibility with old
+        toolchains and also thunk handling.  One day this should be
+        fixed.  */
 /* RTX for structure returns.  NULL means use a hidden first argument.  */
 #define STRUCT_VALUE           0
+#else
+/* Register in which address to store a structure value
+   is passed to a function.  */
+#define STRUCT_VALUE_REGNUM    ARG_REGISTER (1)
+#endif
 
 /* Specify the registers used for certain standard purposes.
    The values of these macros are register numbers.  */
@@ -986,23 +969,9 @@ extern const char * structure_size_string;
     && REGNO != ARG_POINTER_REGNUM)    \
    ? 1 : NUM_REGS (MODE))
 
-/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
-   This is TRUE for ARM regs since they can hold anything, and TRUE for FPU
-   regs holding FP.
-   For the Thumb we only allow values bigger than SImode in registers 0 - 6,
-   so that there is always a second lo register available to hold the upper
-   part of the value.  Probably we ought to ensure that the register is the
-   start of an even numbered register pair.  */
+/* Return true if REGNO is suitable for holding a quantity of type MODE.  */
 #define HARD_REGNO_MODE_OK(REGNO, MODE)                                        \
-  (TARGET_ARM ?                                                                \
-   ((GET_MODE_CLASS (MODE) == MODE_CC) ? (REGNO == CC_REGNUM) :                \
-    (   REGNO <= LAST_ARM_REGNUM                                       \
-     || REGNO == FRAME_POINTER_REGNUM                                  \
-     || REGNO == ARG_POINTER_REGNUM                                    \
-     || GET_MODE_CLASS (MODE) == MODE_FLOAT))                          \
-   :                                                                   \
-   ((GET_MODE_CLASS (MODE) == MODE_CC) ? (REGNO == CC_REGNUM) :                \
-    (NUM_REGS (MODE) < 2 || REGNO < LAST_LO_REGNUM)))
+  arm_hard_regno_mode_ok ((REGNO), (MODE))
 
 /* Value is 1 if it is a good idea to tie two pseudo registers
    when one has mode MODE1 and one has mode MODE2.
@@ -1024,11 +993,18 @@ extern const char * structure_size_string;
     16, 17, 18, 19, 20, 21, 22, 23, \
     24, 25, 26                     \
 }
+
+/* Interrupt functions can only use registers that have already been
+   saved by the prologue, even if they would normally be
+   call-clobbered.  */
+#define HARD_REGNO_RENAME_OK(SRC, DST)                                 \
+       (! IS_INTERRUPT (cfun->machine->func_type) ||                   \
+               regs_ever_live[DST])
 \f
 /* Register and constant classes.  */
 
 /* Register classes: used to be simple, just all ARM regs or all FPU regs
-   Now that the Thumb is involved it has become more compilcated.  */
+   Now that the Thumb is involved it has become more complicated.  */
 enum reg_class
 {
   NO_REGS,
@@ -1074,7 +1050,7 @@ enum reg_class
   { 0x200FFFF }, /* GENERAL_REGS */    \
   { 0x2FFFFFF }  /* ALL_REGS */                \
 }
-  
+
 /* The same information, inverted:
    Return the class number of the smallest class containing
    reg number REGNO.  This could be a conditional expression
@@ -1085,6 +1061,13 @@ enum reg_class
 #define INDEX_REG_CLASS  (TARGET_THUMB ? LO_REGS : GENERAL_REGS)
 #define BASE_REG_CLASS   (TARGET_THUMB ? BASE_REGS : GENERAL_REGS)
 
+/* For the Thumb the high registers cannot be used as base
+   registers when addressing quanitities in QI or HI mode.  */
+#define MODE_BASE_REG_CLASS(MODE)                                      \
+    (TARGET_ARM ? BASE_REGS :                                          \
+     (((MODE) == QImode || (MODE) == HImode || (MODE) == VOIDmode)     \
+     ? LO_REGS : BASE_REGS))
+
 /* When SMALL_REGISTER_CLASSES is nonzero, the compiler allows
    registers explicitly used in the rtl to be used as spill registers
    but prevents the compiler from extending the lifetime of these
@@ -1248,9 +1231,9 @@ enum reg_class
          else                                                             \
            break;                                                         \
                                                                           \
-         high = ((((val - low) & HOST_UINT (0xffffffff))                  \
-                  ^ HOST_UINT (0x80000000))                               \
-                 - HOST_UINT (0x80000000));                               \
+         high = ((((val - low) & (unsigned HOST_WIDE_INT) 0xffffffff)     \
+                  ^ (unsigned HOST_WIDE_INT) 0x80000000)                  \
+                 - (unsigned HOST_WIDE_INT) 0x80000000);                  \
          /* Check for overflow or zero */                                 \
          if (low == 0 || high == 0 || (high + low != val))                \
            break;                                                         \
@@ -1262,8 +1245,8 @@ enum reg_class
                                          GEN_INT (high)),                 \
                            GEN_INT (low));                                \
          push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL,          \
-                      BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0,       \
-                      OPNUM, TYPE);                                       \
+                      MODE_BASE_REG_CLASS (MODE), GET_MODE (X),           \
+                      VOIDmode, 0, 0, OPNUM, TYPE);                       \
          goto WIN;                                                        \
        }                                                                  \
     }                                                                     \
@@ -1289,7 +1272,7 @@ enum reg_class
       rtx orig_X = X;                                                  \
       X = copy_rtx (X);                                                        \
       push_reload (orig_X, NULL_RTX, &X, NULL,                         \
-                  BASE_REG_CLASS,                                      \
+                  MODE_BASE_REG_CLASS (MODE),                          \
                   Pmode, VOIDmode, 0, 0, OPNUM, TYPE);                 \
       goto WIN;                                                                \
     }                                                                  \
@@ -1430,10 +1413,10 @@ enum reg_class
 
 /* A C structure for machine-specific, per-function data.
    This is added to the cfun structure.  */
-typedef struct machine_function
+typedef struct machine_function GTY(())
 {
   /* Additionsl stack adjustment in __builtin_eh_throw.  */
-  struct rtx_def *eh_epilogue_sp_ofs;
+  rtx eh_epilogue_sp_ofs;
   /* Records if LR has to be saved for far jumps.  */
   int far_jump_used;
   /* Records if ARG_POINTER was ever live.  */
@@ -1442,6 +1425,8 @@ typedef struct machine_function
   int lr_save_eliminated;
   /* Records the type of the current function.  */
   unsigned long func_type;
+  /* Record if the function has a variable argument list.  */
+  int uses_anonymous_args;
 }
 machine_function;
 
@@ -1500,8 +1485,7 @@ typedef struct
 
 /* 1 if N is a possible register number for function argument passing.
    On the ARM, r0-r3 are used to pass args.  */
-#define FUNCTION_ARG_REGNO_P(REGNO)  \
-  ((REGNO) >= 0 && (REGNO) <= 3)
+#define FUNCTION_ARG_REGNO_P(REGNO)    (IN_RANGE ((REGNO), 0, 3))
 
 \f
 /* Tail calling.  */
@@ -1525,8 +1509,7 @@ typedef struct
    that way.  */
 #define SETUP_INCOMING_VARARGS(CUM, MODE, TYPE, PRETEND_SIZE, NO_RTL)  \
 {                                                                      \
-  extern int current_function_anonymous_args;                          \
-  current_function_anonymous_args = 1;                                 \
+  cfun->machine->uses_anonymous_args = 1;                              \
   if ((CUM).nregs < NUM_ARG_REGS)                                      \
     (PRETEND_SIZE) = (NUM_ARG_REGS - (CUM).nregs) * UNITS_PER_WORD;    \
 }
@@ -1554,6 +1537,7 @@ typedef struct
 
    The ``mov ip,lr'' seems like a good idea to stick with cc convention.
    ``prof'' doesn't seem to mind about this!  */
+#ifndef ARM_FUNCTION_PROFILER
 #define ARM_FUNCTION_PROFILER(STREAM, LABELNO)         \
 {                                                      \
   char temp[20];                                       \
@@ -1565,15 +1549,18 @@ typedef struct
   fputc ('\n', STREAM);                                        \
   ASM_GENERATE_INTERNAL_LABEL (temp, "LP", LABELNO);   \
   sym = gen_rtx (SYMBOL_REF, Pmode, temp);             \
-  ASM_OUTPUT_INT (STREAM, sym);                                \
+  assemble_aligned_integer (UNITS_PER_WORD, sym);      \
 }
+#endif
 
+#ifndef THUMB_FUNCTION_PROFILER
 #define THUMB_FUNCTION_PROFILER(STREAM, LABELNO)       \
 {                                                      \
-  fprintf (STREAM, "\tmov\\tip, lr\n");                        \
+  fprintf (STREAM, "\tmov\tip, lr\n");                 \
   fprintf (STREAM, "\tbl\tmcount\n");                  \
   fprintf (STREAM, "\t.word\tLP%d\n", LABELNO);                \
 }
+#endif
 
 #define FUNCTION_PROFILER(STREAM, LABELNO)             \
   if (TARGET_ARM)                                      \
@@ -1609,7 +1596,7 @@ typedef struct
    pointer register.  Secondly, the pseudo frame pointer register can always
    be eliminated; it is replaced with either the stack or the real frame
    pointer.  Note we have to use {ARM|THUMB}_HARD_FRAME_POINTER_REGNUM
-   because the defintion of HARD_FRAME_POINTER_REGNUM is not a constant.  */
+   because the definition of HARD_FRAME_POINTER_REGNUM is not a constant.  */
 
 #define ELIMINABLE_REGS                                                \
 {{ ARG_POINTER_REGNUM,        STACK_POINTER_REGNUM            },\
@@ -1701,14 +1688,14 @@ typedef struct
           .word        static chain value
           .word        function's address
    ??? FIXME: When the trampoline returns, r8 will be clobbered.  */
-#define ARM_TRAMPOLINE_TEMPLATE(FILE)                  \
-{                                                      \
-  asm_fprintf (FILE, "\tldr\t%r, [%r, #0]\n",          \
-              STATIC_CHAIN_REGNUM, PC_REGNUM);         \
-  asm_fprintf (FILE, "\tldr\t%r, [%r, #0]\n",          \
-              PC_REGNUM, PC_REGNUM);                   \
-  ASM_OUTPUT_INT (FILE, const0_rtx);                   \
-  ASM_OUTPUT_INT (FILE, const0_rtx);                   \
+#define ARM_TRAMPOLINE_TEMPLATE(FILE)                          \
+{                                                              \
+  asm_fprintf (FILE, "\tldr\t%r, [%r, #0]\n",                  \
+              STATIC_CHAIN_REGNUM, PC_REGNUM);                 \
+  asm_fprintf (FILE, "\tldr\t%r, [%r, #0]\n",                  \
+              PC_REGNUM, PC_REGNUM);                           \
+  assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);       \
+  assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);       \
 }
 
 /* On the Thumb we always switch into ARM mode to execute the trampoline.
@@ -1743,8 +1730,8 @@ typedef struct
 /* Length in units of the trampoline for entering a nested function.  */
 #define TRAMPOLINE_SIZE  (TARGET_ARM ? 16 : 24)
 
-/* Alignment required for a trampoline in units.  */
-#define TRAMPOLINE_ALIGN  4
+/* Alignment required for a trampoline in bits.  */
+#define TRAMPOLINE_ALIGNMENT  32
 
 /* Emit RTL insns to initialize the variable parts of a trampoline.
    FNADDR is an RTX for the address of the function's pure code.
@@ -1829,7 +1816,8 @@ typedef struct
 #define THUMB_LEGITIMATE_CONSTANT_P(X) \
  (   GET_CODE (X) == CONST_INT         \
   || GET_CODE (X) == CONST_DOUBLE      \
-  || CONSTANT_ADDRESS_P (X))
+  || CONSTANT_ADDRESS_P (X)            \
+  || flag_pic)
 
 #define LEGITIMATE_CONSTANT_P(X)       \
   (TARGET_ARM ? ARM_LEGITIMATE_CONSTANT_P (X) : THUMB_LEGITIMATE_CONSTANT_P (X))
@@ -1860,57 +1848,12 @@ typedef struct
   case '*':  return 1;                         \
   SUBTARGET_NAME_ENCODING_LENGTHS              
 
-/* This has to be handled by a function because more than part of the
-   ARM backend uses function name prefixes to encode attributes.  */
-#undef  STRIP_NAME_ENCODING
-#define STRIP_NAME_ENCODING(VAR, SYMBOL_NAME)  \
-  (VAR) = arm_strip_name_encoding (SYMBOL_NAME)
-
 /* This is how to output a reference to a user-level label named NAME.
    `assemble_name' uses this.  */
 #undef  ASM_OUTPUT_LABELREF
 #define ASM_OUTPUT_LABELREF(FILE, NAME)                \
   asm_fprintf (FILE, "%U%s", arm_strip_name_encoding (NAME))
 
-/* If we are referencing a function that is weak then encode a long call
-   flag in the function name, otherwise if the function is static or
-   or known to be defined in this file then encode a short call flag.
-   This macro is used inside the ENCODE_SECTION macro.  */
-#define ARM_ENCODE_CALL_TYPE(decl)                                     \
-  if (TREE_CODE (decl) == FUNCTION_DECL)                               \
-    {                                                                  \
-      if (DECL_WEAK (decl))                                            \
-        arm_encode_call_attribute (decl, LONG_CALL_FLAG_CHAR);         \
-      else if (! TREE_PUBLIC (decl))                                   \
-        arm_encode_call_attribute (decl, SHORT_CALL_FLAG_CHAR);                \
-    }                                                                  \
-
-/* Symbols in the text segment can be accessed without indirecting via the
-   constant pool; it may take an extra binary operation, but this is still
-   faster than indirecting via memory.  Don't do this when not optimizing,
-   since we won't be calculating al of the offsets necessary to do this
-   simplification.  */
-/* This doesn't work with AOF syntax, since the string table may be in
-   a different AREA.  */
-#ifndef AOF_ASSEMBLER
-#define ENCODE_SECTION_INFO(decl)                                      \
-{                                                                      \
-  if (optimize > 0 && TREE_CONSTANT (decl)                             \
-      && (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))   \
-    {                                                                  \
-      rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'             \
-                 ? TREE_CST_RTL (decl) : DECL_RTL (decl));             \
-      SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;                             \
-    }                                                                  \
-  ARM_ENCODE_CALL_TYPE (decl)                                          \
-}
-#else
-#define ENCODE_SECTION_INFO(decl)                                      \
-{                                                                      \
-  ARM_ENCODE_CALL_TYPE (decl)                                          \
-}
-#endif
-
 #define ARM_DECLARE_FUNCTION_SIZE(STREAM, NAME, DECL)  \
   arm_encode_call_attribute (DECL, SHORT_CALL_FLAG_CHAR)
 
@@ -2144,7 +2087,8 @@ typedef struct
     goto WIN;                                                          \
   /* This is PC relative data before MACHINE_DEPENDENT_REORG runs.  */ \
   else if (GET_MODE_SIZE (MODE) >= 4 && CONSTANT_P (X)                 \
-          && CONSTANT_POOL_ADDRESS_P (X) && ! flag_pic)                \
+          && GET_CODE (X) == SYMBOL_REF                                \
+           && CONSTANT_POOL_ADDRESS_P (X) && ! flag_pic)               \
     goto WIN;                                                          \
   /* This is PC relative data after MACHINE_DEPENDENT_REORG runs.  */  \
   else if (GET_MODE_SIZE (MODE) >= 4 && reload_completed               \
@@ -2330,12 +2274,6 @@ typedef struct
    Do not define this if the table should contain absolute addresses. */
 /* #define CASE_VECTOR_PC_RELATIVE 1 */
 
-/* Specify the tree operation to be used to convert reals to integers.  */
-#define IMPLICIT_FIX_EXPR  FIX_ROUND_EXPR
-
-/* This is the kind of divide that is easiest to do in the general case.  */
-#define EASY_DIV_EXPR  TRUNC_DIV_EXPR
-
 /* signed 'char' is most compatible, but RISC OS wants it unsigned.
    unsigned is probably best, but may break some code.  */
 #ifndef DEFAULT_SIGNED_CHAR
@@ -2365,11 +2303,6 @@ typedef struct
    ((arm_arch4 || (MODE) == QImode) ? ZERO_EXTEND                      \
     : ((BYTES_BIG_ENDIAN && (MODE) == HImode) ? SIGN_EXTEND : NIL)))
 
-/* Define this if zero-extension is slow (more than one real instruction).
-   On the ARM, it is more than one instruction only if not fetching from
-   memory.  */
-/* #define SLOW_ZERO_EXTEND */
-
 /* Nonzero if access to memory by bytes is slow and undesirable.  */
 #define SLOW_BYTE_ACCESS 0
 
@@ -2484,30 +2417,7 @@ extern int making_const_table;
 
 /* Condition code information. */
 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
-   return the mode to be used for the comparison. 
-   CCFPEmode should be used with floating inequalities,
-   CCFPmode should be used with floating equalities.
-   CC_NOOVmode should be used with SImode integer equalities.
-   CC_Zmode should be used if only the Z flag is set correctly
-   CCmode should be used otherwise. */
-
-#define EXTRA_CC_MODES \
-        CC(CC_NOOVmode, "CC_NOOV") \
-        CC(CC_Zmode, "CC_Z") \
-        CC(CC_SWPmode, "CC_SWP") \
-        CC(CCFPmode, "CCFP") \
-        CC(CCFPEmode, "CCFPE") \
-        CC(CC_DNEmode, "CC_DNE") \
-        CC(CC_DEQmode, "CC_DEQ") \
-        CC(CC_DLEmode, "CC_DLE") \
-        CC(CC_DLTmode, "CC_DLT") \
-        CC(CC_DGEmode, "CC_DGE") \
-        CC(CC_DGTmode, "CC_DGT") \
-        CC(CC_DLEUmode, "CC_DLEU") \
-        CC(CC_DLTUmode, "CC_DLTU") \
-        CC(CC_DGEUmode, "CC_DGEU") \
-        CC(CC_DGTUmode, "CC_DGTU") \
-        CC(CC_Cmode, "CC_C")
+   return the mode to be used for the comparison.  */
 
 #define SELECT_CC_MODE(OP, X, Y)  arm_select_cc_mode (OP, X, Y)
 
@@ -2578,6 +2488,7 @@ extern int making_const_table;
 
 /* This is how to output a label which precedes a jumptable.  Since
    Thumb instructions are 2 bytes, we may need explicit alignment here.  */
+#undef  ASM_OUTPUT_CASE_LABEL
 #define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, JUMPTABLE)    \
   do                                                           \
     {                                                          \
@@ -2606,8 +2517,8 @@ extern int making_const_table;
 #define ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL1, DECL2)          \
   do                                                           \
     {                                                          \
-      char * LABEL1 = XSTR (XEXP (DECL_RTL (decl), 0), 0);     \
-      char * LABEL2 = IDENTIFIER_POINTER (DECL2);              \
+      const char *const LABEL1 = XSTR (XEXP (DECL_RTL (decl), 0), 0); \
+      const char *const LABEL2 = IDENTIFIER_POINTER (DECL2);   \
                                                                \
       if (TARGET_THUMB && TREE_CODE (DECL1) == FUNCTION_DECL)  \
        {                                                       \
@@ -2654,22 +2565,12 @@ extern int making_const_table;
 #define PRINT_OPERAND(STREAM, X, CODE)  \
   arm_print_operand (STREAM, X, CODE)
 
-/* Create an [unsigned] host sized integer declaration that
-   avoids compiler warnings.  */
-#ifdef __STDC__
-#define HOST_INT(x)  ((signed HOST_WIDE_INT) x##UL)
-#define HOST_UINT(x) ((unsigned HOST_WIDE_INT) x##UL)
-#else
-#define HOST_INT(x)  ((HOST_WIDE_INT) x)
-#define HOST_UINT(x) ((unsigned HOST_WIDE_INT) x)
-#endif
-
 #define ARM_SIGN_EXTEND(x)  ((HOST_WIDE_INT)                   \
   (HOST_BITS_PER_WIDE_INT <= 32 ? (unsigned HOST_WIDE_INT) (x) \
-   : ((((unsigned HOST_WIDE_INT)(x)) & HOST_UINT (0xffffffff)) |\
-      ((((unsigned HOST_WIDE_INT)(x)) & HOST_UINT (0x80000000))        \
-       ? ((~ HOST_UINT (0))                                    \
-         & ~ HOST_UINT(0xffffffff))                            \
+   : ((((unsigned HOST_WIDE_INT)(x)) & (unsigned HOST_WIDE_INT) 0xffffffff) |\
+      ((((unsigned HOST_WIDE_INT)(x)) & (unsigned HOST_WIDE_INT) 0x80000000) \
+       ? ((~ (unsigned HOST_WIDE_INT) 0)                       \
+         & ~ (unsigned HOST_WIDE_INT) 0xffffffff)              \
        : 0))))
 
 /* Output the address of an operand.  */
@@ -2775,24 +2676,6 @@ extern int making_const_table;
   else                                         \
     THUMB_PRINT_OPERAND_ADDRESS (STREAM, X)
      
-#define OUTPUT_INT_ADDR_CONST(STREAM, X)                               \
-  {                                                                    \
-    output_addr_const (STREAM, X);                                     \
-                                                                       \
-    /* Mark symbols as position independent.  We only do this in the   \
-      .text segment, not in the .data segment. */                      \
-    if (NEED_GOT_RELOC && flag_pic && making_const_table &&            \
-       (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == LABEL_REF))      \
-     {                                                                 \
-        if (GET_CODE (X) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (X)) \
-          fprintf (STREAM, "(GOTOFF)");                                        \
-        else if (GET_CODE (X) == LABEL_REF)                            \
-          fprintf (STREAM, "(GOTOFF)");                                        \
-        else                                                           \
-          fprintf (STREAM, "(GOT)");                                   \
-     }                                                                 \
-  }
-
 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
    Used for C++ multiple inheritance.  */
 #define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION)               \
@@ -2899,7 +2782,6 @@ extern int making_const_table;
 enum arm_builtins
 {
   ARM_BUILTIN_CLZ,
-  ARM_BUILTIN_PREFETCH,
   ARM_BUILTIN_MAX
 };
 #endif /* ! GCC_ARM_H */