/* Definitions of target machine for GNU compiler for Renesas / SuperH SH.
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004, 2005 Free Software Foundation, Inc.
+ 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Contributed by Steve Chamberlain (sac@cygnus.com).
Improved by Jim Wilson (wilson@cygnus.com).
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
#ifndef GCC_SH_H
#define GCC_SH_H
+#include "config/vxworks-dummy.h"
+
#define TARGET_VERSION \
fputs (" (Hitachi SH)", stderr);
builtin_define ("__HITACHI__"); \
builtin_define (TARGET_LITTLE_ENDIAN \
? "__LITTLE_ENDIAN__" : "__BIG_ENDIAN__"); \
- if (flag_pic) \
- { \
- builtin_define ("__pic__"); \
- builtin_define ("__PIC__"); \
- } \
} while (0)
/* We can not debug without a frame pointer. */
#define TARGET_HARVARD (TARGET_HARD_SH4 || TARGET_SH5)
/* Nonzero if a double-precision FPU is available. */
-#define TARGET_FPU_DOUBLE (TARGET_SH4 || TARGET_SH2A_DOUBLE)
+#define TARGET_FPU_DOUBLE \
+ ((target_flags & MASK_SH4) != 0 || TARGET_SH2A_DOUBLE)
/* Nonzero if an FPU is available. */
#define TARGET_FPU_ANY (TARGET_SH2E || TARGET_FPU_DOUBLE)
#define TARGET_DIVIDE_INV20L (sh_div_strategy == SH_DIV_INV20L)
#define TARGET_DIVIDE_INV_CALL (sh_div_strategy == SH_DIV_INV_CALL)
#define TARGET_DIVIDE_INV_CALL2 (sh_div_strategy == SH_DIV_INV_CALL2)
+#define TARGET_DIVIDE_CALL_DIV1 (sh_div_strategy == SH_DIV_CALL_DIV1)
+#define TARGET_DIVIDE_CALL_FP (sh_div_strategy == SH_DIV_CALL_FP)
+#define TARGET_DIVIDE_CALL_TABLE (sh_div_strategy == SH_DIV_CALL_TABLE)
#define SELECT_SH1 (MASK_SH1)
#define SELECT_SH2 (MASK_SH2 | SELECT_SH1)
#endif
#if SUPPORT_SH2
#define SUPPORT_SH3 1
+#define SUPPORT_SH2A_NOFPU 1
#endif
#if SUPPORT_SH3
#define SUPPORT_SH4_NOFPU 1
#if SUPPORT_SH4_NOFPU
#define SUPPORT_SH4A_NOFPU 1
#define SUPPORT_SH4AL 1
-#define SUPPORT_SH2A_NOFPU 1
#endif
#if SUPPORT_SH2E
#define SUPPORT_SH3E 1
+#define SUPPORT_SH2A_SINGLE_ONLY 1
#endif
#if SUPPORT_SH3E
#define SUPPORT_SH4_SINGLE_ONLY 1
+#endif
+#if SUPPORT_SH4_SINGLE_ONLY
#define SUPPORT_SH4A_SINGLE_ONLY 1
-#define SUPPORT_SH2A_SINGLE_ONLY 1
#endif
#if SUPPORT_SH4
#define TARGET_DEFAULT \
(TARGET_CPU_DEFAULT | TARGET_ENDIAN_DEFAULT | TARGET_OPT_DEFAULT)
-#ifndef SUBTARGET_OPTIONS
-#define SUBTARGET_OPTIONS
-#endif
-
-#define TARGET_OPTIONS \
-{ { "ultcost=", &sh_multcost_str, \
- N_("Cost to assume for a multiply insn"), 0 }, \
- { "gettrcost=", &sh_gettrcost_str, \
- N_("Cost to assume for gettr insn"), 0 }, \
- { "div=", &sh_div_str, \
- N_("division strategy, one of: call, call2, fp, inv, inv:minlat, inv20u, inv20l, inv:call, inv:call2, inv:fp"), 0 }, \
- { "divsi3_libfunc=", &sh_divsi3_libfunc, \
- N_("Specify name for 32 bit signed division function"), 0 }, \
- { "cut2-workaround", &cut2_workaround_str, \
- N_("Enable SH5 cut2 workaround"), "\1" }, \
- SUBTARGET_OPTIONS \
-}
-
-#define TARGET_SH5_CUT2_WORKAROUND (*cut2_workaround_str)
-
#ifndef SH_MULTILIB_CPU_DEFAULT
#define SH_MULTILIB_CPU_DEFAULT "m1"
#endif
SUBTARGET_EXTRA_SPECS
#if TARGET_CPU_DEFAULT & MASK_HARD_SH4
-#define SUBTARGET_ASM_RELAX_SPEC "%{!m1:%{!m2:%{!m3*:%{!m5*:-isa=sh4}}}}"
+#define SUBTARGET_ASM_RELAX_SPEC "%{!m1:%{!m2:%{!m3*:%{!m5*:-isa=sh4-up}}}}"
#else
-#define SUBTARGET_ASM_RELAX_SPEC "%{m4*:-isa=sh4}"
+#define SUBTARGET_ASM_RELAX_SPEC "%{m4*:-isa=sh4-up}"
#endif
#define SH_ASM_SPEC \
target_flags |= MASK_SMALLCODE; \
sh_div_str = SH_DIV_STR_FOR_SIZE ; \
} \
+ else \
+ { \
+ TARGET_CBRANCHDI4 = 1; \
+ TARGET_EXPAND_CBRANCHDI4 = 1; \
+ } \
/* We can't meaningfully test TARGET_SHMEDIA here, because -m options \
- haven't been parsed yet, hence we';d read only the default. \
+ haven't been parsed yet, hence we'd read only the default. \
sh_target_reg_class will return NO_REGS if this is not SHMEDIA, so \
it's OK to always set flag_branch_target_load_optimize. */ \
if (LEVEL > 1) \
flag_finite_math_only. We set it to 2 here so we know if the user \
explicitly requested this to be on or off. */ \
flag_finite_math_only = 2; \
+ /* If flag_schedule_insns is 1, we set it to 2 here so we know if \
+ the user explicitly requested this to be on or off. */ \
+ if (flag_schedule_insns > 0) \
+ flag_schedule_insns = 2; \
+ \
+ set_param_value ("simultaneous-prefetches", 2); \
} while (0)
#define ASSEMBLER_DIALECT assembler_dialect
extern int assembler_dialect;
enum sh_divide_strategy_e {
+ /* SH5 strategies. */
SH_DIV_CALL,
SH_DIV_CALL2,
- SH_DIV_FP,
+ SH_DIV_FP, /* We could do this also for SH4. */
SH_DIV_INV,
SH_DIV_INV_MINLAT,
SH_DIV_INV20U,
SH_DIV_INV20L,
SH_DIV_INV_CALL,
SH_DIV_INV_CALL2,
- SH_DIV_INV_FP
+ SH_DIV_INV_FP,
+ /* SH1 .. SH4 strategies. Because of the small number of registers
+ available, the compiler uses knowledge of the actual set of registers
+ being clobbered by the different functions called. */
+ SH_DIV_CALL_DIV1, /* No FPU, medium size, highest latency. */
+ SH_DIV_CALL_FP, /* FPU needed, small size, high latency. */
+ SH_DIV_CALL_TABLE, /* No FPU, large size, medium latency. */
+ SH_DIV_INTRINSIC
};
extern enum sh_divide_strategy_e sh_div_strategy;
#define SH_DIV_STRATEGY_DEFAULT SH_DIV_CALL
#endif
+#define SUBTARGET_OVERRIDE_OPTIONS (void) 0
+
+extern const char *sh_fixed_range_str;
+
#define OVERRIDE_OPTIONS \
do { \
int regno; \
\
+ SUBTARGET_OVERRIDE_OPTIONS; \
if (flag_finite_math_only == 2) \
flag_finite_math_only \
= !flag_signaling_nans && TARGET_SH2E && ! TARGET_IEEE; \
else \
sh_div_strategy = SH_DIV_INV; \
} \
+ TARGET_CBRANCHDI4 = 0; \
} \
- /* -fprofile-arcs needs a working libgcov . In unified tree \
- configurations with newlib, this requires to configure with \
- --with-newlib --with-headers. But there is no way to check \
- here we have a working libgcov, so just assume that we have. */\
- if (profile_flag) \
- warning (0, "Profiling is still experimental for this target.");\
} \
else \
{ \
targetm.asm_out.aligned_op.di = NULL; \
targetm.asm_out.unaligned_op.di = NULL; \
} \
+ if (TARGET_SH1) \
+ { \
+ if (! strcmp (sh_div_str, "call-div1")) \
+ sh_div_strategy = SH_DIV_CALL_DIV1; \
+ else if (! strcmp (sh_div_str, "call-fp") \
+ && (TARGET_FPU_DOUBLE \
+ || (TARGET_HARD_SH4 && TARGET_SH2E) \
+ || (TARGET_SHCOMPACT && TARGET_FPU_ANY))) \
+ sh_div_strategy = SH_DIV_CALL_FP; \
+ else if (! strcmp (sh_div_str, "call-table") && TARGET_SH2) \
+ sh_div_strategy = SH_DIV_CALL_TABLE; \
+ else \
+ /* Pick one that makes most sense for the target in general. \
+ It is not much good to use different functions depending \
+ on -Os, since then we'll end up with two different functions \
+ when some of the code is compiled for size, and some for \
+ speed. */ \
+ \
+ /* SH4 tends to emphasize speed. */ \
+ if (TARGET_HARD_SH4) \
+ sh_div_strategy = SH_DIV_CALL_TABLE; \
+ /* These have their own way of doing things. */ \
+ else if (TARGET_SH2A) \
+ sh_div_strategy = SH_DIV_INTRINSIC; \
+ /* ??? Should we use the integer SHmedia function instead? */ \
+ else if (TARGET_SHCOMPACT && TARGET_FPU_ANY) \
+ sh_div_strategy = SH_DIV_CALL_FP; \
+ /* SH1 .. SH3 cores often go into small-footprint systems, so \
+ default to the smallest implementation available. */ \
+ else if (TARGET_SH2) /* ??? EXPERIMENTAL */ \
+ sh_div_strategy = SH_DIV_CALL_TABLE; \
+ else \
+ sh_div_strategy = SH_DIV_CALL_DIV1; \
+ } \
+ if (!TARGET_SH1) \
+ TARGET_PRETEND_CMOVE = 0; \
if (sh_divsi3_libfunc[0]) \
; /* User supplied - leave it alone. */ \
- else if (TARGET_HARD_SH4 && TARGET_SH2E) \
+ else if (TARGET_DIVIDE_CALL_FP) \
sh_divsi3_libfunc = "__sdivsi3_i4"; \
+ else if (TARGET_DIVIDE_CALL_TABLE) \
+ sh_divsi3_libfunc = "__sdivsi3_i4i"; \
else if (TARGET_SH5) \
- { \
- if (TARGET_FPU_ANY && TARGET_SH1) \
- sh_divsi3_libfunc = "__sdivsi3_i4"; \
- else \
- sh_divsi3_libfunc = "__sdivsi3_1"; \
- } \
+ sh_divsi3_libfunc = "__sdivsi3_1"; \
else \
sh_divsi3_libfunc = "__sdivsi3"; \
- if (TARGET_FMOVD) \
- reg_class_from_letter['e' - 'a'] = NO_REGS; \
+ if (sh_branch_cost == -1) \
+ sh_branch_cost \
+ = TARGET_SH5 ? 1 : ! TARGET_SH2 || TARGET_HARD_SH4 ? 2 : 1; \
\
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) \
if (! VALID_REGISTER_P (regno)) \
to the pressure on R0. */ \
/* Enable sched1 for SH4; ready queue will be reordered by \
the target hooks when pressure is high. We can not do this for \
- SH3 and lower as they give spill failures for R0. */ \
- if (!TARGET_HARD_SH4) \
+ PIC, SH3 and lower as they give spill failures for R0. */ \
+ if (!TARGET_HARD_SH4 || flag_pic) \
flag_schedule_insns = 0; \
+ /* ??? Current exception handling places basic block boundaries \
+ after call_insns. It causes the high pressure on R0 and gives \
+ spill failures for R0 in reload. See PR 22553 and the thread \
+ on gcc-patches \
+ <http://gcc.gnu.org/ml/gcc-patches/2005-10/msg00816.html>. */ \
+ else if (flag_exceptions) \
+ { \
+ if (flag_schedule_insns == 1) \
+ warning (0, "ignoring -fschedule-insns because of exception handling bug"); \
+ flag_schedule_insns = 0; \
+ } \
} \
\
if (align_loops == 0) \
if (align_functions < min_align) \
align_functions = min_align; \
} \
+ \
+ if (sh_fixed_range_str) \
+ sh_fix_range (sh_fixed_range_str); \
} while (0)
\f
/* Target machine storage layout. */
((GET_MODE_CLASS (TYPE_MODE (TYPE)) == MODE_COMPLEX_INT \
|| GET_MODE_CLASS (TYPE_MODE (TYPE)) == MODE_COMPLEX_FLOAT) \
? (unsigned) MIN (BIGGEST_ALIGNMENT, GET_MODE_BITSIZE (TYPE_MODE (TYPE))) \
- : (unsigned) ALIGN)
+ : (unsigned) DATA_ALIGNMENT(TYPE, ALIGN))
/* Make arrays of chars word-aligned for the same reasons. */
#define DATA_ALIGNMENT(TYPE, ALIGN) \
"tr0", "tr1", "tr2", "tr3", "tr4", "tr5", "tr6", "tr7", \
"xd0", "xd2", "xd4", "xd6", "xd8", "xd10", "xd12", "xd14", \
"gbr", "ap", "pr", "t", "mach", "macl", "fpul", "fpscr", \
- "rap" \
+ "rap", "sfp" \
}
#define REGNAMES_ARR_INDEX_1(index) \
REGNAMES_ARR_INDEX_8 (128), \
REGNAMES_ARR_INDEX_8 (136), \
REGNAMES_ARR_INDEX_8 (144), \
- REGNAMES_ARR_INDEX_1 (152) \
+ REGNAMES_ARR_INDEX_2 (152) \
}
#define ADDREGNAMES_SIZE 32
#define FIRST_TARGET_REG TR0_REG
#define LAST_TARGET_REG (FIRST_TARGET_REG + (TARGET_SHMEDIA ? 7 : -1))
+/* Registers that can be accessed through bank0 or bank1 depending on sr.md. */
+
+#define FIRST_BANKED_REG R0_REG
+#define LAST_BANKED_REG R7_REG
+
+#define BANKED_REGISTER_P(REGNO) \
+ IN_RANGE ((REGNO), \
+ (unsigned HOST_WIDE_INT) FIRST_BANKED_REG, \
+ (unsigned HOST_WIDE_INT) LAST_BANKED_REG)
+
#define GENERAL_REGISTER_P(REGNO) \
IN_RANGE ((REGNO), \
(unsigned HOST_WIDE_INT) FIRST_GENERAL_REG, \
(unsigned HOST_WIDE_INT) LAST_GENERAL_REG)
#define GENERAL_OR_AP_REGISTER_P(REGNO) \
- (GENERAL_REGISTER_P (REGNO) || ((REGNO) == AP_REG))
+ (GENERAL_REGISTER_P (REGNO) || ((REGNO) == AP_REG) \
+ || ((REGNO) == FRAME_POINTER_REGNUM))
#define FP_REGISTER_P(REGNO) \
((int) (REGNO) >= FIRST_FP_REG && (int) (REGNO) <= LAST_FP_REG)
#define VALID_REGISTER_P(REGNO) \
(SHMEDIA_REGISTER_P (REGNO) || XD_REGISTER_P (REGNO) \
|| (REGNO) == AP_REG || (REGNO) == RAP_REG \
+ || (REGNO) == FRAME_POINTER_REGNUM \
|| (TARGET_SH1 && (SPECIAL_REGISTER_P (REGNO) || (REGNO) == PR_REG)) \
|| (TARGET_SH2E && (REGNO) == FPUL_REG))
? DImode \
: SImode)
-#define FIRST_PSEUDO_REGISTER 153
+#define FIRST_PSEUDO_REGISTER 154
+
+/* Don't count soft frame pointer. */
+#define DWARF_FRAME_REGISTERS (FIRST_PSEUDO_REGISTER - 1)
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator.
0, 0, 0, 0, 0, 0, 0, 0, \
/*"gbr", "ap", "pr", "t", "mach", "macl", "fpul", "fpscr", */ \
1, 1, 1, 1, 1, 1, 0, 1, \
-/*"rap" */ \
- 1, \
+/*"rap", "sfp" */ \
+ 1, 1, \
}
/* 1 for registers not available across function calls.
1, 1, 1, 1, 1, 1, 0, 0, \
/*"gbr", "ap", "pr", "t", "mach", "macl", "fpul", "fpscr", */ \
1, 1, 1, 1, 1, 1, 1, 1, \
-/*"rap" */ \
- 1, \
+/*"rap", "sfp" */ \
+ 1, 1, \
}
/* CONDITIONAL_REGISTER_USAGE might want to make a register call-used, yet
|| GENERAL_REGISTER_P (REGNO)) \
: (MODE) == V4SFmode \
? ((FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 4 == 0) \
- || (! TARGET_SHMEDIA && GENERAL_REGISTER_P (REGNO))) \
+ || GENERAL_REGISTER_P (REGNO)) \
: (MODE) == V16SFmode \
? (TARGET_SHMEDIA \
? (FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 16 == 0) \
#define STACK_POINTER_REGNUM SP_REG
/* Base register for access to local variables of the function. */
-#define FRAME_POINTER_REGNUM FP_REG
+#define HARD_FRAME_POINTER_REGNUM FP_REG
+
+/* Base register for access to local variables of the function. */
+#define FRAME_POINTER_REGNUM 153
/* Fake register that holds the address on the stack of the
current function's return address. */
of elimination fail. */
#define ELIMINABLE_REGS \
-{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
+{{ HARD_FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
+ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
+ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
{ RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
- { RETURN_ADDRESS_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
+ { RETURN_ADDRESS_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
- { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM},}
+ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},}
/* Given FROM and TO register numbers, say whether this elimination
is allowed. */
#define CAN_ELIMINATE(FROM, TO) \
- (!((FROM) == FRAME_POINTER_REGNUM && FRAME_POINTER_REQUIRED))
+ (!((FROM) == HARD_FRAME_POINTER_REGNUM && FRAME_POINTER_REQUIRED))
/* Define the offset between two registers, one to be eliminated, and the other
its replacement, at the start of a routine. */
#define DEFAULT_PCC_STRUCT_RETURN 0
#define SHMEDIA_REGS_STACK_ADJUST() \
- (TARGET_SHCOMPACT && current_function_has_nonlocal_label \
+ (TARGET_SHCOMPACT && crtl->saves_all_registers \
? (8 * (/* r28-r35 */ 8 + /* r44-r59 */ 16 + /* tr5-tr7 */ 3) \
+ (TARGET_FPU_ANY ? 4 * (/* fr36 - fr63 */ 28) : 0)) \
: 0)
DF_REGS,
FPSCR_REGS,
GENERAL_FP_REGS,
+ GENERAL_DF_REGS,
TARGET_REGS,
ALL_REGS,
LIM_REG_CLASSES
"DF_REGS", \
"FPSCR_REGS", \
"GENERAL_FP_REGS", \
+ "GENERAL_DF_REGS", \
"TARGET_REGS", \
"ALL_REGS", \
}
/* SIBCALL_REGS: Initialized in CONDITIONAL_REGISTER_USAGE. */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, \
/* GENERAL_REGS: */ \
- { 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x01020000 }, \
+ { 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x03020000 }, \
/* FP0_REGS: */ \
{ 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000 }, \
/* FP_REGS: */ \
/* FPSCR_REGS: */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00800000 }, \
/* GENERAL_FP_REGS: */ \
- { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0102ff00 }, \
+ { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03020000 }, \
+/* GENERAL_DF_REGS: */ \
+ { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0302ff00 }, \
/* TARGET_REGS: */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000000ff }, \
/* ALL_REGS: */ \
- { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01ffffff }, \
+ { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03ffffff }, \
}
/* The same information, inverted:
128,129,130,131,132,133,134,135, \
/* Fixed registers */ \
15, 16, 24, 25, 26, 27, 63,144, \
- 145,146,147,148,149,152 }
+ 145,146,147,148,149,152,153 }
/* The class value for index registers, and the one for base regs. */
#define INDEX_REG_CLASS \
(!ALLOW_INDEXED_ADDRESS ? NO_REGS : TARGET_SHMEDIA ? GENERAL_REGS : R0_REGS)
#define BASE_REG_CLASS GENERAL_REGS
-
-/* Get reg_class from a letter such as appears in the machine
- description. */
-extern enum reg_class reg_class_from_letter[];
-
-/* We might use 'Rxx' constraints in the future for exotic reg classes.*/
-#define REG_CLASS_FROM_CONSTRAINT(C, STR) \
- (ISLOWER (C) ? reg_class_from_letter[(C)-'a'] : NO_REGS )
\f
-/* Overview of uppercase letter constraints:
- A: Addresses (constraint len == 3)
- Ac4: sh4 cache operations
- Ac5: sh5 cache operations
- Bxx: miscellaneous constraints
- Bsc: SCRATCH - for the scratch register in movsi_ie in the
- fldi0 / fldi0 cases
- C: Constants other than only CONST_INT (constraint len == 3)
- C16: 16 bit constant, literal or symbolic
- Csy: label or symbol
- Cpg: non-explicit constants that can be directly loaded into a general
- purpose register in PIC code. like 's' except we don't allow
- PIC_DIRECT_ADDR_P
- IJKLMNOP: CONT_INT constants
- Ixx: signed xx bit
- J16: 0xffffffff00000000 | 0x00000000ffffffff
- Kxx: unsigned xx bit
- M: 1
- N: 0
- P27: 1 | 2 | 8 | 16
- Q: pc relative load operand
- Rxx: reserved for exotic register classes.
- S: extra memory (storage) constraints (constraint len == 3)
- Sua: unaligned memory operations
- W: vector
- Z: zero in any mode
-
- unused CONST_INT constraint letters: LO
- unused EXTRA_CONSTRAINT letters: D T U Y */
-
-#define CONSTRAINT_LEN(C,STR) \
- (((C) == 'A' || (C) == 'B' || (C) == 'C' \
- || (C) == 'I' || (C) == 'J' || (C) == 'K' || (C) == 'P' \
- || (C) == 'R' || (C) == 'S') \
- ? 3 : DEFAULT_CONSTRAINT_LEN ((C), (STR)))
-
-/* The letters I, J, K, L and M in a register constraint string
- can be used to stand for particular ranges of immediate operands.
- This macro defines what the ranges are.
- C is the letter, and VALUE is a constant value.
- Return 1 if VALUE is in the range specified by C.
- I08: arithmetic operand -127..128, as used in add, sub, etc
- I16: arithmetic operand -32768..32767, as used in SHmedia movi and shori
- P27: shift operand 1,2,8 or 16
- K08: logical operand 0..255, as used in and, or, etc.
- M: constant 1
- N: constant 0
- I06: arithmetic operand -32..31, as used in SHmedia beqi, bnei and xori
- I10: arithmetic operand -512..511, as used in SHmedia andi, ori
-*/
+/* Defines for sh.md and constraints.md. */
#define CONST_OK_FOR_I06(VALUE) (((HOST_WIDE_INT)(VALUE)) >= -32 \
&& ((HOST_WIDE_INT)(VALUE)) <= 31)
&& ((HOST_WIDE_INT)(VALUE)) <= 511)
#define CONST_OK_FOR_I16(VALUE) (((HOST_WIDE_INT)(VALUE)) >= -32768 \
&& ((HOST_WIDE_INT)(VALUE)) <= 32767)
-#define CONST_OK_FOR_I20(VALUE) (((HOST_WIDE_INT)(VALUE)) >= -524288 \
- && ((HOST_WIDE_INT)(VALUE)) <= 524287 \
- && TARGET_SH2A)
-#define CONST_OK_FOR_I(VALUE, STR) \
- ((STR)[1] == '0' && (STR)[2] == '6' ? CONST_OK_FOR_I06 (VALUE) \
- : (STR)[1] == '0' && (STR)[2] == '8' ? CONST_OK_FOR_I08 (VALUE) \
- : (STR)[1] == '1' && (STR)[2] == '0' ? CONST_OK_FOR_I10 (VALUE) \
- : (STR)[1] == '1' && (STR)[2] == '6' ? CONST_OK_FOR_I16 (VALUE) \
- : (STR)[1] == '2' && (STR)[2] == '0' ? CONST_OK_FOR_I20 (VALUE) \
- : 0)
#define CONST_OK_FOR_J16(VALUE) \
((HOST_BITS_PER_WIDE_INT >= 64 && (VALUE) == (HOST_WIDE_INT) 0xffffffff) \
|| (HOST_BITS_PER_WIDE_INT >= 64 && (VALUE) == (HOST_WIDE_INT) -1 << 32))
-#define CONST_OK_FOR_J(VALUE, STR) \
- ((STR)[1] == '1' && (STR)[2] == '6' ? CONST_OK_FOR_J16 (VALUE) \
- : 0)
#define CONST_OK_FOR_K08(VALUE) (((HOST_WIDE_INT)(VALUE))>= 0 \
&& ((HOST_WIDE_INT)(VALUE)) <= 255)
-#define CONST_OK_FOR_K(VALUE, STR) \
- ((STR)[1] == '0' && (STR)[2] == '8' ? CONST_OK_FOR_K08 (VALUE) \
- : 0)
-#define CONST_OK_FOR_P27(VALUE) \
- ((VALUE)==1||(VALUE)==2||(VALUE)==8||(VALUE)==16)
-#define CONST_OK_FOR_P(VALUE, STR) \
- ((STR)[1] == '2' && (STR)[2] == '7' ? CONST_OK_FOR_P27 (VALUE) \
- : 0)
-#define CONST_OK_FOR_M(VALUE) ((VALUE)==1)
-#define CONST_OK_FOR_N(VALUE) ((VALUE)==0)
-#define CONST_OK_FOR_CONSTRAINT_P(VALUE, C, STR) \
- ((C) == 'I' ? CONST_OK_FOR_I ((VALUE), (STR)) \
- : (C) == 'J' ? CONST_OK_FOR_J ((VALUE), (STR)) \
- : (C) == 'K' ? CONST_OK_FOR_K ((VALUE), (STR)) \
- : (C) == 'M' ? CONST_OK_FOR_M (VALUE) \
- : (C) == 'N' ? CONST_OK_FOR_N (VALUE) \
- : (C) == 'P' ? CONST_OK_FOR_P ((VALUE), (STR)) \
- : 0)
-
-/* Similar, but for floating constants, and defining letters G and H.
- Here VALUE is the CONST_DOUBLE rtx itself. */
-
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
-((C) == 'G' ? (fp_zero_operand (VALUE) && fldi_ok ()) \
- : (C) == 'H' ? (fp_one_operand (VALUE) && fldi_ok ()) \
- : (C) == 'F')
/* Given an rtx X being reloaded into a reg required to be
in class CLASS, return the class of reg to actually use.
? GENERAL_REGS \
: (CLASS)) \
+#if 0
#define SECONDARY_INOUT_RELOAD_CLASS(CLASS,MODE,X,ELSE) \
((((REGCLASS_HAS_FP_REG (CLASS) \
&& (GET_CODE (X) == REG \
? GENERAL_REGS \
: (((CLASS) == TARGET_REGS \
|| (TARGET_SHMEDIA && (CLASS) == SIBCALL_REGS)) \
- && !EXTRA_CONSTRAINT_Csy (X) \
+ && !satisfies_constraint_Csy (X) \
&& (GET_CODE (X) != REG || ! GENERAL_REGISTER_P (REGNO (X)))) \
? GENERAL_REGS \
: (((CLASS) == MAC_REGS || (CLASS) == PR_REGS) \
|| GET_CODE (X) == PLUS)) \
? GENERAL_REGS \
: (CLASS) == FPUL_REGS && immediate_operand ((X), (MODE)) \
- ? (GET_CODE (X) == CONST_INT && CONST_OK_FOR_I08 (INTVAL (X)) \
+ ? (satisfies_constraint_I08 (X) \
? GENERAL_REGS \
: R0_REGS) \
: ((CLASS) == FPSCR_REGS \
&& (GET_CODE (X) == LABEL_REF || PIC_DIRECT_ADDR_P (X))) \
? TARGET_REGS \
: SECONDARY_INOUT_RELOAD_CLASS((CLASS),(MODE),(X), NO_REGS))
+#endif
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS.
makes the stack pointer a smaller address. */
#define STACK_GROWS_DOWNWARD
-/* Define this macro if the addresses of local variable slots are at
- negative offsets from the frame pointer.
-
- The SH only has positive indexes, so grow the frame up. */
-/* #define FRAME_GROWS_DOWNWARD */
+/* Define this macro to nonzero if the addresses of local variable slots
+ are at negative offsets from the frame pointer. */
+#define FRAME_GROWS_DOWNWARD 1
/* Offset from the frame pointer to the first local variable slot to
be allocated. */
&& (TREE_CODE (VALTYPE) == INTEGER_TYPE \
|| TREE_CODE (VALTYPE) == ENUMERAL_TYPE \
|| TREE_CODE (VALTYPE) == BOOLEAN_TYPE \
- || TREE_CODE (VALTYPE) == CHAR_TYPE \
|| TREE_CODE (VALTYPE) == REAL_TYPE \
|| TREE_CODE (VALTYPE) == OFFSET_TYPE)) \
&& sh_promote_prototypes (VALTYPE) \
- If T is set, a return trampoline will be set up for 64-bit
return values to be split into 2 32-bit registers. */
+ long call_cookie;
+
+ /* This is set to nonzero when the call in question must use the Renesas ABI,
+ even without the -mrenesas option. */
+ int renesas_abi;
+};
+
#define CALL_COOKIE_RET_TRAMP_SHIFT 0
#define CALL_COOKIE_RET_TRAMP(VAL) ((VAL) << CALL_COOKIE_RET_TRAMP_SHIFT)
#define CALL_COOKIE_STACKSEQ_SHIFT 1
((VAL) << CALL_COOKIE_INT_REG_SHIFT (REG))
#define CALL_COOKIE_INT_REG_GET(COOKIE, REG) \
(((COOKIE) >> CALL_COOKIE_INT_REG_SHIFT (REG)) & ((REG) < 4 ? 7 : 15))
- long call_cookie;
-
- /* This is set to nonzero when the call in question must use the Renesas ABI,
- even without the -mrenesas option. */
- int renesas_abi;
-};
#define CUMULATIVE_ARGS struct sh_args
&& ((MODE) == BLKmode || (MODE) == TImode || (MODE) == CDImode \
|| (MODE) == DCmode) \
&& ((CUM).arg_count[(int) SH_ARG_INT] \
- + (int_size_in_bytes (TYPE) + 7) / 8) > NPARM_REGS (SImode))
+ + (((MODE) == BLKmode ? int_size_in_bytes (TYPE) \
+ : GET_MODE_SIZE (MODE)) \
+ + 7) / 8) > NPARM_REGS (SImode))
/* Perform any needed actions needed for a function that is receiving a
variable number of arguments. */
-/* Implement `va_start' for varargs and stdarg. */
-#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
- sh_va_start (valist, nextarg)
-
/* Call the function profiler with a given profile label.
We use two .aligns, so as to make sure that both the .long is aligned
on a 4 byte boundary, and that the .long is a fixed distance (2 bytes)
(move_by_pieces_ninsns (SIZE, ALIGN, STORE_MAX_PIECES + 1) \
< (TARGET_SMALLCODE ? 2 : ((ALIGN >= 32) ? 16 : 2)))
+#define SET_BY_PIECES_P(SIZE, ALIGN) STORE_BY_PIECES_P(SIZE, ALIGN)
+
/* Macros to check register numbers against specific register classes. */
/* These assume that REGNO is a hard or pseudo reg number.
#define CONSTANT_ADDRESS_P(X) (GET_CODE (X) == LABEL_REF)
/* Nonzero if the constant value X is a legitimate general operand. */
+/* can_store_by_pieces constructs VOIDmode CONST_DOUBLEs. */
#define LEGITIMATE_CONSTANT_P(X) \
(TARGET_SHMEDIA \
|| TARGET_SHMEDIA64) \
: (GET_CODE (X) != CONST_DOUBLE \
|| GET_MODE (X) == DFmode || GET_MODE (X) == SFmode \
- || (TARGET_SH2E && (fp_zero_operand (X) || fp_one_operand (X)))))
+ || GET_MODE (X) == DImode || GET_MODE (X) == VOIDmode))
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
#endif
-/* The 'Q' constraint is a pc relative load operand. */
-#define EXTRA_CONSTRAINT_Q(OP) \
- (GET_CODE (OP) == MEM \
- && ((GET_CODE (XEXP ((OP), 0)) == LABEL_REF) \
- || (GET_CODE (XEXP ((OP), 0)) == CONST \
- && GET_CODE (XEXP (XEXP ((OP), 0), 0)) == PLUS \
- && GET_CODE (XEXP (XEXP (XEXP ((OP), 0), 0), 0)) == LABEL_REF \
- && GET_CODE (XEXP (XEXP (XEXP ((OP), 0), 0), 1)) == CONST_INT)))
+/* Macros for extra constraints. */
-/* Extra address constraints. */
-#define EXTRA_CONSTRAINT_A(OP, STR) 0
+#define IS_PC_RELATIVE_LOAD_ADDR_P(OP) \
+ ((GET_CODE ((OP)) == LABEL_REF) \
+ || (GET_CODE ((OP)) == CONST \
+ && GET_CODE (XEXP ((OP), 0)) == PLUS \
+ && GET_CODE (XEXP (XEXP ((OP), 0), 0)) == LABEL_REF \
+ && GET_CODE (XEXP (XEXP ((OP), 0), 1)) == CONST_INT))
-/* Constraint for selecting FLDI0 or FLDI1 instruction. If the clobber
- operand is not SCRATCH (i.e. REG) then R0 is probably being
- used, hence mova is being used, hence do not select this pattern */
-#define EXTRA_CONSTRAINT_Bsc(OP) (GET_CODE(OP) == SCRATCH)
-#define EXTRA_CONSTRAINT_B(OP, STR) \
- ((STR)[1] == 's' && (STR)[2] == 'c' ? EXTRA_CONSTRAINT_Bsc (OP) \
- : 0)
+#define IS_LITERAL_OR_SYMBOLIC_S16_P(OP) \
+ (GET_CODE ((OP)) == SIGN_EXTEND \
+ && (GET_MODE ((OP)) == DImode \
+ || GET_MODE ((OP)) == SImode) \
+ && GET_CODE (XEXP ((OP), 0)) == TRUNCATE \
+ && GET_MODE (XEXP ((OP), 0)) == HImode \
+ && (MOVI_SHORI_BASE_OPERAND_P (XEXP (XEXP ((OP), 0), 0)) \
+ || (GET_CODE (XEXP (XEXP ((OP), 0), 0)) == ASHIFTRT \
+ && (MOVI_SHORI_BASE_OPERAND_P \
+ (XEXP (XEXP (XEXP ((OP), 0), 0), 0))) \
+ && GET_CODE (XEXP (XEXP (XEXP ((OP), 0), 0), 1)) == CONST_INT)))
-/* The `C16' constraint is a 16-bit constant, literal or symbolic. */
-#define EXTRA_CONSTRAINT_C16(OP) \
- (GET_CODE (OP) == CONST \
- && GET_CODE (XEXP ((OP), 0)) == SIGN_EXTEND \
- && (GET_MODE (XEXP ((OP), 0)) == DImode \
- || GET_MODE (XEXP ((OP), 0)) == SImode) \
- && GET_CODE (XEXP (XEXP ((OP), 0), 0)) == TRUNCATE \
- && GET_MODE (XEXP (XEXP ((OP), 0), 0)) == HImode \
- && (MOVI_SHORI_BASE_OPERAND_P (XEXP (XEXP (XEXP ((OP), 0), 0), 0)) \
- || (GET_CODE (XEXP (XEXP (XEXP ((OP), 0), 0), 0)) == ASHIFTRT \
- && (MOVI_SHORI_BASE_OPERAND_P \
- (XEXP (XEXP (XEXP (XEXP ((OP), 0), 0), 0), 0))) \
- && GET_CODE (XEXP (XEXP (XEXP (XEXP ((OP), 0), 0), 0), \
- 1)) == CONST_INT)))
+#define IS_LITERAL_OR_SYMBOLIC_U16_P(OP) \
+ (GET_CODE ((OP)) == ZERO_EXTEND \
+ && (GET_MODE ((OP)) == DImode \
+ || GET_MODE ((OP)) == SImode) \
+ && GET_CODE (XEXP ((OP), 0)) == TRUNCATE \
+ && GET_MODE (XEXP ((OP), 0)) == HImode \
+ && (MOVI_SHORI_BASE_OPERAND_P (XEXP (XEXP ((OP), 0), 0)) \
+ || (GET_CODE (XEXP (XEXP ((OP), 0), 0)) == ASHIFTRT \
+ && (MOVI_SHORI_BASE_OPERAND_P \
+ (XEXP (XEXP (XEXP ((OP), 0), 0), 0))) \
+ && GET_CODE (XEXP (XEXP (XEXP ((OP), 0), 0), 1)) == CONST_INT)))
+
+#define IS_NON_EXPLICIT_CONSTANT_P(OP) \
+ (CONSTANT_P (OP) \
+ && GET_CODE (OP) != CONST_INT \
+ && GET_CODE (OP) != CONST_DOUBLE \
+ && (!flag_pic \
+ || (LEGITIMATE_PIC_OPERAND_P (OP) \
+ && (! PIC_ADDR_P (OP) || PIC_OFFSET_P (OP)) \
+ && GET_CODE (OP) != LABEL_REF)))
/* Check whether OP is a datalabel unspec. */
#define DATALABEL_REF_NO_CONST_P(OP) \
? (GOT_ENTRY_P (OP) || GOTPLT_ENTRY_P (OP) || GOTOFF_P (OP) \
|| PIC_OFFSET_P (OP)) \
: NON_PIC_REFERENCE_P (OP))
-
-/* The `Csy' constraint is a label or a symbol. */
-#define EXTRA_CONSTRAINT_Csy(OP) \
- (NON_PIC_REFERENCE_P (OP) || PIC_DIRECT_ADDR_P (OP))
-
-/* A zero in any shape or form. */
-#define EXTRA_CONSTRAINT_Z(OP) \
- ((OP) == CONST0_RTX (GET_MODE (OP)))
-
-/* Any vector constant we can handle. */
-#define EXTRA_CONSTRAINT_W(OP) \
- (GET_CODE (OP) == CONST_VECTOR \
- && (sh_rep_vec ((OP), VOIDmode) \
- || (HOST_BITS_PER_WIDE_INT >= 64 \
- ? sh_const_vec ((OP), VOIDmode) \
- : sh_1el_vec ((OP), VOIDmode))))
-
-/* A non-explicit constant that can be loaded directly into a general purpose
- register. This is like 's' except we don't allow PIC_DIRECT_ADDR_P. */
-#define EXTRA_CONSTRAINT_Cpg(OP) \
- (CONSTANT_P (OP) \
- && GET_CODE (OP) != CONST_INT \
- && GET_CODE (OP) != CONST_DOUBLE \
- && (!flag_pic \
- || (LEGITIMATE_PIC_OPERAND_P (OP) \
- && (! PIC_ADDR_P (OP) || PIC_OFFSET_P (OP)) \
- && GET_CODE (OP) != LABEL_REF)))
-#define EXTRA_CONSTRAINT_C(OP, STR) \
- ((STR)[1] == '1' && (STR)[2] == '6' ? EXTRA_CONSTRAINT_C16 (OP) \
- : (STR)[1] == 's' && (STR)[2] == 'y' ? EXTRA_CONSTRAINT_Csy (OP) \
- : (STR)[1] == 'p' && (STR)[2] == 'g' ? EXTRA_CONSTRAINT_Cpg (OP) \
- : 0)
-
-#define EXTRA_MEMORY_CONSTRAINT(C,STR) ((C) == 'S')
-#define EXTRA_CONSTRAINT_Sr0(OP) \
- (memory_operand((OP), GET_MODE (OP)) \
- && ! refers_to_regno_p (R0_REG, R0_REG + 1, OP, (rtx *)0))
-#define EXTRA_CONSTRAINT_Sua(OP) \
- (memory_operand((OP), GET_MODE (OP)) \
- && GET_CODE (XEXP (OP, 0)) != PLUS)
-#define EXTRA_CONSTRAINT_S(OP, STR) \
- ((STR)[1] == 'r' && (STR)[2] == '0' ? EXTRA_CONSTRAINT_Sr0 (OP) \
- : (STR)[1] == 'u' && (STR)[2] == 'a' ? EXTRA_CONSTRAINT_Sua (OP) \
- : 0)
-
-#define EXTRA_CONSTRAINT_STR(OP, C, STR) \
- ((C) == 'Q' ? EXTRA_CONSTRAINT_Q (OP) \
- : (C) == 'A' ? EXTRA_CONSTRAINT_A ((OP), (STR)) \
- : (C) == 'B' ? EXTRA_CONSTRAINT_B ((OP), (STR)) \
- : (C) == 'C' ? EXTRA_CONSTRAINT_C ((OP), (STR)) \
- : (C) == 'S' ? EXTRA_CONSTRAINT_S ((OP), (STR)) \
- : (C) == 'W' ? EXTRA_CONSTRAINT_W (OP) \
- : (C) == 'Z' ? EXTRA_CONSTRAINT_Z (OP) \
- : 0)
\f
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
that is a valid memory address for an instruction.
int MODE_SIZE; \
/* Check if this the address of an unaligned load / store. */\
if ((MODE) == VOIDmode) \
- { \
- if (CONST_OK_FOR_I06 (INTVAL (OP))) \
- goto LABEL; \
- break; \
- } \
+ { \
+ if (CONST_OK_FOR_I06 (INTVAL (OP))) \
+ goto LABEL; \
+ break; \
+ } \
MODE_SIZE = GET_MODE_SIZE (MODE); \
if (! (INTVAL (OP) & (MODE_SIZE - 1)) \
&& INTVAL (OP) >= -512 * MODE_SIZE \
else \
break; \
} \
+ if (TARGET_SH2A) \
+ { \
+ if (GET_MODE_SIZE (MODE) == 1 \
+ && (unsigned) INTVAL (OP) < 4096) \
+ goto LABEL; \
+ } \
if (MODE_DISP_OK_4 ((OP), (MODE))) goto LABEL; \
if (MODE_DISP_OK_8 ((OP), (MODE))) goto LABEL; \
} \
if (GET_MODE_SIZE (MODE) <= 8 && BASE_REGISTER_RTX_P (xop0)) \
GO_IF_LEGITIMATE_INDEX ((MODE), xop1, LABEL); \
if ((ALLOW_INDEXED_ADDRESS || GET_MODE (X) == DImode \
- || ((xop0 == stack_pointer_rtx || xop0 == frame_pointer_rtx) \
+ || ((xop0 == stack_pointer_rtx \
+ || xop0 == hard_frame_pointer_rtx) \
&& REG_P (xop1) && REGNO (xop1) == R0_REG) \
- || ((xop1 == stack_pointer_rtx || xop1 == frame_pointer_rtx) \
+ || ((xop1 == stack_pointer_rtx \
+ || xop1 == hard_frame_pointer_rtx) \
&& REG_P (xop0) && REGNO (xop0) == R0_REG)) \
&& ((!TARGET_SHMEDIA && GET_MODE_SIZE (MODE) <= 4) \
|| (TARGET_SHMEDIA && GET_MODE_SIZE (MODE) <= 8) \
&& ! ((MODE) == PSImode && (TYPE) == RELOAD_FOR_INPUT_ADDRESS) \
&& (ALLOW_INDEXED_ADDRESS \
|| XEXP ((X), 0) == stack_pointer_rtx \
- || XEXP ((X), 0) == frame_pointer_rtx)) \
+ || XEXP ((X), 0) == hard_frame_pointer_rtx)) \
{ \
rtx index_rtx = XEXP (X, 1); \
HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base; \
??? Strictly speaking, we should also include all indexed addressing,
because the index scale factor is the length of the operand.
However, the impact of GO_IF_MODE_DEPENDENT_ADDRESS would be to
- high if we did that. So we rely on reload to fix things up. */
+ high if we did that. So we rely on reload to fix things up.
-#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \
-{ \
- if (GET_CODE(ADDR) == PRE_DEC || GET_CODE(ADDR) == POST_INC) \
- goto LABEL; \
-}
+ Auto-increment addressing is now treated in recog.c. */
+
+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)
\f
/* Specify the machine mode that this machine uses
for the index in the tablejump instruction. */
floating point types equivalent to `float'. */
#define DOUBLE_TYPE_SIZE ((TARGET_SH2E && ! TARGET_SH4 && ! TARGET_SH2A_DOUBLE) ? 32 : 64)
+#if defined(__SH2E__) || defined(__SH3E__) || defined( __SH4_SINGLE_ONLY__)
+#define LIBGCC2_DOUBLE_TYPE_SIZE 32
+#else
+#define LIBGCC2_DOUBLE_TYPE_SIZE 64
+#endif
+
/* 'char' is signed by default. */
#define DEFAULT_SIGNED_CHAR 1
#undef DO_GLOBAL_CTORS_BODY
#define DO_GLOBAL_CTORS_BODY \
{ \
- typedef (*pfunc)(); \
+ typedef void (*pfunc) (void); \
extern pfunc __ctors[]; \
extern pfunc __ctors_end[]; \
pfunc *p; \
#undef DO_GLOBAL_DTORS_BODY
#define DO_GLOBAL_DTORS_BODY \
{ \
- typedef (*pfunc)(); \
+ typedef void (*pfunc) (void); \
extern pfunc __dtors[]; \
extern pfunc __dtors_end[]; \
pfunc *p; \
? (TARGET_SH5 ? 18 : 17) \
: (REGNO) == PR_MEDIA_REG \
? (TARGET_SH5 ? 18 : (unsigned) -1) \
- : (REGNO) == T_REG \
- ? (TARGET_SH5 ? 242 : 18) \
: (REGNO) == GBR_REG \
- ? (TARGET_SH5 ? 238 : 19) \
+ ? (TARGET_SH5 ? 238 : 18) \
: (REGNO) == MACH_REG \
? (TARGET_SH5 ? 239 : 20) \
: (REGNO) == MACL_REG \
? (TARGET_SH5 ? 240 : 21) \
+ : (REGNO) == T_REG \
+ ? (TARGET_SH5 ? 242 : 22) \
: (REGNO) == FPUL_REG \
? (TARGET_SH5 ? 244 : 23) \
+ : (REGNO) == FPSCR_REG \
+ ? (TARGET_SH5 ? 243 : 24) \
: (unsigned) -1)
/* This is how to output a reference to a symbol_ref. On SH5,
c_register_pragma (0, "nosave_low_regs", sh_pr_nosave_low_regs); \
} while (0)
-/* Set when processing a function with pragma interrupt turned on. */
-
-extern int pragma_interrupt;
+extern tree sh_deferred_function_attributes;
+extern tree *sh_deferred_function_attributes_tail;
/* Set when processing a function with interrupt attribute. */
extern int current_function_interrupt;
-/* Set to an RTX containing the address of the stack to switch to
- for interrupt functions. */
-extern struct rtx_def *sp_switch;
-
\f
/* Instructions with unfilled delay slots take up an
extra two bytes for the nop in the delay slot.
#define ADJUST_INSN_LENGTH(X, LENGTH) \
(LENGTH) += sh_insn_length_adjustment (X);
\f
-/* Define the codes that are matched by predicates in sh.c. */
-#define PREDICATE_CODES \
- {"and_operand", {SUBREG, REG, CONST_INT}}, \
- {"any_arith_reg_dest", {SUBREG, REG}}, \
- {"any_register_operand", {SUBREG, REG}}, \
- {"arith_operand", {SUBREG, REG, CONST_INT}}, \
- {"arith_reg_dest", {SUBREG, REG}}, \
- {"arith_reg_operand", {SUBREG, REG, SIGN_EXTEND}}, \
- {"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_VECTOR}}, \
- {"binary_float_operator", {PLUS, MINUS, MULT, DIV}}, \
- {"binary_logical_operator", {AND, IOR, XOR}}, \
- {"cache_address_operand", {PLUS, REG}}, \
- {"cmp_operand", {SUBREG, REG, CONST_INT}}, \
- {"cmpsi_operand", {SUBREG, REG, CONST_INT}}, \
- {"commutative_float_operator", {PLUS, MULT}}, \
- {"equality_comparison_operator", {EQ,NE}}, \
- {"extend_reg_operand", {SUBREG, REG, TRUNCATE}}, \
- {"extend_reg_or_0_operand", {SUBREG, REG, TRUNCATE, CONST_INT}}, \
- {"ext_dest_operand", {SUBREG, REG}}, \
- {"fp_arith_reg_dest", {SUBREG, REG}}, \
- {"fp_arith_reg_operand", {SUBREG, REG}}, \
- {"fpscr_operand", {REG}}, \
- {"fpul_operand", {REG}}, \
- {"general_extend_operand", {SUBREG, REG, MEM, TRUNCATE}}, \
- {"general_movsrc_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE, MEM, CONST }}, \
- {"general_movdst_operand", {SUBREG, REG, MEM}}, \
- {"unaligned_load_operand", {MEM}}, \
- {"greater_comparison_operator", {GT,GE,GTU,GEU}}, \
- {"inqhi_operand", {TRUNCATE}}, \
- {"int_gpr_dest", {SUBREG, REG}}, \
- {"less_comparison_operator", {LT,LE,LTU,LEU}}, \
- {"logical_operand", {SUBREG, REG, CONST_INT}}, \
- {"logical_operator", {AND,IOR,XOR}}, \
- {"logical_reg_operand", {SUBREG, REG}}, \
- {"mextr_bit_offset", {CONST_INT}}, \
- {"minuend_operand", {SUBREG, REG, TRUNCATE, CONST_INT}}, \
- {"noncommutative_float_operator", {MINUS, DIV}}, \
- {"sh_const_vec", {CONST_VECTOR}}, \
- {"sh_1el_vec", {CONST_VECTOR}}, \
- {"sh_register_operand", {REG, SUBREG, CONST_INT}}, \
- {"sh_rep_vec", {CONST_VECTOR}}, \
- {"shift_count_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \
- LABEL_REF, SUBREG, REG, ZERO_EXTEND, SIGN_EXTEND}},\
- {"shift_count_reg_operand", {SUBREG, REG, ZERO_EXTEND, SIGN_EXTEND}}, \
- {"shift_operator", {ASHIFT, ASHIFTRT, LSHIFTRT}}, \
- {"symbol_ref_operand", {SYMBOL_REF}}, \
- {"target_operand", {SUBREG, REG, LABEL_REF, SYMBOL_REF, CONST, UNSPEC}},\
- {"target_reg_operand", {SUBREG, REG}}, \
- {"trunc_hi_operand", {SUBREG, REG, TRUNCATE}}, \
- {"ua_address_operand", {SUBREG, REG, PLUS}}, \
- {"ua_offset", {CONST_INT}}, \
- {"unary_float_operator", {ABS, NEG, SQRT}}, \
- {"xor_operand", {SUBREG, REG, CONST_INT}}, \
-
-#define SPECIAL_MODE_PREDICATES \
- "any_arith_reg_dest", \
- "any_register_operand", \
- "int_gpr_dest", \
- "target_operand", \
- "target_reg_operand", \
- "trunc_hi_operand", \
- /* This line intentionally left blank. */
-
-#define any_register_operand register_operand
-#define any_arith_reg_dest arith_reg_dest
-#define ext_dest_operand arith_reg_operand
-
/* 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
2:\n" TEXT_SECTION_ASM_OP);
#endif /* (defined CRT_BEGIN || defined CRT_END) && ! __SHMEDIA__ */
-#define ALLOCATE_INITIAL_VALUE(hard_reg) \
- (REGNO (hard_reg) == (TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG) \
- ? (current_function_is_leaf \
- && ! sh_pr_n_sets () \
- && ! (TARGET_SHCOMPACT \
- && ((current_function_args_info.call_cookie \
- & ~ CALL_COOKIE_RET_TRAMP (1)) \
- || current_function_has_nonlocal_label)) \
- ? (hard_reg) \
- : gen_rtx_MEM (Pmode, return_address_pointer_rtx)) \
- : NULL_RTX)
-
-#define SIMULTANEOUS_PREFETCHES 2
-
-extern const char *sh_multcost_str;
-extern const char *sh_gettrcost_str;
-extern const char *sh_div_str;
-extern const char *sh_divsi3_libfunc;
-extern const char *cut2_workaround_str;
-
/* FIXME: middle-end support for highpart optimizations is missing. */
#define high_life_started reload_in_progress