#undef SUBTARGET_TARGET_OPTIONS
#define SUBTARGET_TARGET_OPTIONS \
{ "abi=", &mips_abi_string, \
"Specify ABI to use"},
#undef STACK_BOUNDARY
#define STACK_BOUNDARY \
((mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI) \
? 64 : 128)
#undef MIPS_STACK_ALIGN
#define MIPS_STACK_ALIGN(LOC) \
((mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI) \
? ((LOC) + 7) & ~7 \
: ((LOC) + 15) & ~15)
#undef GP_ARG_LAST
#define GP_ARG_LAST ((mips_abi == ABI_32 || mips_abi == ABI_O64) \
? GP_REG_FIRST + 7 : GP_REG_FIRST + 11)
#undef FP_ARG_LAST
#define FP_ARG_LAST ((mips_abi == ABI_32 || mips_abi == ABI_O64) \
? FP_REG_FIRST + 15 : FP_REG_FIRST + 19)
#undef SUBTARGET_CONDITIONAL_REGISTER_USAGE
#define SUBTARGET_CONDITIONAL_REGISTER_USAGE \
{ \
\
if (mips_abi == ABI_64) \
{ \
int regno; \
for (regno = FP_REG_FIRST + 20; regno < FP_REG_FIRST + 24; regno++) \
call_really_used_regs[regno] = call_used_regs[regno] = 1; \
} \
\
if (mips_abi == ABI_N32 || mips_abi == ABI_MEABI) \
{ \
int regno; \
for (regno = FP_REG_FIRST + 21; regno <= FP_REG_FIRST + 31; regno+=2) \
call_really_used_regs[regno] = call_used_regs[regno] = 1; \
} \
}
#undef MAX_ARGS_IN_REGISTERS
#define MAX_ARGS_IN_REGISTERS ((mips_abi == ABI_32 || mips_abi == ABI_O64) \
? 4 : 8)
#undef REG_PARM_STACK_SPACE
#define REG_PARM_STACK_SPACE(FNDECL) \
((mips_abi == ABI_32 || mips_abi == ABI_O64) \
? (MAX_ARGS_IN_REGISTERS*UNITS_PER_WORD) - FIRST_PARM_OFFSET (FNDECL) \
: 0)
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
(! BYTES_BIG_ENDIAN \
? upward \
: (((MODE) == BLKmode \
? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
&& int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT))\
: (GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY \
&& (mips_abi == ABI_32 \
|| mips_abi == ABI_O64 \
|| mips_abi == ABI_EABI \
|| GET_MODE_CLASS (MODE) == MODE_INT))) \
? downward : upward))
#define MUST_PASS_IN_STACK(MODE,TYPE) \
((TYPE) != 0 \
&& (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST \
|| TREE_ADDRESSABLE (TYPE) \
|| ((MODE) == BLKmode \
&& mips_abi != ABI_32 && mips_abi != ABI_O64 \
&& ! ((TYPE) != 0 && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
&& 0 == (int_size_in_bytes (TYPE) \
% (PARM_BOUNDARY / BITS_PER_UNIT))) \
&& (FUNCTION_ARG_PADDING (MODE, TYPE) \
== (BYTES_BIG_ENDIAN ? upward : downward)))))
#undef RETURN_IN_MEMORY
#define RETURN_IN_MEMORY(TYPE) \
((mips_abi == ABI_32 || mips_abi == ABI_O64) \
? TYPE_MODE (TYPE) == BLKmode \
: ((int_size_in_bytes (TYPE) \
> (2 * UNITS_PER_WORD)) \
|| (int_size_in_bytes (TYPE) == -1)))
#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
{ unsigned int mips_off \
= (! current_function_varargs) && (! (CUM).last_arg_fp); \
unsigned int mips_fp_off \
= (! current_function_varargs) && ((CUM).last_arg_fp); \
if (((mips_abi != ABI_32 && mips_abi != ABI_O64) \
&& (CUM).arg_words < MAX_ARGS_IN_REGISTERS - mips_off) \
|| (mips_abi == ABI_EABI \
&& ! TARGET_SOFT_FLOAT \
&& (CUM).fp_arg_words < MAX_ARGS_IN_REGISTERS - mips_fp_off)) \
{ \
int mips_save_gp_regs \
= MAX_ARGS_IN_REGISTERS - (CUM).arg_words - mips_off; \
int mips_save_fp_regs \
= (mips_abi != ABI_EABI ? 0 \
: MAX_ARGS_IN_REGISTERS - (CUM).fp_arg_words - mips_fp_off); \
\
if (mips_save_gp_regs < 0) \
mips_save_gp_regs = 0; \
if (mips_save_fp_regs < 0) \
mips_save_fp_regs = 0; \
PRETEND_SIZE = ((mips_save_gp_regs * UNITS_PER_WORD) \
+ (mips_save_fp_regs * UNITS_PER_FPREG)); \
\
if (! (NO_RTL)) \
{ \
if ((CUM).arg_words < MAX_ARGS_IN_REGISTERS - mips_off) \
{ \
rtx ptr, mem; \
if (mips_abi != ABI_EABI) \
ptr = virtual_incoming_args_rtx; \
else \
ptr = plus_constant (virtual_incoming_args_rtx, \
- (mips_save_gp_regs \
* UNITS_PER_WORD)); \
mem = gen_rtx_MEM (BLKmode, ptr); \
\
if (mips_abi != ABI_EABI && BYTES_BIG_ENDIAN) \
MEM_SET_IN_STRUCT_P (mem, 1); \
move_block_from_reg \
((CUM).arg_words + GP_ARG_FIRST + mips_off, \
mem, \
mips_save_gp_regs, \
mips_save_gp_regs * UNITS_PER_WORD); \
} \
if (mips_abi == ABI_EABI \
&& ! TARGET_SOFT_FLOAT \
&& (CUM).fp_arg_words < MAX_ARGS_IN_REGISTERS - mips_fp_off) \
{ \
enum machine_mode mode = TARGET_SINGLE_FLOAT ? SFmode : DFmode; \
int size = GET_MODE_SIZE (mode); \
int off; \
int i; \
\
off = - (mips_save_gp_regs * UNITS_PER_WORD); \
if (! TARGET_SINGLE_FLOAT) \
off &= ~ 7; \
if (! TARGET_FLOAT64 || TARGET_SINGLE_FLOAT) \
off -= (mips_save_fp_regs / 2) * size; \
else \
off -= mips_save_fp_regs * size; \
for (i = 0; i < mips_save_fp_regs; i++) \
{ \
rtx tem = \
gen_rtx_MEM (mode, \
plus_constant (virtual_incoming_args_rtx, \
off)); \
emit_move_insn (tem, \
gen_rtx_REG (mode, \
((CUM).fp_arg_words \
+ FP_ARG_FIRST \
+ i \
+ mips_fp_off))); \
off += size; \
if (! TARGET_FLOAT64 || TARGET_SINGLE_FLOAT) \
++i; \
} \
} \
} \
} \
}
#define STRICT_ARGUMENT_NAMING (mips_abi != ABI_32 && mips_abi != ABI_O64)
#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
function_arg_pass_by_reference (&CUM, MODE, TYPE, NAMED)
#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \
(mips_abi == ABI_EABI && (NAMED) \
&& FUNCTION_ARG_PASS_BY_REFERENCE (CUM, MODE, TYPE, NAMED))
#undef LONG_MAX_SPEC
#if ((MIPS_ABI_DEFAULT == ABI_64) || ((MIPS_ABI_DEFAULT == ABI_EABI) && ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_64BIT)))
#define LONG_MAX_SPEC \
"%{!mabi=32:%{!mabi=n32:%{!mlong32:%{!mgp32:%{!mips1:%{!mips2:-D__LONG_MAX__=9223372036854775807L}}}}}}"
#else
#define LONG_MAX_SPEC \
"%{mabi=64:-D__LONG_MAX__=9223372036854775807L} \
%{mlong64:-D__LONG_MAX__=9223372036854775807L} \
%{mgp64:-D__LONG_MAX__=9223372036854775807L}"
#endif