sh.h (ROUND_ADVANCE): Delete macro.
* config/sh/sh.h (ROUND_ADVANCE): Delete macro. (ROUND_REG, PASS_IN_REG_P): Move and rename macros to ... * config/sh/sh.c (sh_round_reg, sh_pass_in_reg_p): ... these new functions. (sh_arg_partial_bytes, sh_function_arg, sh_function_arg_advance, sh_setup_incoming_varargs): Replace usage of PASS_IN_REG_P with sh_pass_in_reg_p. Replace usage of ROUND_REG with sh_round_reg. Use CEIL instead of ROUND_ADVANCE. From-SVN: r210032
This commit is contained in:
parent
3c922bcd25
commit
f6982a08ca
|
@ -1,3 +1,15 @@
|
||||||
|
2014-05-03 Oleg Endo <olegendo@gcc.gnu.org>
|
||||||
|
|
||||||
|
* config/sh/sh.h (ROUND_ADVANCE): Delete macro.
|
||||||
|
(ROUND_REG, PASS_IN_REG_P): Move and rename macros to ...
|
||||||
|
* config/sh/sh.c (sh_round_reg, sh_pass_in_reg_p): ... these new
|
||||||
|
functions.
|
||||||
|
(sh_arg_partial_bytes, sh_function_arg, sh_function_arg_advance,
|
||||||
|
sh_setup_incoming_varargs): Replace usage of PASS_IN_REG_P with
|
||||||
|
sh_pass_in_reg_p.
|
||||||
|
Replace usage of ROUND_REG with sh_round_reg.
|
||||||
|
Use CEIL instead of ROUND_ADVANCE.
|
||||||
|
|
||||||
2014-05-03 Oleg Endo <olegendo@gcc.gnu.org>
|
2014-05-03 Oleg Endo <olegendo@gcc.gnu.org>
|
||||||
|
|
||||||
PR target/61026
|
PR target/61026
|
||||||
|
|
|
@ -8809,6 +8809,54 @@ sh_callee_copies (cumulative_args_t cum, enum machine_mode mode,
|
||||||
% SH_MIN_ALIGN_FOR_CALLEE_COPY == 0));
|
% SH_MIN_ALIGN_FOR_CALLEE_COPY == 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Round a register number up to a proper boundary for an arg of mode
|
||||||
|
MODE.
|
||||||
|
The SH doesn't care about double alignment, so we only
|
||||||
|
round doubles to even regs when asked to explicitly. */
|
||||||
|
static int
|
||||||
|
sh_round_reg (const CUMULATIVE_ARGS& cum, machine_mode mode)
|
||||||
|
{
|
||||||
|
/* FIXME: This used to be a macro and has been copy pasted into this
|
||||||
|
function as is. Make this more readable. */
|
||||||
|
return
|
||||||
|
(((TARGET_ALIGN_DOUBLE
|
||||||
|
|| ((TARGET_SH4 || TARGET_SH2A_DOUBLE)
|
||||||
|
&& (mode == DFmode || mode == DCmode)
|
||||||
|
&& cum.arg_count[(int) SH_ARG_FLOAT] < NPARM_REGS (mode)))
|
||||||
|
&& GET_MODE_UNIT_SIZE (mode) > UNITS_PER_WORD)
|
||||||
|
? (cum.arg_count[(int) GET_SH_ARG_CLASS (mode)]
|
||||||
|
+ (cum.arg_count[(int) GET_SH_ARG_CLASS (mode)] & 1))
|
||||||
|
: cum.arg_count[(int) GET_SH_ARG_CLASS (mode)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return true if arg of the specified mode should be be passed in a register
|
||||||
|
or false otherwise. */
|
||||||
|
static bool
|
||||||
|
sh_pass_in_reg_p (const CUMULATIVE_ARGS& cum, machine_mode mode,
|
||||||
|
const_tree type)
|
||||||
|
{
|
||||||
|
/* FIXME: This used to be a macro and has been copy pasted into this
|
||||||
|
function as is. Make this more readable. */
|
||||||
|
return
|
||||||
|
((type == 0
|
||||||
|
|| (! TREE_ADDRESSABLE (type)
|
||||||
|
&& (! (TARGET_HITACHI || cum.renesas_abi)
|
||||||
|
|| ! (AGGREGATE_TYPE_P (type)
|
||||||
|
|| (!TARGET_FPU_ANY
|
||||||
|
&& (GET_MODE_CLASS (mode) == MODE_FLOAT
|
||||||
|
&& GET_MODE_SIZE (mode) > GET_MODE_SIZE (SFmode)))))))
|
||||||
|
&& ! cum.force_mem
|
||||||
|
&& (TARGET_SH2E
|
||||||
|
? ((mode) == BLKmode
|
||||||
|
? ((cum.arg_count[(int) SH_ARG_INT] * UNITS_PER_WORD
|
||||||
|
+ int_size_in_bytes (type))
|
||||||
|
<= NPARM_REGS (SImode) * UNITS_PER_WORD)
|
||||||
|
: ((sh_round_reg (cum, mode)
|
||||||
|
+ HARD_REGNO_NREGS (BASE_ARG_REG (mode), mode))
|
||||||
|
<= NPARM_REGS (mode)))
|
||||||
|
: sh_round_reg (cum, mode) < NPARM_REGS (mode)));
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sh_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode,
|
sh_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode,
|
||||||
tree type, bool named ATTRIBUTE_UNUSED)
|
tree type, bool named ATTRIBUTE_UNUSED)
|
||||||
|
@ -8817,14 +8865,14 @@ sh_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode,
|
||||||
int words = 0;
|
int words = 0;
|
||||||
|
|
||||||
if (!TARGET_SH5
|
if (!TARGET_SH5
|
||||||
&& PASS_IN_REG_P (*cum, mode, type)
|
&& sh_pass_in_reg_p (*cum, mode, type)
|
||||||
&& !(TARGET_SH4 || TARGET_SH2A_DOUBLE)
|
&& !(TARGET_SH4 || TARGET_SH2A_DOUBLE)
|
||||||
&& (ROUND_REG (*cum, mode)
|
&& (sh_round_reg (*cum, mode)
|
||||||
+ (mode != BLKmode
|
+ (mode != BLKmode
|
||||||
? ROUND_ADVANCE (GET_MODE_SIZE (mode))
|
? CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD)
|
||||||
: ROUND_ADVANCE (int_size_in_bytes (type)))
|
: CEIL (int_size_in_bytes (type), UNITS_PER_WORD))
|
||||||
> NPARM_REGS (mode)))
|
> NPARM_REGS (mode)))
|
||||||
words = NPARM_REGS (mode) - ROUND_REG (*cum, mode);
|
words = NPARM_REGS (mode) - sh_round_reg (*cum, mode);
|
||||||
|
|
||||||
else if (!TARGET_SHCOMPACT
|
else if (!TARGET_SHCOMPACT
|
||||||
&& SH5_WOULD_BE_PARTIAL_NREGS (*cum, mode, type, named))
|
&& SH5_WOULD_BE_PARTIAL_NREGS (*cum, mode, type, named))
|
||||||
|
@ -8861,23 +8909,23 @@ sh_function_arg (cumulative_args_t ca_v, enum machine_mode mode,
|
||||||
return GEN_INT (ca->renesas_abi ? 1 : 0);
|
return GEN_INT (ca->renesas_abi ? 1 : 0);
|
||||||
|
|
||||||
if (! TARGET_SH5
|
if (! TARGET_SH5
|
||||||
&& PASS_IN_REG_P (*ca, mode, type)
|
&& sh_pass_in_reg_p (*ca, mode, type)
|
||||||
&& (named || ! (TARGET_HITACHI || ca->renesas_abi)))
|
&& (named || ! (TARGET_HITACHI || ca->renesas_abi)))
|
||||||
{
|
{
|
||||||
int regno;
|
int regno;
|
||||||
|
|
||||||
if (mode == SCmode && TARGET_SH4 && TARGET_LITTLE_ENDIAN
|
if (mode == SCmode && TARGET_SH4 && TARGET_LITTLE_ENDIAN
|
||||||
&& (! FUNCTION_ARG_SCmode_WART || (ROUND_REG (*ca, mode) & 1)))
|
&& (! FUNCTION_ARG_SCmode_WART || (sh_round_reg (*ca, mode) & 1)))
|
||||||
{
|
{
|
||||||
rtx r1 = gen_rtx_EXPR_LIST (VOIDmode,
|
rtx r1 = gen_rtx_EXPR_LIST (VOIDmode,
|
||||||
gen_rtx_REG (SFmode,
|
gen_rtx_REG (SFmode,
|
||||||
BASE_ARG_REG (mode)
|
BASE_ARG_REG (mode)
|
||||||
+ (ROUND_REG (*ca, mode) ^ 1)),
|
+ (sh_round_reg (*ca, mode) ^ 1)),
|
||||||
const0_rtx);
|
const0_rtx);
|
||||||
rtx r2 = gen_rtx_EXPR_LIST (VOIDmode,
|
rtx r2 = gen_rtx_EXPR_LIST (VOIDmode,
|
||||||
gen_rtx_REG (SFmode,
|
gen_rtx_REG (SFmode,
|
||||||
BASE_ARG_REG (mode)
|
BASE_ARG_REG (mode)
|
||||||
+ ((ROUND_REG (*ca, mode) + 1) ^ 1)),
|
+ ((sh_round_reg (*ca, mode) + 1) ^ 1)),
|
||||||
GEN_INT (4));
|
GEN_INT (4));
|
||||||
return gen_rtx_PARALLEL(SCmode, gen_rtvec(2, r1, r2));
|
return gen_rtx_PARALLEL(SCmode, gen_rtvec(2, r1, r2));
|
||||||
}
|
}
|
||||||
|
@ -8890,7 +8938,7 @@ sh_function_arg (cumulative_args_t ca_v, enum machine_mode mode,
|
||||||
&& mode == SFmode)
|
&& mode == SFmode)
|
||||||
return gen_rtx_REG (mode, ca->free_single_fp_reg);
|
return gen_rtx_REG (mode, ca->free_single_fp_reg);
|
||||||
|
|
||||||
regno = (BASE_ARG_REG (mode) + ROUND_REG (*ca, mode))
|
regno = (BASE_ARG_REG (mode) + sh_round_reg (*ca, mode))
|
||||||
^ (mode == SFmode && TARGET_SH4
|
^ (mode == SFmode && TARGET_SH4
|
||||||
&& TARGET_LITTLE_ENDIAN
|
&& TARGET_LITTLE_ENDIAN
|
||||||
&& ! TARGET_HITACHI && ! ca->renesas_abi);
|
&& ! TARGET_HITACHI && ! ca->renesas_abi);
|
||||||
|
@ -9070,20 +9118,20 @@ sh_function_arg_advance (cumulative_args_t ca_v, enum machine_mode mode,
|
||||||
register, because the next SF value will use it, and not the
|
register, because the next SF value will use it, and not the
|
||||||
SF that follows the DF. */
|
SF that follows the DF. */
|
||||||
if (mode == DFmode
|
if (mode == DFmode
|
||||||
&& ROUND_REG (*ca, DFmode) != ROUND_REG (*ca, SFmode))
|
&& sh_round_reg (*ca, DFmode) != sh_round_reg (*ca, SFmode))
|
||||||
{
|
{
|
||||||
ca->free_single_fp_reg = (ROUND_REG (*ca, SFmode)
|
ca->free_single_fp_reg = (sh_round_reg (*ca, SFmode)
|
||||||
+ BASE_ARG_REG (mode));
|
+ BASE_ARG_REG (mode));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! ((TARGET_SH4 || TARGET_SH2A) || ca->renesas_abi)
|
if (! ((TARGET_SH4 || TARGET_SH2A) || ca->renesas_abi)
|
||||||
|| PASS_IN_REG_P (*ca, mode, type))
|
|| sh_pass_in_reg_p (*ca, mode, type))
|
||||||
(ca->arg_count[(int) GET_SH_ARG_CLASS (mode)]
|
(ca->arg_count[(int) GET_SH_ARG_CLASS (mode)]
|
||||||
= (ROUND_REG (*ca, mode)
|
= (sh_round_reg (*ca, mode)
|
||||||
+ (mode == BLKmode
|
+ (mode == BLKmode
|
||||||
? ROUND_ADVANCE (int_size_in_bytes (type))
|
? CEIL (int_size_in_bytes (type), UNITS_PER_WORD)
|
||||||
: ROUND_ADVANCE (GET_MODE_SIZE (mode)))));
|
: CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD))));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The Renesas calling convention doesn't quite fit into this scheme since
|
/* The Renesas calling convention doesn't quite fit into this scheme since
|
||||||
|
@ -9178,10 +9226,10 @@ sh_setup_incoming_varargs (cumulative_args_t ca,
|
||||||
{
|
{
|
||||||
int named_parm_regs, anon_parm_regs;
|
int named_parm_regs, anon_parm_regs;
|
||||||
|
|
||||||
named_parm_regs = (ROUND_REG (*get_cumulative_args (ca), mode)
|
named_parm_regs = (sh_round_reg (*get_cumulative_args (ca), mode)
|
||||||
+ (mode == BLKmode
|
+ (mode == BLKmode
|
||||||
? ROUND_ADVANCE (int_size_in_bytes (type))
|
? CEIL (int_size_in_bytes (type), UNITS_PER_WORD)
|
||||||
: ROUND_ADVANCE (GET_MODE_SIZE (mode))));
|
: CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD)));
|
||||||
anon_parm_regs = NPARM_REGS (SImode) - named_parm_regs;
|
anon_parm_regs = NPARM_REGS (SImode) - named_parm_regs;
|
||||||
if (anon_parm_regs > 0)
|
if (anon_parm_regs > 0)
|
||||||
*pretend_arg_size = anon_parm_regs * 4;
|
*pretend_arg_size = anon_parm_regs * 4;
|
||||||
|
|
|
@ -1361,24 +1361,6 @@ struct sh_args {
|
||||||
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
|
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
|
||||||
? SH_ARG_FLOAT : SH_ARG_INT)
|
? SH_ARG_FLOAT : SH_ARG_INT)
|
||||||
|
|
||||||
#define ROUND_ADVANCE(SIZE) \
|
|
||||||
(((SIZE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
|
|
||||||
|
|
||||||
/* Round a register number up to a proper boundary for an arg of mode
|
|
||||||
MODE.
|
|
||||||
|
|
||||||
The SH doesn't care about double alignment, so we only
|
|
||||||
round doubles to even regs when asked to explicitly. */
|
|
||||||
#define ROUND_REG(CUM, MODE) \
|
|
||||||
(((TARGET_ALIGN_DOUBLE \
|
|
||||||
|| ((TARGET_SH4 || TARGET_SH2A_DOUBLE) \
|
|
||||||
&& ((MODE) == DFmode || (MODE) == DCmode) \
|
|
||||||
&& (CUM).arg_count[(int) SH_ARG_FLOAT] < NPARM_REGS (MODE))) \
|
|
||||||
&& GET_MODE_UNIT_SIZE ((MODE)) > UNITS_PER_WORD) \
|
|
||||||
? ((CUM).arg_count[(int) GET_SH_ARG_CLASS (MODE)] \
|
|
||||||
+ ((CUM).arg_count[(int) GET_SH_ARG_CLASS (MODE)] & 1)) \
|
|
||||||
: (CUM).arg_count[(int) GET_SH_ARG_CLASS (MODE)])
|
|
||||||
|
|
||||||
/* Initialize a variable CUM of type CUMULATIVE_ARGS
|
/* Initialize a variable CUM of type CUMULATIVE_ARGS
|
||||||
for a call to a function whose data type is FNTYPE.
|
for a call to a function whose data type is FNTYPE.
|
||||||
For a library call, FNTYPE is 0.
|
For a library call, FNTYPE is 0.
|
||||||
|
@ -1394,27 +1376,6 @@ struct sh_args {
|
||||||
#define INIT_CUMULATIVE_LIBCALL_ARGS(CUM, MODE, LIBNAME) \
|
#define INIT_CUMULATIVE_LIBCALL_ARGS(CUM, MODE, LIBNAME) \
|
||||||
sh_init_cumulative_args (& (CUM), NULL_TREE, (LIBNAME), NULL_TREE, 0, (MODE))
|
sh_init_cumulative_args (& (CUM), NULL_TREE, (LIBNAME), NULL_TREE, 0, (MODE))
|
||||||
|
|
||||||
/* Return boolean indicating arg of mode MODE will be passed in a reg.
|
|
||||||
This macro is only used in this file. */
|
|
||||||
#define PASS_IN_REG_P(CUM, MODE, TYPE) \
|
|
||||||
(((TYPE) == 0 \
|
|
||||||
|| (! TREE_ADDRESSABLE ((TYPE)) \
|
|
||||||
&& (! (TARGET_HITACHI || (CUM).renesas_abi) \
|
|
||||||
|| ! (AGGREGATE_TYPE_P (TYPE) \
|
|
||||||
|| (!TARGET_FPU_ANY \
|
|
||||||
&& (GET_MODE_CLASS (MODE) == MODE_FLOAT \
|
|
||||||
&& GET_MODE_SIZE (MODE) > GET_MODE_SIZE (SFmode))))))) \
|
|
||||||
&& ! (CUM).force_mem \
|
|
||||||
&& (TARGET_SH2E \
|
|
||||||
? ((MODE) == BLKmode \
|
|
||||||
? (((CUM).arg_count[(int) SH_ARG_INT] * UNITS_PER_WORD \
|
|
||||||
+ int_size_in_bytes (TYPE)) \
|
|
||||||
<= NPARM_REGS (SImode) * UNITS_PER_WORD) \
|
|
||||||
: ((ROUND_REG((CUM), (MODE)) \
|
|
||||||
+ HARD_REGNO_NREGS (BASE_ARG_REG (MODE), (MODE))) \
|
|
||||||
<= NPARM_REGS (MODE))) \
|
|
||||||
: ROUND_REG ((CUM), (MODE)) < NPARM_REGS (MODE)))
|
|
||||||
|
|
||||||
/* By accident we got stuck with passing SCmode on SH4 little endian
|
/* By accident we got stuck with passing SCmode on SH4 little endian
|
||||||
in two registers that are nominally successive - which is different from
|
in two registers that are nominally successive - which is different from
|
||||||
two single SFmode values, where we take endianness translation into
|
two single SFmode values, where we take endianness translation into
|
||||||
|
|
Loading…
Reference in New Issue