X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gcc%2Fconfig%2Fa29k%2Fa29k.h;h=d7a2bd426f45aa24d58005aad010e350830eb815;hb=f73ad30e011e5fa64e634e576bd6297b667f9364;hp=98f9a8d195da3712a5c87508cc76c51a58c59ea9;hpb=767880cde63ffbd42f89c2aee7aa8b09c2398ca6;p=gcc.git diff --git a/gcc/config/a29k/a29k.h b/gcc/config/a29k/a29k.h index 98f9a8d195d..d7a2bd426f4 100644 --- a/gcc/config/a29k/a29k.h +++ b/gcc/config/a29k/a29k.h @@ -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 /* 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)))) /* 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)); \ } /* Addressing modes, and classification of registers for them. */ -/* #define HAVE_POST_INCREMENT */ -/* #define HAVE_POST_DECREMENT */ +/* #define HAVE_POST_INCREMENT 0 */ +/* #define HAVE_POST_DECREMENT 0 */ -/* #define HAVE_PRE_DECREMENT */ -/* #define HAVE_PRE_INCREMENT */ +/* #define HAVE_PRE_DECREMENT 0 */ +/* #define HAVE_PRE_INCREMENT 0 */ /* 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