/* Definitions of target machine for GNU compiler.
- Hitachi H8/300 (generic)
+ Renesas H8/300 (generic)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Steve Chamberlain (sac@cygnus.com),
Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
/* Print subsidiary information on the compiler version in use. */
-#define TARGET_VERSION fprintf (stderr, " (Hitachi H8/300)");
+#define TARGET_VERSION fprintf (stderr, " (Renesas H8/300)");
/* Run-time compilation parameters selecting different hardware subsets. */
#define BYTES_BIG_ENDIAN 1
/* Define this if most significant word of a multiword number is lowest
- numbered.
- This is true on an H8/300 (actually we can make it up, but we choose to
- be consistent). */
+ numbered. */
#define WORDS_BIG_ENDIAN 1
#define MAX_BITS_PER_WORD 32
eliminated during reloading in favor of either the stack or frame
pointer. */
-#define FIRST_PSEUDO_REGISTER 11
+#define FIRST_PSEUDO_REGISTER 12
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator. */
&& ((MODE2) == QImode || (MODE2) == HImode \
|| ((TARGET_H8300H || TARGET_H8300S) && (MODE2) == SImode))))
+/* A C expression that is nonzero if hard register NEW_REG can be
+ considered for use as a rename register for OLD_REG register */
+
+#define HARD_REGNO_RENAME_OK(OLD_REG, NEW_REG) \
+ h8300_hard_regno_rename_ok (OLD_REG, NEW_REG)
+
/* Specify the registers used for certain standard purposes.
The values of these macros are register numbers. */
#define STACK_POINTER_REGNUM SP_REG
/* Base register for access to local variables of the function. */
+#define HARD_FRAME_POINTER_REGNUM HFP_REG
+
+/* Base register for access to local variables of the function. */
#define FRAME_POINTER_REGNUM FP_REG
/* Value should be nonzero if functions must have frame pointers.
followed by "to". Eliminations of the same "from" register are listed
in order of preference.
- We have two registers that can be eliminated on the h8300. First, the
- frame pointer register can often be eliminated in favor of the stack
- pointer register. Secondly, the argument pointer register can always be
- eliminated; it is replaced with either the stack or frame pointer. */
+ We have three registers that can be eliminated on the h8300.
+ First, the frame pointer register can often be eliminated in favor
+ of the stack pointer register. Secondly, the argument pointer
+ register and the return address pointer register are always
+ eliminated; they are replaced with either the stack or frame
+ pointer. */
-#define ELIMINABLE_REGS \
-{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
- { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
- { RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM},\
- { RETURN_ADDRESS_POINTER_REGNUM, FRAME_POINTER_REGNUM},\
- { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}
+#define ELIMINABLE_REGS \
+{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
+ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
+ { RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
+ { RETURN_ADDRESS_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
+ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
+ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
/* Given FROM and TO register numbers, say whether this elimination is allowed.
Frame pointer elimination is automatically handled.
On the H8 the return value is in R0/R1. */
#define FUNCTION_VALUE(VALTYPE, FUNC) \
- gen_rtx_REG (TYPE_MODE (VALTYPE), 0)
+ gen_rtx_REG (TYPE_MODE (VALTYPE), R0_REG)
/* Define how to find the value returned by a library function
assuming the value has mode MODE. */
/* On the H8 the return value is in R0/R1. */
#define LIBCALL_VALUE(MODE) \
- gen_rtx_REG (MODE, 0)
+ gen_rtx_REG (MODE, R0_REG)
/* 1 if N is a possible register number for a function value.
On the H8, R0 is the only register thus used. */
-#define FUNCTION_VALUE_REGNO_P(N) ((N) == 0)
+#define FUNCTION_VALUE_REGNO_P(N) ((N) == R0_REG)
/* Define this if PCC uses the nonreentrant convention for returning
structure and union values. */
#define FUNCTION_ARG_REGNO_P(N) (TARGET_QUICKCALL ? N < 3 : 0)
-/* Register in which address to store a structure value
- is passed to a function. */
-
-#define STRUCT_VALUE 0
-
-/* Return true if X should be returned in memory. */
-#define RETURN_IN_MEMORY(X) \
- (TYPE_MODE (X) == BLKmode \
- || GET_MODE_SIZE (TYPE_MODE (X)) > (TARGET_H8300 ? 4 : 8))
-
/* When defined, the compiler allows registers explicitly used in the
rtl to be used as spill registers but prevents the compiler from
extending the lifetime of these registers. */
/* Length in units of the trampoline for entering a nested function. */
-#define TRAMPOLINE_SIZE ((TARGET_H8300 || TARGET_NORMAL_MODE) ? 8 : 12)
+#define TRAMPOLINE_SIZE ((Pmode == HImode) ? 8 : 12)
/* Emit RTL insns to build a trampoline.
FNADDR is an RTX for the address of the function's pure code.
#define REGNO_OK_FOR_INDEX_P(regno) 0
-#define REGNO_OK_FOR_BASE_P(regno) \
- (((regno) < FIRST_PSEUDO_REGISTER && regno != 8) || reg_renumber[regno] >= 0)
+#define REGNO_OK_FOR_BASE_P(regno) \
+ (((regno) < FIRST_PSEUDO_REGISTER && regno != MAC_REG) \
+ || reg_renumber[regno] >= 0)
\f
/* Maximum number of registers that can appear in a valid memory address. */
/* Nonzero if the constant value X is a legitimate general operand.
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
-#define LEGITIMATE_CONSTANT_P(X) (1)
+#define LEGITIMATE_CONSTANT_P(X) (h8300_legitimate_constant_p (X))
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
After reload, it makes no difference, since pseudo regs have
been eliminated by then. */
+/* Non-strict versions. */
+#define REG_OK_FOR_INDEX_NONSTRICT_P(X) 0
+/* Don't use REGNO_OK_FOR_BASE_P here because it uses reg_renumber. */
+#define REG_OK_FOR_BASE_NONSTRICT_P(X) \
+ (REGNO (X) >= FIRST_PSEUDO_REGISTER || REGNO (X) != 8)
+
+/* Strict versions. */
+#define REG_OK_FOR_INDEX_STRICT_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
+#define REG_OK_FOR_BASE_STRICT_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
+
#ifndef REG_OK_STRICT
-/* Nonzero if X is a hard reg that can be used as an index
- or if it is a pseudo reg. */
-#define REG_OK_FOR_INDEX_P(X) 0
-/* Nonzero if X is a hard reg that can be used as a base reg
- or if it is a pseudo reg. */
-/* Don't use REGNO_OK_FOR_BASE_P here because it uses reg_renumber. */
-#define REG_OK_FOR_BASE_P(X) \
- (REGNO (X) >= FIRST_PSEUDO_REGISTER || REGNO (X) != 8)
-#define REG_OK_FOR_INDEX_P_STRICT(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
-#define REG_OK_FOR_BASE_P_STRICT(X) REGNO_OK_FOR_BASE_P (REGNO (X))
-#define STRICT 0
+#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_INDEX_NONSTRICT_P (X)
+#define REG_OK_FOR_BASE_P(X) REG_OK_FOR_BASE_NONSTRICT_P (X)
#else
-/* Nonzero if X is a hard reg that can be used as an index. */
-#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
-/* Nonzero if X is a hard reg that can be used as a base reg. */
-#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
-#define STRICT 1
+#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_INDEX_STRICT_P (X)
+#define REG_OK_FOR_BASE_P(X) REG_OK_FOR_BASE_STRICT_P (X)
#endif
(C) == 'U' ? OK_FOR_U (OP) : \
0)
\f
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
- that is a valid memory address for an instruction.
- The MODE argument is the machine mode for the MEM expression
- that wants to use this address.
-
- The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS,
- except for CONSTANT_ADDRESS_P which is actually
- machine-independent.
-
- On the H8/300, a legitimate address has the form
- REG, REG+CONSTANT_ADDRESS or CONSTANT_ADDRESS. */
-
-/* Accept either REG or SUBREG where a register is valid. */
-
-#define RTX_OK_FOR_BASE_P(X) \
- ((REG_P (X) && REG_OK_FOR_BASE_P (X)) \
- || (GET_CODE (X) == SUBREG && REG_P (SUBREG_REG (X)) \
- && REG_OK_FOR_BASE_P (SUBREG_REG (X))))
-
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
- if (RTX_OK_FOR_BASE_P (X)) goto ADDR; \
- if (CONSTANT_ADDRESS_P (X)) goto ADDR; \
- if (GET_CODE (X) == PLUS \
- && CONSTANT_ADDRESS_P (XEXP (X, 1)) \
- && RTX_OK_FOR_BASE_P (XEXP (X, 0))) goto ADDR;
+#ifndef REG_OK_STRICT
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
+ do \
+ { \
+ if (h8300_legitimate_address_p ((X), 0)) \
+ goto ADDR; \
+ } \
+ while (0)
+#else
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
+ do \
+ { \
+ if (h8300_legitimate_address_p ((X), 1)) \
+ goto ADDR; \
+ } \
+ while (0)
+#endif
\f
/* Try machine-dependent ways of modifying an illegitimate address
to be legitimate. If we find one, return the new, valid address.
#undef DO_GLOBAL_CTORS_BODY
#define DO_GLOBAL_CTORS_BODY \
{ \
- typedef (*pfunc)(); \
- extern pfunc __ctors[]; \
- extern pfunc __ctors_end[]; \
- pfunc *p; \
+ extern func_ptr __ctors[]; \
+ extern func_ptr __ctors_end[]; \
+ func_ptr *p; \
for (p = __ctors_end; p > __ctors; ) \
{ \
(*--p)(); \
#undef DO_GLOBAL_DTORS_BODY
#define DO_GLOBAL_DTORS_BODY \
{ \
- typedef (*pfunc)(); \
- extern pfunc __dtors[]; \
- extern pfunc __dtors_end[]; \
- pfunc *p; \
+ extern func_ptr __dtors[]; \
+ extern func_ptr __dtors_end[]; \
+ func_ptr *p; \
for (p = __dtors; p < __dtors_end; p++) \
{ \
(*p)(); \
This sequence is indexed by compiler's hard-register-number (see above). */
#define REGISTER_NAMES \
-{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "sp", "mac", "ap", "rap" }
+{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "sp", "mac", "ap", "rap", "fp" }
#define ADDITIONAL_REGISTER_NAMES \
{ {"er0", 0}, {"er1", 1}, {"er2", 2}, {"er3", 3}, {"er4", 4}, \
#define TARGET_MEM_FUNCTIONS
-#define MULHI3_LIBCALL "__mulhi3"
-#define DIVHI3_LIBCALL "__divhi3"
-#define UDIVHI3_LIBCALL "__udivhi3"
-#define MODHI3_LIBCALL "__modhi3"
-#define UMODHI3_LIBCALL "__umodhi3"
-
-/* Perform target dependent optabs initialization. */
-
-#define INIT_TARGET_OPTABS \
- do \
- { \
- smul_optab->handlers[(int) HImode].libfunc \
- = init_one_libfunc (MULHI3_LIBCALL); \
- sdiv_optab->handlers[(int) HImode].libfunc \
- = init_one_libfunc (DIVHI3_LIBCALL); \
- udiv_optab->handlers[(int) HImode].libfunc \
- = init_one_libfunc (UDIVHI3_LIBCALL); \
- smod_optab->handlers[(int) HImode].libfunc \
- = init_one_libfunc (MODHI3_LIBCALL); \
- umod_optab->handlers[(int) HImode].libfunc \
- = init_one_libfunc (UMODHI3_LIBCALL); \
- } \
- while (0)
-
#define MOVE_RATIO 3
/* Define the codes that are matched by predicates in h8300.c. */