Convert ACCUMULATE_OUTGOING_ARGS to an expression.
[gcc.git] / gcc / config / a29k / a29k.h
index 98f9a8d195da3712a5c87508cc76c51a58c59ea9..d7a2bd426f45aa24d58005aad010e350830eb815 100644 (file)
@@ -1,5 +1,6 @@
 /* Definitions of target machine for GNU compiler, for AMD Am29000 CPU.
-   Copyright (C) 1988, 90-94, 1995 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,7 +17,8 @@ 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.  */
@@ -90,26 +92,32 @@ extern int target_flags;
 
 #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},                      \
-    {"normal", - (4|8)},               \
-    {"large", 8},                      \
-    {"29050", 16+128},                 \
-    {"29000", -16},                    \
-    {"kernel-registers", 32},          \
-    {"user-registers", -32},           \
-    {"stack-check", 64},               \
-    {"no-stack-check", - 74},          \
-    {"storem-bug", -128},              \
-    {"no-storem-bug", 128},            \
-    {"reuse-arg-regs", -256},          \
-    {"no-reuse-arg-regs", 256},                \
-    {"soft-float", 512},               \
-    {"", 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
 
@@ -212,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.  */
 
@@ -584,7 +592,7 @@ enum reg_class { NO_REGS, LR0_REGS, GENERAL_REGS, BP_REGS, FC_REGS, CR_REGS,
 
 #define CONDITIONAL_REGISTER_USAGE             \
   {                                            \
-    char *p;                                   \
+    const char *p;                             \
     int i;                                     \
                                                \
     if (TARGET_KERNEL_REGISTERS)               \
@@ -646,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.
 
@@ -674,7 +678,7 @@ extern struct rtx_def *a29k_get_reloaded_address ();
    this higher.  In addition, we need to keep it more expensive than the
    most expensive register-register copy.  */
 
-#define MEMORY_MOVE_COST(MODE) 6
+#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
@@ -712,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.  */
 
@@ -724,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).
@@ -738,12 +743,12 @@ 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.
@@ -772,7 +777,7 @@ 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.
 
@@ -838,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.
@@ -848,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
@@ -903,7 +908,7 @@ 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),           \
+          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;         \
     }                                                                  \
@@ -920,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.
@@ -976,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.
@@ -1027,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.  */
 
@@ -1084,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
@@ -1191,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
@@ -1264,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
@@ -1435,6 +1450,12 @@ literal_section ()                                               \
 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.  */
 
@@ -1447,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.  */
@@ -1530,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