Convert ACCUMULATE_OUTGOING_ARGS to an expression.
[gcc.git] / gcc / config / a29k / a29k.h
index 882a5bdebc71060b2ba1c34e554ed716773ecd82..d7a2bd426f45aa24d58005aad010e350830eb815 100644 (file)
@@ -1,5 +1,6 @@
 /* Definitions of target machine for GNU compiler, for AMD Am29000 CPU.
-   Copyright (C) 1988, 1990, 1991, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1988, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+   2000 Free Software Foundation, Inc.
    Contributed by Richard Kenner (kenner@nyu.edu)
 
 This file is part of GNU CC.
@@ -16,12 +17,13 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 
 /* Names to predefine in the preprocessor for this target machine.  */
 
-#define CPP_PREDEFINES "-D_AM29K -D_AM29000 -D_EPI"
+#define CPP_PREDEFINES "-D_AM29K -D_AM29000 -D_EPI -Acpu(a29k) -Amachine(a29k)"
 
 /* Print subsidiary information on the compiler version in use.  */
 #define TARGET_VERSION
@@ -54,62 +56,73 @@ extern int target_flags;
 
 #define TARGET_SMALL_MEMORY    (target_flags & 4)
 
+/* This means that we must always used on indirect call, even when
+   calling a function in the same file, since the file might be > 256KB.  */
+
+#define TARGET_LARGE_MEMORY    (target_flags & 8)
+
 /* This means that we are compiling for a 29050.  */
 
-#define TARGET_29050           (target_flags & 8)
+#define TARGET_29050           (target_flags & 16)
 
 /* This means that we are compiling for the kernel which means that we use
    gr64-gr95 instead of gr96-126.  */
 
-#define TARGET_KERNEL_REGISTERS        (target_flags & 16)
+#define TARGET_KERNEL_REGISTERS        (target_flags & 32)
 
 /* This means that a call to "__msp_check" should be inserted after each stack
    adjustment to check for stack overflow.  */
 
-#define TARGET_STACK_CHECK     (target_flags & 32)
+#define TARGET_STACK_CHECK     (target_flags & 64)
 
 /* This handles 29k processors which cannot handle the separation
    of a mtsrim insns and a storem insn (most 29000 chips to date, but
    not the 29050.  */
 
-#define TARGET_NO_STOREM_BUG   (target_flags & 64)
+#define TARGET_NO_STOREM_BUG   (target_flags & 128)
 
 /* This forces the compiler not to use incoming argument registers except
    for copying out arguments.  It helps detect problems when a function is
    called with fewer arguments than it is declared with.  */
 
-#define TARGET_NO_REUSE_ARGS   (target_flags & 128)
+#define TARGET_NO_REUSE_ARGS   (target_flags & 256)
+
+/* This means that neither builtin nor emulated float operations are
+   available, and that GCC should generate libcalls instead. */
+
+#define TARGET_SOFT_FLOAT      (target_flags & 512)
+
+/* This means that we should not emit the multm or mutmu instructions
+   that some embedded systems' trap handlers don't support.  */
+
+#define TARGET_MULTM           ((target_flags & 1024) == 0)
 
 #define TARGET_SWITCHES                        \
-  { {"dw", 1},                         \
-    {"ndw", -1},                       \
-    {"bw", 2},                         \
-    {"nbw", - (1|2)},                  \
-    {"small", 4},                      \
-    {"large", -4},                     \
-    {"29050", 8+64},                   \
-    {"29000", -8},                     \
-    {"kernel-registers", 16},          \
-    {"user-registers", -16},           \
-    {"stack-check", 32},               \
-    {"no-storem-bug", 64},             \
-    {"reuse-arg-regs", -128},          \
-    {"no-reuse-arg-regs", 128},                \
-    {"", TARGET_DEFAULT}}
+  { {"dw", 1, "Generate code assuming DW bit is set"},                 \
+    {"ndw", -1, "Generate code assuming DW bit is not set"},           \
+    {"bw", 2, "Generate code using byte writes"},                      \
+    {"nbw", - (1|2), "Do not generate byte writes"},                   \
+    {"small", 4, "Use small memory model"},                            \
+    {"normal", - (4|8), "Use normal memory model"},                    \
+    {"large", 8, "Use large memory model"},                            \
+    {"29050", 16+128, "Generate 29050 code"},                          \
+    {"29000", -16, "Generate 29000 code"},                             \
+    {"kernel-registers", 32, "Use kernel global registers"},           \
+    {"user-registers", -32, "Use user global registers"},              \
+    {"stack-check", 64, "Emit stack checking code"},                   \
+    {"no-stack-check", - 74, "Do not emit stack checking code"},       \
+    {"storem-bug", -128, "Work around storem hardware bug"},           \
+    {"no-storem-bug", 128, "Do not work around storem hardware bug"},  \
+    {"reuse-arg-regs", -256, "Store locals in argument registers"},    \
+    {"no-reuse-arg-regs", 256, "Do not store locals in arg registers"},        \
+    {"soft-float", 512, "Use software floating point"},                        \
+    {"no-multm", 1024, "Do not generate multm instructions"},          \
+    {"", TARGET_DEFAULT, NULL}}
 
 #define TARGET_DEFAULT 3
 
-/* Define this to change the optimizations performed by default.  */
-
-#define OPTIMIZATION_OPTIONS(LEVEL)    \
-{                                      \
-  if ((LEVEL) > 0)                     \
-    {                                  \
-      flag_force_addr = 1;             \
-      flag_force_mem = 1;              \
-      flag_omit_frame_pointer = 1;     \
-    }                                  \
-}
+/* Show we can debug even without a frame pointer.  */
+#define CAN_DEBUG_WITHOUT_FP
 \f
 /* target machine storage layout */
 
@@ -122,7 +135,7 @@ extern int target_flags;
 #define WCHAR_TYPE "char"
 #define WCHAR_TYPE_SIZE BITS_PER_UNIT
 
-/* Define this macro if it is advisible to hold scalars in registers
+/* Define this macro if it is advisable to hold scalars in registers
    in a wider mode than that declared by the program.  In such cases, 
    the value is constrained to be within the bounds of the declared
    type, but kept valid in the wider mode.  The signedness of the
@@ -131,7 +144,7 @@ extern int target_flags;
 #define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE)  \
   if (GET_MODE_CLASS (MODE) == MODE_INT        \
       && GET_MODE_SIZE (MODE) < 4)     \
-    (MODE) == SImode;
+    (MODE) = SImode;
 
 /* Define this if most significant bit is lowest numbered
    in instructions that operate on numbered bit-fields.
@@ -207,7 +220,7 @@ extern int target_flags;
 /* Set this non-zero if unaligned move instructions are extremely slow.
 
    On the 29k, they trap.  */
-#define SLOW_UNALIGNED_ACCESS 1
+#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) 1
 \f
 /* Standard register usage.  */
 
@@ -235,10 +248,14 @@ extern int target_flags;
    Registers 200-203 are the four floating-point accumulator register in
    the 29050.
 
+   Registers 204-235 are the 32 global registers for kernel mode when
+   -mkernel-registers is not specified, and the 32 global user registers
+   when it is.
+
    When -mkernel-registers is specified, we still use the same register
    map but change the names so 0-31 print as gr64-gr95.  */
 
-#define FIRST_PSEUDO_REGISTER 204
+#define FIRST_PSEUDO_REGISTER 236
 
 /* Because of the large number of registers on the 29k, we define macros
    to refer to each group of registers and then define the number for some
@@ -248,6 +265,7 @@ extern int target_flags;
 #define R_LR(N)                ((N) + 32)      /* lr0 is register number 32 */
 #define R_FP           176             /* frame pointer is register 176 */
 #define R_AR(N)                ((N) + 160)     /* first incoming arg reg is 160 */
+#define R_KR(N)                ((N) + 204)     /* kernel registers (gr64 to gr95) */
 
 /* Define the numbers of the special registers.  */
 #define R_BP   177
@@ -279,7 +297,7 @@ extern int target_flags;
 #define R_EXO  199
 
 /* Define the number for floating-point accumulator N.  */
-#define R_ACC(N)       ((N) + 200)
+#define R_ACU(N)       ((N) + 200)
 
 /* Now define the registers used in the calling sequence.  */
 #define R_TAV  R_GR (121)
@@ -307,7 +325,9 @@ extern int target_flags;
   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
   1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
   1, 1, 1, 1, 1, 1, 1, 1,                        \
-  0, 0, 0, 0 }
+  0, 0, 0, 0,                                    \
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
 
 /* 1 for registers not available across function calls.
    These must include the FIXED_REGISTERS and also any
@@ -329,7 +349,9 @@ extern int target_flags;
   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
   1, 1, 1, 1, 1, 1, 1, 1,                        \
-  1, 1, 1, 1 }
+  1, 1, 1, 1,                                    \
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
 
 /* List the order in which to allocate registers.  Each register must be
    listed once, even those in FIXED_REGISTERS.
@@ -373,14 +395,20 @@ extern int target_flags;
    R_LR (117), R_LR (118), R_LR (119), R_LR (120), R_LR (121),         \
    R_LR (122), R_LR (123), R_LR (124), R_LR (124), R_LR (126),         \
    R_LR (127),                                                         \
-   R_ACC (3), R_ACC (2), R_ACC (1), R_ACC (0),                         \
+   R_ACU (3), R_ACU (2), R_ACU (1), R_ACU (0),                         \
    R_GR (112), R_GR (113), R_GR (114), R_GR (115), R_GR (121),         \
    R_GR (122), R_GR (123), R_GR (124), R_GR (125), R_GR (126),         \
    R_GR (127),                                                         \
    R_FP, R_BP, R_FC, R_CR, R_Q,                                                \
    R_VAB, R_OPS, R_CPS, R_CFG, R_CHA, R_CHD, R_CHC, R_RBP, R_TMC,      \
    R_TMR, R_PC0, R_PC1, R_PC2, R_MMU, R_LRU, R_FPE, R_INT, R_FPS,      \
-   R_EXO }
+   R_EXO,                                                              \
+   R_KR (0), R_KR (1), R_KR (2), R_KR (3), R_KR (4), R_KR (5),                 \
+   R_KR (6), R_KR (7), R_KR (8), R_KR (9), R_KR (10), R_KR (11),       \
+   R_KR (12), R_KR (13), R_KR (14), R_KR (15), R_KR (16), R_KR (17),   \
+   R_KR (18), R_KR (19), R_KR (20), R_KR (21), R_KR (22), R_KR (23),   \
+   R_KR (24), R_KR (25), R_KR (26), R_KR (27), R_KR (28), R_KR (29),   \
+   R_KR (30), R_KR (31) }
 
 /* Return number of consecutive hard regs needed starting at reg REGNO
    to hold something of mode MODE.
@@ -388,7 +416,7 @@ extern int target_flags;
    but can be less for certain modes in special long registers.  */
 
 #define HARD_REGNO_NREGS(REGNO, MODE)   \
-  ((REGNO) >= R_ACC (0) ? 1            \
+  ((REGNO) >= R_ACU (0) && (REGNO) <= R_ACU (3)? 1             \
    : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
 
 /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
@@ -405,15 +433,15 @@ extern int target_flags;
    (I'd like to use the "?:" syntax to make this more readable, but Sun's
    compiler doesn't seem to accept it.)  */
 #define HARD_REGNO_MODE_OK(REGNO, MODE)                                \
-  (((REGNO) >= R_ACC (0)                                               \
+(((REGNO) >= R_ACU (0) && (REGNO) <= R_ACU (3)                         \
     && (GET_MODE_CLASS (MODE) == MODE_FLOAT                            \
        || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT))                \
    || ((REGNO) >= R_BP && (REGNO) <= R_CR                              \
        && GET_MODE_CLASS (MODE) == MODE_PARTIAL_INT)                   \
-   || ((REGNO) >= R_Q && (REGNO) < R_ACC (0)                           \
+   || ((REGNO) >= R_Q && (REGNO) < R_ACU (0)                           \
        && GET_MODE_CLASS (MODE) != MODE_FLOAT                          \
        && GET_MODE_CLASS (MODE) != MODE_COMPLEX_FLOAT)                 \
-   || ((REGNO) < R_BP                                                  \
+   || (((REGNO) < R_BP || (REGNO) >= R_KR (0))                          \
        && ((((REGNO) & 1) == 0)                                                \
           || GET_MODE_UNIT_SIZE (MODE) <= UNITS_PER_WORD)))
 
@@ -509,18 +537,18 @@ enum reg_class { NO_REGS, LR0_REGS, GENERAL_REGS, BP_REGS, FC_REGS, CR_REGS,
    of length N_REG_CLASSES.  */
 
 #define REG_CLASS_CONTENTS     \
-  { {0, 0, 0, 0, 0, 0, 0},     \
-    {0, 1, 0, 0, 0, 0, 0},     \
-    {~0, ~0, ~0, ~0, ~0, ~ 0xfffe0000, 0},  \
-    {0, 0, 0, 0, 0, 0x20000, 0},       \
-    {0, 0, 0, 0, 0, 0x40000, 0},       \
-    {0, 0, 0, 0, 0, 0x80000, 0},       \
-    {0, 0, 0, 0, 0, 0x100000, 0},      \
-    {0, 0, 0, 0, 0, 0xfffe0000, 0xff}, \
-    {0, 0, 0, 0, 0, 0, 0x100},         \
-    {0, 0, 0, 0, 0, 0, 0xf00},         \
-    {~0, ~0, ~0, ~0, ~0, ~ 0xfffe0000, 0xf00}, \
-    {~0, ~0, ~0, ~0, ~0, ~0, ~0} }
+  { {0, 0, 0, 0, 0, 0, 0, 0},                             \
+    {0, 1, 0, 0, 0, 0, 0, 0},                             \
+    {~0, ~0, ~0, ~0, ~0, ~ 0xfffe0000, ~ 0xfff, 0xfff},           \
+    {0, 0, 0, 0, 0, 0x20000, 0, 0},                       \
+    {0, 0, 0, 0, 0, 0x40000, 0, 0},                       \
+    {0, 0, 0, 0, 0, 0x80000, 0, 0},                       \
+    {0, 0, 0, 0, 0, 0x100000, 0, 0},                      \
+    {0, 0, 0, 0, 0, 0xfffe0000, 0xff, 0},                 \
+    {0, 0, 0, 0, 0, 0, 0x100, 0},                         \
+    {0, 0, 0, 0, 0, 0, 0xf00, 0},                         \
+    {~0, ~0, ~0, ~0, ~0, ~ 0xfffe0000, ~ 0xff, 0xfff},            \
+    {~0, ~0, ~0, ~0, ~0, ~0, ~0, 0xfff} }
 
 /* The same information, inverted:
    Return the class number of the smallest class containing
@@ -533,8 +561,9 @@ enum reg_class { NO_REGS, LR0_REGS, GENERAL_REGS, BP_REGS, FC_REGS, CR_REGS,
    : (REGNO) == R_CR ? CR_REGS         \
    : (REGNO) == R_Q ? Q_REGS           \
    : (REGNO) > R_BP && (REGNO) <= R_EXO ? SPECIAL_REGS \
-   : (REGNO) == R_ACC (0) ? ACCUM0_REGS        \
-   : (REGNO) > R_ACC (0) ? ACCUM_REGS  \
+   : (REGNO) == R_ACU (0) ? ACCUM0_REGS        \
+   : (REGNO) >= R_KR (0) ? GENERAL_REGS \
+   : (REGNO) > R_ACU (0) ? ACCUM_REGS  \
    : (REGNO) == R_LR (0) ? LR0_REGS    \
    : GENERAL_REGS)
 
@@ -561,21 +590,18 @@ enum reg_class { NO_REGS, LR0_REGS, GENERAL_REGS, BP_REGS, FC_REGS, CR_REGS,
 
    On the 29k, we use this to change the register names for kernel mapping.  */
 
-#define CONDITIONAL_REGISTER_USAGE                                     \
-  {                                                                    \
-    static char *kernel_names[] = {"gr64", "gr65", "gr66", "gr67",     \
-                                  "gr68", "gr69", "gr70", "gr71",      \
-                                  "gr72", "gr73", "gr74", "gr75",      \
-                                  "gr76", "gr77", "gr78", "gr79",      \
-                                  "gr80", "gr81", "gr82", "gr83",      \
-                                  "gr84", "gr85", "gr86", "gr87",      \
-                                  "gr88", "gr89", "gr90", "gr91",      \
-                                  "gr92", "gr93", "gr94", "gr95"};     \
-    int i;                                                             \
-                                                                       \
-    if (TARGET_KERNEL_REGISTERS)                                       \
-      for (i = 0; i < 32; i++)                                         \
-       reg_names[i] = kernel_names[i];                                 \
+#define CONDITIONAL_REGISTER_USAGE             \
+  {                                            \
+    const char *p;                             \
+    int i;                                     \
+                                               \
+    if (TARGET_KERNEL_REGISTERS)               \
+      for (i = 0; i < 32; i++)                 \
+       {                                       \
+         p = reg_names[i];                     \
+         reg_names[i] = reg_names[R_KR (i)];   \
+         reg_names[R_KR (i)] = p;              \
+       }                                       \
   }
 
 /* The letters I, J, K, L, M, N, O, and P in a register constraint string
@@ -628,10 +654,6 @@ enum reg_class { NO_REGS, LR0_REGS, GENERAL_REGS, BP_REGS, FC_REGS, CR_REGS,
 #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
   secondary_reload_class (CLASS, MODE, IN)
 
-/* This function is used to get the address of an object.  */
-
-extern struct rtx_def *a29k_get_reloaded_address ();
-
 /* Return the maximum number of consecutive registers
    needed to represent mode MODE in a register of class CLASS.
 
@@ -649,6 +671,15 @@ extern struct rtx_def *a29k_get_reloaded_address ();
 #define REGISTER_MOVE_COST(CLASS1, CLASS2)     \
   ((CLASS1) == GENERAL_REGS || (CLASS2) == GENERAL_REGS ? 2 : 4)
 
+/* A C expressions returning the cost of moving data of MODE from a register to
+   or from memory.
+
+   It takes extra insns on the 29k to form addresses, so we want to make
+   this higher.  In addition, we need to keep it more expensive than the
+   most expensive register-register copy.  */
+
+#define MEMORY_MOVE_COST(MODE,CLASS,IN) 6
+
 /* A C statement (sans semicolon) to update the integer variable COST
    based on the relationship between INSN that is dependent on
    DEP_INSN through the dependence LINK.  The default is to make no
@@ -685,7 +716,7 @@ extern struct rtx_def *a29k_get_reloaded_address ();
 /* Define this if the maximum size of all the outgoing args is to be
    accumulated and pushed during the prologue.  The amount can be
    found in the variable current_function_outgoing_args_size.  */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
 
 /* Offset of first parameter from the argument pointer register value.  */
 
@@ -697,11 +728,12 @@ extern struct rtx_def *a29k_get_reloaded_address ();
 
 /* Value is the number of bytes 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.  */
 
-#define RETURN_POPS_ARGS(FUNTYPE,SIZE) 0
+#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0
 
 /* Define how to find the value returned by a function.
    VALTYPE is the data type of the value (as a tree).
@@ -711,18 +743,18 @@ extern struct rtx_def *a29k_get_reloaded_address ();
    On 29k the value is found in gr96.  */
 
 #define FUNCTION_VALUE(VALTYPE, FUNC)  \
-  gen_rtx (REG, TYPE_MODE (VALTYPE), R_GR (96))
+  gen_rtx_REG (TYPE_MODE (VALTYPE), R_GR (96))
 
 /* Define how to find the value returned by a library function
    assuming the value has mode MODE.  */
 
-#define LIBCALL_VALUE(MODE)  gen_rtx (REG, MODE, R_GR (96))
+#define LIBCALL_VALUE(MODE)  gen_rtx_REG (MODE, R_GR (96))
 
 /* 1 if N is a possible register number for a function value
    as seen by the caller.
    On 29k, gr96-gr111 are used.  */
 
-#define FUNCTION_VALUE_REGNO_P(N) ((N) < R_GR (112))
+#define FUNCTION_VALUE_REGNO_P(N) ((N) == R_GR (96))
 
 /* 1 if N is a possible register number for function argument passing.
    On 29k, these are lr2-lr17.  */
@@ -745,24 +777,26 @@ extern struct rtx_def *a29k_get_reloaded_address ();
    for a call to a function whose data type is FNTYPE.
    For a library call, FNTYPE is 0.  */
 
-#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME)  (CUM) = 0
+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT)  (CUM) = 0
 
 /* Same, but called for incoming args.
 
    On the 29k, we use this to set all argument registers to fixed and
-   set the last 16 local regs (lr112-lr127) to available.  Some
-   will later be changed to call-saved by FUNCTION_INCOMING_ARG.  */
+   set the last 16 local regs, less two, (lr110-lr125) to available.  Some
+   will later be changed to call-saved by FUNCTION_INCOMING_ARG.
+   lr126,lr127 are always fixed, they are place holders for the caller's
+   lr0,lr1.  */
 
-#define INIT_CUMULATIVE_INCOMING_ARGS(CUM,FNTYPE,IGNORE)               \
+#define INIT_CUMULATIVE_INCOMING_ARGS(CUM,FNTYPE,IGNORE)       \
 { int i;                                                       \
-  for (i = R_AR (0); i < R_AR (16); i++)                       \
+  for (i = R_AR (0) - 2; i < R_AR (16); i++)                   \
     {                                                          \
       fixed_regs[i] = call_used_regs[i] = call_fixed_regs[i] = 1; \
       SET_HARD_REG_BIT (fixed_reg_set, i);                     \
       SET_HARD_REG_BIT (call_used_reg_set, i);                 \
       SET_HARD_REG_BIT (call_fixed_reg_set, i);                        \
     }                                                          \
-  for (i = R_LR (112); i < R_LR (128); i++)                                    \
+  for (i = R_LR (110); i < R_LR (126); i++)                                    \
     {                                                          \
       fixed_regs[i] = call_used_regs[i] = call_fixed_regs[i] = 0; \
       CLEAR_HARD_REG_BIT (fixed_reg_set, i);                   \
@@ -809,7 +843,7 @@ extern struct rtx_def *a29k_get_reloaded_address ();
 
 #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED)                   \
 ((CUM) < 16 && (NAMED) && ! MUST_PASS_IN_STACK (MODE, TYPE)    \
- ? gen_rtx(REG, (MODE), R_LR (2) + (CUM)) : 0)
+ ? gen_rtx_REG ((MODE), R_LR (2) + (CUM)) : 0)
 
 /* Define where a function finds its arguments.
    This is different from FUNCTION_ARG because of register windows.
@@ -819,8 +853,8 @@ extern struct rtx_def *a29k_get_reloaded_address ();
 
 #define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED)                  \
 ((CUM) < 16 && (NAMED) && ! MUST_PASS_IN_STACK (MODE, TYPE)            \
- ? gen_rtx (REG, MODE,                                                 \
-           incoming_reg (CUM, A29K_ARG_SIZE (MODE, TYPE, NAMED)))      \
+ ? gen_rtx_REG (MODE,                                                  \
+               incoming_reg (CUM, A29K_ARG_SIZE (MODE, TYPE, NAMED)))  \
  : 0)
 
 /* This indicates that an argument is to be passed with an invisible reference
@@ -874,8 +908,8 @@ extern struct rtx_def *a29k_get_reloaded_address ();
       if (! (NO_RTL) && first_reg_offset != 16)                                \
        move_block_from_reg                                             \
          (R_AR (0) + first_reg_offset,                                 \
-          gen_rtx (MEM, BLKmode, virtual_incoming_args_rtx),           \
-          16 - first_reg_offset);                                      \
+          gen_rtx_MEM (BLKmode, virtual_incoming_args_rtx),            \
+          16 - first_reg_offset, (16 - first_reg_offset) * UNITS_PER_WORD); \
       PRETEND_SIZE = (16 - first_reg_offset) * UNITS_PER_WORD;         \
     }                                                                  \
 }
@@ -891,12 +925,15 @@ extern int a29k_compare_fp_p;
 
    For the 29k, we need the prolog to contain one or two words prior to
    the declaration of the function name.  So just store away the name and
-   write it as part of the prolog.  */
+   write it as part of the prolog.  This also computes the register names,
+   which can't be done until after register allocation, but must be done
+   before final_start_function is called.  */
 
-extern char *a29k_function_name;
+extern const char *a29k_function_name;
 
 #define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL)      \
-  a29k_function_name = NAME;
+  a29k_function_name = NAME; \
+  a29k_compute_reg_names ();
 
 /* This macro generates the assembly code for function entry.
    FILE is a stdio stream to output the code to.
@@ -947,13 +984,18 @@ extern char *a29k_function_name;
 
    On the 29k, we must be able to place it in a delay slot, it must
    not use sp if the frame pointer cannot be eliminated, and it cannot
-   use local regs if we need to push the register stack.  */
+   use local regs if we need to push the register stack.
+   If this is a SET with a memory as source, it might load from
+   a stack slot, unless the address is constant.  */
 
 #define ELIGIBLE_FOR_EPILOGUE_DELAY(INSN,N)                            \
   (get_attr_in_delay_slot (INSN) == IN_DELAY_SLOT_YES                  \
    && ! (frame_pointer_needed                                          \
         && reg_mentioned_p (stack_pointer_rtx, PATTERN (INSN)))        \
-   && ! (needs_regstack_p () && uses_local_reg_p (PATTERN (INSN))))
+   && ! (needs_regstack_p () && uses_local_reg_p (PATTERN (INSN)))     \
+   && (GET_CODE (PATTERN (INSN)) != SET                                        \
+       || GET_CODE (SET_SRC (PATTERN (INSN))) != MEM                   \
+       || ! rtx_varies_p (XEXP (SET_SRC (PATTERN (INSN)), 0))))
 \f
 /* Output assembler code for a block containing the constant parts
    of a trampoline, leaving space for the variable parts.
@@ -998,35 +1040,35 @@ extern char *a29k_function_name;
   rtx _val = force_reg (SImode, VALUE);                                        \
                                                                        \
   _addr = memory_address (QImode, plus_constant (TRAMP, (CONST) + 3)); \
-  emit_move_insn (gen_rtx (MEM, QImode, _addr),                                \
+  emit_move_insn (gen_rtx_MEM (QImode, _addr),                         \
                  gen_lowpart (QImode, _val));                          \
                                                                        \
   _temp = expand_shift (RSHIFT_EXPR, SImode, _val,                     \
                       build_int_2 (8, 0), 0, 1);                       \
   _addr = memory_address (QImode, plus_constant (TRAMP, (CONST) + 1)); \
-  emit_move_insn (gen_rtx (MEM, QImode, _addr),                                \
+  emit_move_insn (gen_rtx_MEM (QImode, _addr),                         \
                  gen_lowpart (QImode, _temp));                         \
                                                                        \
   _temp = expand_shift (RSHIFT_EXPR, SImode, _temp,                    \
                       build_int_2 (8, 0), _temp, 1);                   \
   _addr = memory_address (QImode, plus_constant (TRAMP, (CONSTH) + 3));        \
-  emit_move_insn (gen_rtx (MEM, QImode, _addr),                                \
+  emit_move_insn (gen_rtx_MEM (QImode, _addr),                         \
                  gen_lowpart (QImode, _temp));                         \
                                                                        \
   _temp = expand_shift (RSHIFT_EXPR, SImode, _temp,                    \
                       build_int_2 (8, 0), _temp, 1);                   \
   _addr = memory_address (QImode, plus_constant (TRAMP, (CONSTH) + 1));        \
-  emit_move_insn (gen_rtx (MEM, QImode, _addr),                                \
+  emit_move_insn (gen_rtx_MEM (QImode, _addr),                         \
                  gen_lowpart (QImode, _temp));                         \
 }
 \f
 /* Addressing modes, and classification of registers for them.  */
 
-/* #define HAVE_POST_INCREMENT */
-/* #define HAVE_POST_DECREMENT */
+/* #define HAVE_POST_INCREMENT */
+/* #define HAVE_POST_DECREMENT */
 
-/* #define HAVE_PRE_DECREMENT */
-/* #define HAVE_PRE_INCREMENT */
+/* #define HAVE_PRE_DECREMENT */
+/* #define HAVE_PRE_INCREMENT */
 
 /* Macros to check register numbers against specific register classes.  */
 
@@ -1055,10 +1097,10 @@ extern char *a29k_function_name;
 /* Maximum number of registers that can appear in a valid memory address.  */
 #define MAX_REGS_PER_ADDRESS 1
 
-/* Recognize any constant value that is a valid address.
+/* Recognize any constant value that is a valid address.  */
 
-   None are on the 29K.  */
-#define CONSTANT_ADDRESS_P(X)  0
+#define CONSTANT_ADDRESS_P(X)  \
+(GET_CODE (X) == CONST_INT && (unsigned) INTVAL (X) < 0x100)
 
 /* Include all constant integers and constant doubles */
 #define LEGITIMATE_CONSTANT_P(X)       1
@@ -1162,10 +1204,11 @@ extern char *a29k_function_name;
    for the index in the tablejump instruction.  */
 #define CASE_VECTOR_MODE SImode
 
-/* Define this if the tablejump instruction expects the table
-   to contain offsets from the address of the table.
-   Do not define this if the table should contain absolute addresses.  */
-/* #define CASE_VECTOR_PC_RELATIVE */
+/* Define as C expression which evaluates to nonzero if the tablejump
+   instruction expects the table to contain offsets from the address of the
+   table.
+   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
@@ -1202,9 +1245,18 @@ extern char *a29k_function_name;
    manipulate fields.  */
 #define SLOW_BYTE_ACCESS       0
 
-/* Define if normal loads of shorter-than-word items from memory clears
-   the rest of the bigs in the register.  */
-#define BYTE_LOADS_ZERO_EXTEND
+/* Define if operations between registers always perform the operation
+   on the full register even if a narrower mode is specified.  */
+#define WORD_REGISTER_OPERATIONS
+
+/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD
+   will either zero-extend or sign-extend.  The value of this macro should
+   be the code that says which one of the two operations is implicitly
+   done, NIL if none.  */
+#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
+
+/* Define if the object format being used is COFF or a superset.  */
+#define OBJECT_FORMAT_COFF
 
 /* This uses COFF, so it wants SDB format.  */
 #define SDB_DEBUGGING_INFO
@@ -1226,9 +1278,10 @@ extern char *a29k_function_name;
 #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
 
 /* We assume that the store-condition-codes instructions store 0 for false
-   and some other value for true.  This is the value stored for true.  */
+   and some other value for true.  This is the value stored for true, which
+   is just the sign bit.  */
 
-#define STORE_FLAG_VALUE 0x80000000
+#define STORE_FLAG_VALUE (-2147483647 - 1)
 
 /* Specify the machine mode that pointers have.
    After generation of rtl, the compiler makes no further distinction
@@ -1246,9 +1299,9 @@ extern char *a29k_function_name;
    but a CALL with constant address is cheap.  */
 #define NO_FUNCTION_CSE
 
-/* Define this if shift instructions ignore all but the low-order
+/* Define this to be nonzero if shift instructions ignore all but the low-order
    few bits. */
-#define SHIFT_COUNT_TRUNCATED
+#define SHIFT_COUNT_TRUNCATED 1
 
 /* Compute the cost of computing a constant rtl expression RTX
    whose rtx-code is CODE.  The body of this macro is a portion
@@ -1300,7 +1353,9 @@ extern char *a29k_function_name;
   for (p = main_input_filename; *p; p++)                       \
     if (*p == '/')                                             \
       after_dir = p + 1;                                       \
-  fprintf (FILE, "\t.file \"%s\"\n", after_dir);               \
+  fprintf (FILE, "\t.file ");                                  \
+  output_quoted_string (FILE, after_dir);                      \
+  fprintf (FILE, "\n");                                                \
   fprintf (FILE, "\t.sect .lit,lit\n"); }
 
 /* Output to assembler file text saying following lines
@@ -1346,6 +1401,16 @@ literal_section ()                                               \
 
 #define READONLY_DATA_SECTION  literal_section
 
+/* If we are referencing a function that is static or is known to be
+   in this file, make the SYMBOL_REF special.  We can use this to indicate
+   that we can branch to this function without emitting a no-op after the
+   call.  */
+
+#define ENCODE_SECTION_INFO(DECL)  \
+  if (TREE_CODE (DECL) == FUNCTION_DECL                        \
+      && (TREE_ASM_WRITTEN (DECL) || ! TREE_PUBLIC (DECL))) \
+    SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1;
+
 /* How to refer to registers in assembler output.
    This sequence is indexed by compiler's hard-register-number (see above).  */
 
@@ -1374,13 +1439,23 @@ literal_section ()                                              \
   "bp", "fc", "cr", "q",                                                \
   "vab", "ops", "cps", "cfg", "cha", "chd", "chc", "rbp", "tmc", "tmr",         \
   "pc0", "pc1", "pc2", "mmu", "lru", "fpe", "int", "fps", "exo",        \
-  "0", "1", "2", "3" }
+  "0", "1", "2", "3",                                                   \
+  "gr64", "gr65", "gr66", "gr67", "gr68", "gr69", "gr70", "gr71",       \
+  "gr72", "gr73", "gr74", "gr75", "gr76", "gr77", "gr78", "gr79",       \
+  "gr80", "gr81", "gr82", "gr83", "gr84", "gr85", "gr86", "gr87",       \
+  "gr88", "gr89", "gr90", "gr91", "gr92", "gr93", "gr94", "gr95" }
 
 /* How to renumber registers for dbx and gdb.  */
 
 extern int a29k_debug_reg_map[];
 #define DBX_REGISTER_NUMBER(REGNO) a29k_debug_reg_map[REGNO]
 
+/* This how to write an assembler directive to FILE to switch to
+   section NAME for DECL.  */
+
+#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \
+  fprintf (FILE, "\t.sect %s, bss\n\t.use %s\n", NAME, NAME)
+
 /* This is how to output the definition of a user-level label named NAME,
    such as the label on a static function or variable NAME.  */
 
@@ -1393,11 +1468,10 @@ extern int a29k_debug_reg_map[];
 #define ASM_GLOBALIZE_LABEL(FILE,NAME) \
   do { fputs ("\t.global ", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE);} while (0)
 
-/* This is how to output a reference to a user-level label named NAME.
-   `assemble_name' uses this.  */
+/* The prefix to add to user-visible assembler symbols. */
 
-#define ASM_OUTPUT_LABELREF(FILE,NAME) \
-  fprintf (FILE, "_%s", NAME)
+#undef USER_LABEL_PREFIX
+#define USER_LABEL_PREFIX "_"
 
 /* This is how to output an internal numbered label where
    PREFIX is the class of label and NUM is the number within the class.  */
@@ -1476,10 +1550,9 @@ extern int a29k_debug_reg_map[];
   fprintf (FILE, "\t.word L%d\n", VALUE)
 
 /* This is how to output an element of a case-vector that is relative.
-   (29k does not use such vectors,
-   but we must define this macro anyway.)  */
+   Don't define this if it is not supported. */
 
-#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL)  abort ()
+/* #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) */
 
 /* This is how to output an assembler line
    that says to advance the location counter
@@ -1563,18 +1636,22 @@ extern int a29k_debug_reg_map[];
   {"long_const_operand", {CONST_INT, CONST, CONST_DOUBLE,      \
                          LABEL_REF, SYMBOL_REF}},              \
   {"shift_constant_operand", {CONST_INT, ASHIFT}},             \
-  {"const_0__operand", {CONST_INT, ASHIFT}},                   \
-  {"const_8__operand", {CONST_INT, ASHIFT}},                   \
-  {"const_16__operand", {CONST_INT, ASHIFT}},                  \
-  {"const_24__operand", {CONST_INT, ASHIFT}},                  \
+  {"const_0_operand", {CONST_INT, ASHIFT}},                    \
+  {"const_8_operand", {CONST_INT, ASHIFT}},                    \
+  {"const_16_operand", {CONST_INT, ASHIFT}},                   \
+  {"const_24_operand", {CONST_INT, ASHIFT}},                   \
   {"float_const_operand", {CONST_DOUBLE}},                     \
   {"gpc_reg_operand", {SUBREG, REG}},                          \
   {"gpc_reg_or_float_constant_operand", {SUBREG, REG, CONST_DOUBLE}}, \
   {"gpc_reg_or_integer_constant_operand", {SUBREG, REG,                \
                                           CONST_INT, CONST_DOUBLE}}, \
+  {"gpc_reg_or_immediate_operand", {SUBREG, REG, CONST_INT,    \
+                                   CONST_DOUBLE, CONST,        \
+                                   SYMBOL_REF, LABEL_REF}},    \
   {"spec_reg_operand", {REG}},                                 \
   {"accum_reg_operand", {REG}},                                        \
   {"srcb_operand", {SUBREG, REG, CONST_INT}},                  \
+  {"cmplsrcb_operand", {SUBREG, REG, CONST_INT}},              \
   {"reg_or_immediate_operand", {SUBREG, REG, CONST_INT, CONST, \
                                CONST_DOUBLE, CONST, SYMBOL_REF, LABEL_REF}}, \
   {"reg_or_u_short_operand", {SUBREG, REG, CONST_INT}},                \
@@ -1587,4 +1664,6 @@ extern int a29k_debug_reg_map[];
   {"reload_memory_operand", {SUBREG, REG, MEM}},               \
   {"fp_comparison_operator", {EQ, GT, GE}},                    \
   {"branch_operator", {GE, LT}},                               \
+  {"load_multiple_operation", {PARALLEL}},                     \
+  {"store_multiple_operation", {PARALLEL}},                    \
   {"epilogue_operand", {CODE_LABEL}},