mips.h (MAX_FPRS_PER_FMT): Renamed from FP_INC.
2007-05-08 Sandra Loosemore <sandra@codesourcery.com> Nigel Stephens <nigel@mips.com> gcc/ * config/mips/mips.h (MAX_FPRS_PER_FMT): Renamed from FP_INC. Update comments and all uses. (MIN_FPRS_PER_FMT): Define. * config/mips/mips.c (function_arg): Fix to correctly handle the -mips32r2 -mfp64 -mabi=32 case. (override_options): Enable use of odd-numbered registers for SFmode values on MIPS32. (mips_save_reg_p): Save whole floating-point register pair if either half is used. (compute_frame_size): Fix comment. Co-Authored-By: Nigel Stephens <nigel@mips.com> From-SVN: r124545
This commit is contained in:
parent
28f601ff8a
commit
e8ab09c1bd
|
@ -1,3 +1,17 @@
|
|||
2007-05-08 Sandra Loosemore <sandra@codesourcery.com>
|
||||
Nigel Stephens <nigel@mips.com>
|
||||
|
||||
* config/mips/mips.h (MAX_FPRS_PER_FMT): Renamed from FP_INC.
|
||||
Update comments and all uses.
|
||||
(MIN_FPRS_PER_FMT): Define.
|
||||
* config/mips/mips.c (function_arg): Fix to correctly handle
|
||||
the -mips32r2 -mfp64 -mabi=32 case.
|
||||
(override_options): Enable use of odd-numbered registers for
|
||||
SFmode values on MIPS32.
|
||||
(mips_save_reg_p): Save whole floating-point register pair if
|
||||
either half is used.
|
||||
(compute_frame_size): Fix comment.
|
||||
|
||||
2007-05-08 Jie Zhang <jie.zhang@analog.com>
|
||||
|
||||
* config/bfin/bfin-protos.h (bfin_expand_epilogue): Add a third
|
||||
|
|
|
@ -3528,7 +3528,7 @@ mips_emit_fcc_reload (rtx dest, rtx src, rtx scratch)
|
|||
src = gen_rtx_REG (SFmode, true_regnum (src));
|
||||
|
||||
fp1 = gen_rtx_REG (SFmode, REGNO (scratch));
|
||||
fp2 = gen_rtx_REG (SFmode, REGNO (scratch) + FP_INC);
|
||||
fp2 = gen_rtx_REG (SFmode, REGNO (scratch) + MAX_FPRS_PER_FMT);
|
||||
|
||||
emit_move_insn (copy_rtx (fp1), src);
|
||||
emit_move_insn (copy_rtx (fp2), CONST0_RTX (SFmode));
|
||||
|
@ -3872,7 +3872,7 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
if (mips_abi != ABI_EABI || !info.fpr_p)
|
||||
cum->num_gprs = info.reg_offset + info.reg_words;
|
||||
else if (info.reg_words > 0)
|
||||
cum->num_fprs += FP_INC;
|
||||
cum->num_fprs += MAX_FPRS_PER_FMT;
|
||||
|
||||
if (info.stack_words > 0)
|
||||
cum->stack_words = info.stack_offset + info.stack_words;
|
||||
|
@ -4006,10 +4006,11 @@ function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
|
||||
if (!info.fpr_p)
|
||||
return gen_rtx_REG (mode, GP_ARG_FIRST + info.reg_offset);
|
||||
else if (info.reg_offset == 1)
|
||||
/* This code handles the special o32 case in which the second word
|
||||
of the argument structure is passed in floating-point registers. */
|
||||
return gen_rtx_REG (mode, FP_ARG_FIRST + FP_INC);
|
||||
else if (mips_abi == ABI_32 && TARGET_DOUBLE_FLOAT && info.reg_offset > 0)
|
||||
/* In o32, the second argument is always passed in $f14
|
||||
for TARGET_DOUBLE_FLOAT, regardless of whether the
|
||||
first argument was a word or doubleword. */
|
||||
return gen_rtx_REG (mode, FP_ARG_FIRST + 2);
|
||||
else
|
||||
return gen_rtx_REG (mode, FP_ARG_FIRST + info.reg_offset);
|
||||
}
|
||||
|
@ -4150,7 +4151,8 @@ mips_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
|
||||
mode = TARGET_SINGLE_FLOAT ? SFmode : DFmode;
|
||||
|
||||
for (i = local_cum.num_fprs; i < MAX_ARGS_IN_REGISTERS; i += FP_INC)
|
||||
for (i = local_cum.num_fprs; i < MAX_ARGS_IN_REGISTERS;
|
||||
i += MAX_FPRS_PER_FMT)
|
||||
{
|
||||
rtx ptr, mem;
|
||||
|
||||
|
@ -5098,7 +5100,9 @@ override_options (void)
|
|||
temp = ((regno & 1) == 0 || size <= UNITS_PER_WORD);
|
||||
|
||||
else if (FP_REG_P (regno))
|
||||
temp = ((regno % FP_INC) == 0)
|
||||
temp = ((((regno % MAX_FPRS_PER_FMT) == 0)
|
||||
|| (MIN_FPRS_PER_FMT == 1
|
||||
&& size <= UNITS_PER_FPREG))
|
||||
&& (((class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT
|
||||
|| class == MODE_VECTOR_FLOAT)
|
||||
&& size <= UNITS_PER_FPVALUE)
|
||||
|
@ -5112,7 +5116,7 @@ override_options (void)
|
|||
&& size >= MIN_UNITS_PER_WORD
|
||||
&& size <= UNITS_PER_FPREG)
|
||||
/* Allow TFmode for CCmode reloads. */
|
||||
|| (ISA_HAS_8CC && mode == TFmode));
|
||||
|| (ISA_HAS_8CC && mode == TFmode)));
|
||||
|
||||
else if (ACC_REG_P (regno))
|
||||
temp = (INTEGRAL_MODE_P (mode)
|
||||
|
@ -6285,6 +6289,15 @@ mips_save_reg_p (unsigned int regno)
|
|||
if (regs_ever_live[regno] && !call_used_regs[regno])
|
||||
return true;
|
||||
|
||||
/* Save both registers in an FPR pair if either one is used. This is
|
||||
needed for the case when MIN_FPRS_PER_FMT == 1, which allows the odd
|
||||
register to be used without the even register. */
|
||||
if (FP_REG_P (regno)
|
||||
&& MAX_FPRS_PER_FMT == 2
|
||||
&& regs_ever_live[regno + 1]
|
||||
&& !call_used_regs[regno + 1])
|
||||
return true;
|
||||
|
||||
/* We need to save the old frame pointer before setting up a new one. */
|
||||
if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
|
||||
return true;
|
||||
|
@ -6437,15 +6450,15 @@ compute_frame_size (HOST_WIDE_INT size)
|
|||
}
|
||||
|
||||
/* This loop must iterate over the same space as its companion in
|
||||
save_restore_insns. */
|
||||
for (regno = (FP_REG_LAST - FP_INC + 1);
|
||||
mips_for_each_saved_reg. */
|
||||
for (regno = (FP_REG_LAST - MAX_FPRS_PER_FMT + 1);
|
||||
regno >= FP_REG_FIRST;
|
||||
regno -= FP_INC)
|
||||
regno -= MAX_FPRS_PER_FMT)
|
||||
{
|
||||
if (mips_save_reg_p (regno))
|
||||
{
|
||||
fp_reg_size += FP_INC * UNITS_PER_FPREG;
|
||||
fmask |= ((1 << FP_INC) - 1) << (regno - FP_REG_FIRST);
|
||||
fp_reg_size += MAX_FPRS_PER_FMT * UNITS_PER_FPREG;
|
||||
fmask |= ((1 << MAX_FPRS_PER_FMT) - 1) << (regno - FP_REG_FIRST);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6467,7 +6480,8 @@ compute_frame_size (HOST_WIDE_INT size)
|
|||
cfun->machine->frame.fmask = fmask;
|
||||
cfun->machine->frame.initialized = reload_completed;
|
||||
cfun->machine->frame.num_gp = gp_reg_size / UNITS_PER_WORD;
|
||||
cfun->machine->frame.num_fp = fp_reg_size / (FP_INC * UNITS_PER_FPREG);
|
||||
cfun->machine->frame.num_fp = (fp_reg_size
|
||||
/ (MAX_FPRS_PER_FMT * UNITS_PER_FPREG));
|
||||
|
||||
if (mask)
|
||||
{
|
||||
|
@ -6490,7 +6504,7 @@ compute_frame_size (HOST_WIDE_INT size)
|
|||
|
||||
offset = (args_size + cprestore_size + var_size
|
||||
+ gp_reg_rounded + fp_reg_size
|
||||
- FP_INC * UNITS_PER_FPREG);
|
||||
- MAX_FPRS_PER_FMT * UNITS_PER_FPREG);
|
||||
cfun->machine->frame.fp_sp_offset = offset;
|
||||
cfun->machine->frame.fp_save_offset = offset - total_size;
|
||||
}
|
||||
|
@ -6593,9 +6607,9 @@ mips_for_each_saved_reg (HOST_WIDE_INT sp_offset, mips_save_restore_fn fn)
|
|||
compute_frame_size. */
|
||||
offset = cfun->machine->frame.fp_sp_offset - sp_offset;
|
||||
fpr_mode = (TARGET_SINGLE_FLOAT ? SFmode : DFmode);
|
||||
for (regno = (FP_REG_LAST - FP_INC + 1);
|
||||
for (regno = (FP_REG_LAST - MAX_FPRS_PER_FMT + 1);
|
||||
regno >= FP_REG_FIRST;
|
||||
regno -= FP_INC)
|
||||
regno -= MAX_FPRS_PER_FMT)
|
||||
if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST))
|
||||
{
|
||||
mips_save_restore_reg (fpr_mode, regno, offset, fn);
|
||||
|
@ -7507,7 +7521,7 @@ mips_return_fpr_pair (enum machine_mode mode,
|
|||
{
|
||||
int inc;
|
||||
|
||||
inc = (TARGET_NEWABI ? 2 : FP_INC);
|
||||
inc = (TARGET_NEWABI ? 2 : MAX_FPRS_PER_FMT);
|
||||
return gen_rtx_PARALLEL
|
||||
(mode,
|
||||
gen_rtvec (2,
|
||||
|
@ -7645,7 +7659,7 @@ mips_cannot_change_mode_class (enum machine_mode from,
|
|||
registers, the first register always holds the low word.
|
||||
We therefore can't allow FPRs to change between single-word
|
||||
and multi-word modes. */
|
||||
if (FP_INC > 1 && reg_classes_intersect_p (FP_REGS, class))
|
||||
if (MAX_FPRS_PER_FMT > 1 && reg_classes_intersect_p (FP_REGS, class))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1021,13 +1021,19 @@ extern const struct mips_rtx_cost_data *mips_cost;
|
|||
/* For MIPS, width of a floating point register. */
|
||||
#define UNITS_PER_FPREG (TARGET_FLOAT64 ? 8 : 4)
|
||||
|
||||
/* If register $f0 holds a floating-point value, $f(0 + FP_INC) is
|
||||
the next available register. */
|
||||
#define FP_INC (TARGET_FLOAT64 || TARGET_SINGLE_FLOAT ? 1 : 2)
|
||||
/* The number of consecutive floating-point registers needed to store the
|
||||
largest format supported by the FPU. */
|
||||
#define MAX_FPRS_PER_FMT (TARGET_FLOAT64 || TARGET_SINGLE_FLOAT ? 1 : 2)
|
||||
|
||||
/* The number of consecutive floating-point registers needed to store the
|
||||
smallest format supported by the FPU. */
|
||||
#define MIN_FPRS_PER_FMT \
|
||||
(ISA_MIPS32 || ISA_MIPS32R2 || ISA_MIPS64 ? 1 : MAX_FPRS_PER_FMT)
|
||||
|
||||
/* The largest size of value that can be held in floating-point
|
||||
registers and moved with a single instruction. */
|
||||
#define UNITS_PER_HWFPVALUE (TARGET_SOFT_FLOAT ? 0 : FP_INC * UNITS_PER_FPREG)
|
||||
#define UNITS_PER_HWFPVALUE \
|
||||
(TARGET_SOFT_FLOAT ? 0 : MAX_FPRS_PER_FMT * UNITS_PER_FPREG)
|
||||
|
||||
/* The largest size of value that can be held in floating-point
|
||||
registers. */
|
||||
|
|
Loading…
Reference in New Issue