/* 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.
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
#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 */
#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
#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.
/* 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. */
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
#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
#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)
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
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.
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.
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.
(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)))
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
: (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)
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
#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.
#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
/* 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. */
/* 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).
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. */
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); \
#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.
#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
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; \
} \
}
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.
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.
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 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. */
/* 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
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
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
#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
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
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
#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). */
"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. */
#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. */
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
{"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}}, \
{"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}},