Implement MIPS o32 FPXX, FP64, FP64A ABI extensions.
2014-11-12 Matthew Fortune <matthew.fortune@imgtec.com> gcc/ * common/config/mips/mips-common.c (mips_handle_option): Ensure that -mfp32, -mfp64 disable -mfpxx and -mfpxx disables -mfp64. * config.gcc (--with-fp-32): New option. (--with-odd-spreg-32): Likewise. * config.in (HAVE_AS_DOT_MODULE): New config define. * config/mips/mips-protos.h (mips_secondary_memory_needed): New prototype. (mips_hard_regno_caller_save_mode): Likewise. * config/mips/mips.c (mips_get_reg_raw_mode): New static prototype. (mips_get_arg_info): Assert that V2SFmode is only handled specially with TARGET_PAIRED_SINGLE_FLOAT. (mips_return_mode_in_fpr_p): Likewise. (mips16_call_stub_mode_suffix): Likewise. (mips_get_reg_raw_mode): New static function. (mips_return_fpr_pair): O32 return values span two registers. (mips16_build_call_stub): Likewise. (mips_function_value_regno_p): Support both FP return registers. (mips_output_64bit_xfer): Use mthc1 whenever TARGET_HAS_MXHC1. Add specific cases for TARGET_FPXX to move via memory. (mips_dwarf_register_span): For TARGET_FPXX pretend that modes larger than UNITS_PER_FPREG 'span' one register. (mips_dwarf_frame_reg_mode): New static function. (mips_file_start): Switch to using .module instead of .gnu_attribute. No longer support FP ABI 4 (-mips32r2 -mfp64), replace with FP ABI 6. Add FP ABI 5 (-mfpxx) and FP ABI 7 (-mfp64 -mno-odd-spreg). (mips_save_reg, mips_restore_reg): Always represent DFmode frame slots with two CFI directives even for O32 FP64. (mips_for_each_saved_gpr_and_fpr): Account for fixed_regs when saving/restoring callee-saved registers. (mips_hard_regno_mode_ok_p): Implement O32 FP64A extension. (mips_secondary_memory_needed): New function. (mips_option_override): ABI check for TARGET_FLOATXX. Disable odd-numbered single-precision registers when using TARGET_FLOATXX. Implement -modd-spreg and defaults. (mips_conditional_register_usage): Redefine O32 FP64 to match O32 FP32 callee-saved behaviour. (mips_hard_regno_caller_save_mode): Implement. (TARGET_GET_RAW_RESULT_MODE): Define target hook. (TARGET_GET_RAW_ARG_MODE): Define target hook. (TARGET_DWARF_FRAME_REG_MODE): Define target hook. * config/mips/mips.h (TARGET_FLOAT32): New macro. (TARGET_O32_FP64A_ABI): Likewise. (TARGET_CPU_CPP_BUILTINS): TARGET_FPXX is __mips_fpr==0. Add _MIPS_SPFPSET builtin define. (MIPS_FPXX_OPTION_SPEC): New macro. (OPTION_DEFAULT_SPECS): Pass through --with-fp-32=* to -mfp and --with-odd-spreg-32=* to -m[no-]odd-spreg. (ISA_HAS_ODD_SPREG): New macro. (ISA_HAS_MXHC1): True for anything other than -mfp32. (ASM_SPEC): Pass through mfpxx, mfp64, -mno-odd-spreg and -modd-spreg. (MIN_FPRS_PER_FMT): Redefine in terms of TARGET_ODD_SPREG. (HARD_REGNO_CALLER_SAVE_MODE): Define. Implement O32 FPXX extension (HARD_REGNO_CALL_PART_CLOBBERED): Likewise. (SECONDARY_MEMORY_NEEDED): Likewise. (FUNCTION_ARG_REGNO_P): Update for O32 FPXX and FP64 extensions. * config/mips/mips.md (define_attr enabled): Implement O32 FPXX and FP64A ABI extensions. (move_doubleword_fpr<mode>): Use ISA_HAS_MXHC1 instead of TARGET_FLOAT64. * config/mips/mips.opt (mfpxx): New target option. (modd-spreg): Likewise. * config/mips/mti-elf.h (DRIVER_SELF_SPECS): Infer FP ABI from arch. * config/mips/mti-linux.h (DRIVER_SELF_SPECS): Likewise and remove fp64 sysroot. * config/mips/t-mti-elf: Remove fp64 multilib. * config/mips/t-mti-linux: Likewise. * configure.ac: Detect .module support. * configure: Regenerate. * doc/invoke.texi: Document -mfpxx, -modd-spreg, -mno-odd-spreg option. * doc/install.texi (--with-fp-32, --with-odd-spreg-32): Document new options. gcc/testsuite/ * gcc.target/mips/args-1.c: Handle __mips_fpr == 0. * gcc.target/mips/call-clobbered-1.c: New. * gcc.target/mips/call-clobbered-2.c: New. * gcc.target/mips/call-clobbered-3.c: New. * gcc.target/mips/call-clobbered-4.c: New. * gcc.target/mips/call-clobbered-5.c: New. * gcc.target/mips/call-saved-4.c: New. * gcc.target/mips/call-saved-5.c: New. * gcc.target/mips/call-saved-6.c: New. * gcc.target/mips/mips.exp: Support -mfpxx, -ffixed-f*, and -m[no-]odd-spreg. Use _MIPS_SPFPSET to determine default odd-spreg option. Account for -modd-spreg in minimum arch code. * gcc.target/mips/movdf-1.c: New. * gcc.target/mips/movdf-2.c: New. * gcc.target/mips/movdf-3.c: New. * gcc.target/mips/oddspreg-1.c: New. * gcc.target/mips/oddspreg-2.c: New. * gcc.target/mips/oddspreg-3.c: New. * gcc.target/mips/oddspreg-4.c: New. * gcc.target/mips/oddspreg-5.c: New. * gcc.target/mips/oddspreg-6.c: New. libgcc/ * config/mips/mips16.S: Set .module when supported. Update O32 FP64 calling convention and use for FPXX when possible. Add FPXX calling convention fallback case. From-SVN: r217446
This commit is contained in:
parent
21c767169b
commit
050af1445b
|
@ -1,3 +1,77 @@
|
|||
2014-11-12 Matthew Fortune <matthew.fortune@imgtec.com>
|
||||
|
||||
* common/config/mips/mips-common.c (mips_handle_option): Ensure
|
||||
that -mfp32, -mfp64 disable -mfpxx and -mfpxx disables -mfp64.
|
||||
* config.gcc (--with-fp-32): New option.
|
||||
(--with-odd-spreg-32): Likewise.
|
||||
* config.in (HAVE_AS_DOT_MODULE): New config define.
|
||||
* config/mips/mips-protos.h
|
||||
(mips_secondary_memory_needed): New prototype.
|
||||
(mips_hard_regno_caller_save_mode): Likewise.
|
||||
* config/mips/mips.c (mips_get_reg_raw_mode): New static prototype.
|
||||
(mips_get_arg_info): Assert that V2SFmode is only handled specially
|
||||
with TARGET_PAIRED_SINGLE_FLOAT.
|
||||
(mips_return_mode_in_fpr_p): Likewise.
|
||||
(mips16_call_stub_mode_suffix): Likewise.
|
||||
(mips_get_reg_raw_mode): New static function.
|
||||
(mips_return_fpr_pair): O32 return values span two registers.
|
||||
(mips16_build_call_stub): Likewise.
|
||||
(mips_function_value_regno_p): Support both FP return registers.
|
||||
(mips_output_64bit_xfer): Use mthc1 whenever TARGET_HAS_MXHC1. Add
|
||||
specific cases for TARGET_FPXX to move via memory.
|
||||
(mips_dwarf_register_span): For TARGET_FPXX pretend that modes larger
|
||||
than UNITS_PER_FPREG 'span' one register.
|
||||
(mips_dwarf_frame_reg_mode): New static function.
|
||||
(mips_file_start): Switch to using .module instead of .gnu_attribute.
|
||||
No longer support FP ABI 4 (-mips32r2 -mfp64), replace with FP ABI 6.
|
||||
Add FP ABI 5 (-mfpxx) and FP ABI 7 (-mfp64 -mno-odd-spreg).
|
||||
(mips_save_reg, mips_restore_reg): Always represent DFmode frame
|
||||
slots with two CFI directives even for O32 FP64.
|
||||
(mips_for_each_saved_gpr_and_fpr): Account for fixed_regs when
|
||||
saving/restoring callee-saved registers.
|
||||
(mips_hard_regno_mode_ok_p): Implement O32 FP64A extension.
|
||||
(mips_secondary_memory_needed): New function.
|
||||
(mips_option_override): ABI check for TARGET_FLOATXX. Disable
|
||||
odd-numbered single-precision registers when using TARGET_FLOATXX.
|
||||
Implement -modd-spreg and defaults.
|
||||
(mips_conditional_register_usage): Redefine O32 FP64 to match O32 FP32
|
||||
callee-saved behaviour.
|
||||
(mips_hard_regno_caller_save_mode): Implement.
|
||||
(TARGET_GET_RAW_RESULT_MODE): Define target hook.
|
||||
(TARGET_GET_RAW_ARG_MODE): Define target hook.
|
||||
(TARGET_DWARF_FRAME_REG_MODE): Define target hook.
|
||||
* config/mips/mips.h (TARGET_FLOAT32): New macro.
|
||||
(TARGET_O32_FP64A_ABI): Likewise.
|
||||
(TARGET_CPU_CPP_BUILTINS): TARGET_FPXX is __mips_fpr==0. Add
|
||||
_MIPS_SPFPSET builtin define.
|
||||
(MIPS_FPXX_OPTION_SPEC): New macro.
|
||||
(OPTION_DEFAULT_SPECS): Pass through --with-fp-32=* to -mfp and
|
||||
--with-odd-spreg-32=* to -m[no-]odd-spreg.
|
||||
(ISA_HAS_ODD_SPREG): New macro.
|
||||
(ISA_HAS_MXHC1): True for anything other than -mfp32.
|
||||
(ASM_SPEC): Pass through mfpxx, mfp64, -mno-odd-spreg and -modd-spreg.
|
||||
(MIN_FPRS_PER_FMT): Redefine in terms of TARGET_ODD_SPREG.
|
||||
(HARD_REGNO_CALLER_SAVE_MODE): Define. Implement O32 FPXX extension
|
||||
(HARD_REGNO_CALL_PART_CLOBBERED): Likewise.
|
||||
(SECONDARY_MEMORY_NEEDED): Likewise.
|
||||
(FUNCTION_ARG_REGNO_P): Update for O32 FPXX and FP64 extensions.
|
||||
* config/mips/mips.md (define_attr enabled): Implement O32 FPXX and
|
||||
FP64A ABI extensions.
|
||||
(move_doubleword_fpr<mode>): Use ISA_HAS_MXHC1 instead of
|
||||
TARGET_FLOAT64.
|
||||
* config/mips/mips.opt (mfpxx): New target option.
|
||||
(modd-spreg): Likewise.
|
||||
* config/mips/mti-elf.h (DRIVER_SELF_SPECS): Infer FP ABI from arch.
|
||||
* config/mips/mti-linux.h (DRIVER_SELF_SPECS): Likewise and remove
|
||||
fp64 sysroot.
|
||||
* config/mips/t-mti-elf: Remove fp64 multilib.
|
||||
* config/mips/t-mti-linux: Likewise.
|
||||
* configure.ac: Detect .module support.
|
||||
* configure: Regenerate.
|
||||
* doc/invoke.texi: Document -mfpxx, -modd-spreg, -mno-odd-spreg option.
|
||||
* doc/install.texi (--with-fp-32, --with-odd-spreg-32): Document new
|
||||
options.
|
||||
|
||||
2014-11-12 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/63815
|
||||
|
|
|
@ -42,6 +42,15 @@ mips_handle_option (struct gcc_options *opts,
|
|||
opts->x_mips_cache_flush_func = NULL;
|
||||
return true;
|
||||
|
||||
case OPT_mfp32:
|
||||
case OPT_mfp64:
|
||||
opts->x_target_flags &= ~MASK_FLOATXX;
|
||||
return true;
|
||||
|
||||
case OPT_mfpxx:
|
||||
opts->x_target_flags &= ~MASK_FLOAT64;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -3754,7 +3754,7 @@ case "${target}" in
|
|||
;;
|
||||
|
||||
mips*-*-*)
|
||||
supported_defaults="abi arch arch_32 arch_64 float fpu nan tune tune_32 tune_64 divide llsc mips-plt synci"
|
||||
supported_defaults="abi arch arch_32 arch_64 float fpu nan fp_32 odd_spreg_32 tune tune_32 tune_64 divide llsc mips-plt synci"
|
||||
|
||||
case ${with_float} in
|
||||
"" | soft | hard)
|
||||
|
@ -3786,6 +3786,32 @@ case "${target}" in
|
|||
;;
|
||||
esac
|
||||
|
||||
case ${with_fp_32} in
|
||||
"" | 32 | xx | 64)
|
||||
# OK
|
||||
;;
|
||||
*)
|
||||
echo "Unknown FP mode used in --with-fp-32=$with_fp_32" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${with_odd_spreg_32} in
|
||||
yes)
|
||||
with_odd_spreg_32="odd-spreg"
|
||||
;;
|
||||
no)
|
||||
with_odd_spreg_32="no-odd-spreg"
|
||||
;;
|
||||
"")
|
||||
# OK
|
||||
;;
|
||||
*)
|
||||
echo "Unknown odd-spreg-32 type used in --with-odd-spreg-32=$with_odd_spreg_32" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${with_abi} in
|
||||
"" | 32 | o64 | n32 | 64 | eabi)
|
||||
# OK
|
||||
|
@ -4213,7 +4239,7 @@ case ${target} in
|
|||
esac
|
||||
|
||||
t=
|
||||
all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu nan divide llsc mips-plt synci tls"
|
||||
all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu nan fp_32 odd_spreg_32 divide llsc mips-plt synci tls"
|
||||
for option in $all_defaults
|
||||
do
|
||||
eval "val=\$with_"`echo $option | sed s/-/_/g`
|
||||
|
|
|
@ -472,6 +472,12 @@
|
|||
#endif
|
||||
|
||||
|
||||
/* Define if the assembler understands .module. */
|
||||
#ifndef USED_FOR_TARGET
|
||||
#undef HAVE_AS_DOT_MODULE
|
||||
#endif
|
||||
|
||||
|
||||
/* Define if your assembler supports the -no-mul-bug-abort option. */
|
||||
#ifndef USED_FOR_TARGET
|
||||
#undef HAVE_AS_NO_MUL_BUG_ABORT_OPTION
|
||||
|
|
|
@ -278,6 +278,8 @@ extern void mips_expand_before_return (void);
|
|||
extern void mips_expand_epilogue (bool);
|
||||
extern bool mips_can_use_return_insn (void);
|
||||
|
||||
extern bool mips_secondary_memory_needed (enum reg_class, enum reg_class,
|
||||
machine_mode);
|
||||
extern bool mips_cannot_change_mode_class (machine_mode,
|
||||
machine_mode, enum reg_class);
|
||||
extern bool mips_dangerous_for_la25_p (rtx);
|
||||
|
@ -287,6 +289,9 @@ extern enum reg_class mips_secondary_reload_class (enum reg_class,
|
|||
rtx, bool);
|
||||
extern int mips_class_max_nregs (enum reg_class, machine_mode);
|
||||
|
||||
extern machine_mode mips_hard_regno_caller_save_mode (unsigned int,
|
||||
unsigned int,
|
||||
machine_mode);
|
||||
extern int mips_adjust_insn_length (rtx_insn *, int);
|
||||
extern void mips_output_load_label (rtx);
|
||||
extern const char *mips_output_conditional_branch (rtx_insn *, rtx *,
|
||||
|
|
|
@ -1232,6 +1232,7 @@ static rtx mips_find_pic_call_symbol (rtx_insn *, rtx, bool);
|
|||
static int mips_register_move_cost (machine_mode, reg_class_t,
|
||||
reg_class_t);
|
||||
static unsigned int mips_function_arg_boundary (machine_mode, const_tree);
|
||||
static machine_mode mips_get_reg_raw_mode (int regno);
|
||||
|
||||
struct mips16_flip_traits : default_hashmap_traits
|
||||
{
|
||||
|
@ -5160,6 +5161,7 @@ mips_get_arg_info (struct mips_arg_info *info, const CUMULATIVE_ARGS *cum,
|
|||
/* Only leading floating-point scalars are passed in
|
||||
floating-point registers. We also handle vector floats the same
|
||||
say, which is OK because they are not covered by the standard ABI. */
|
||||
gcc_assert (TARGET_PAIRED_SINGLE_FLOAT || mode != V2SFmode);
|
||||
info->fpr_p = (!cum->gp_reg_found
|
||||
&& cum->arg_number < 2
|
||||
&& (type == 0
|
||||
|
@ -5175,6 +5177,7 @@ mips_get_arg_info (struct mips_arg_info *info, const CUMULATIVE_ARGS *cum,
|
|||
/* Scalar, complex and vector floating-point types are passed in
|
||||
floating-point registers, as long as this is a named rather
|
||||
than a variable argument. */
|
||||
gcc_assert (TARGET_PAIRED_SINGLE_FLOAT || mode != V2SFmode);
|
||||
info->fpr_p = (named
|
||||
&& (type == 0 || FLOAT_TYPE_P (type))
|
||||
&& (GET_MODE_CLASS (mode) == MODE_FLOAT
|
||||
|
@ -5458,6 +5461,16 @@ mips_function_arg_boundary (machine_mode mode, const_tree type)
|
|||
return alignment;
|
||||
}
|
||||
|
||||
/* Implement TARGET_GET_RAW_RESULT_MODE and TARGET_GET_RAW_ARG_MODE. */
|
||||
|
||||
static machine_mode
|
||||
mips_get_reg_raw_mode (int regno)
|
||||
{
|
||||
if (TARGET_FLOATXX && FP_REG_P (regno))
|
||||
return DFmode;
|
||||
return default_get_reg_raw_mode (regno);
|
||||
}
|
||||
|
||||
/* Return true if FUNCTION_ARG_PADDING (MODE, TYPE) should return
|
||||
upward rather than downward. In other words, return true if the
|
||||
first byte of the stack slot has useful data, false if the last
|
||||
|
@ -5615,6 +5628,7 @@ mips_return_in_msb (const_tree valtype)
|
|||
static bool
|
||||
mips_return_mode_in_fpr_p (machine_mode mode)
|
||||
{
|
||||
gcc_assert (TARGET_PAIRED_SINGLE_FLOAT || mode != V2SFmode);
|
||||
return ((GET_MODE_CLASS (mode) == MODE_FLOAT
|
||||
|| mode == V2SFmode
|
||||
|| GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
|
||||
|
@ -5661,7 +5675,7 @@ mips_return_fpr_pair (machine_mode mode,
|
|||
{
|
||||
int inc;
|
||||
|
||||
inc = (TARGET_NEWABI ? 2 : MAX_FPRS_PER_FMT);
|
||||
inc = (TARGET_NEWABI || mips_abi == ABI_32 ? 2 : MAX_FPRS_PER_FMT);
|
||||
return gen_rtx_PARALLEL
|
||||
(mode,
|
||||
gen_rtvec (2,
|
||||
|
@ -5777,19 +5791,31 @@ mips_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
|
|||
|
||||
/* Implement TARGET_FUNCTION_VALUE_REGNO_P.
|
||||
|
||||
On the MIPS, R2 R3 and F0 F2 are the only register thus used.
|
||||
Currently, R2 and F0 are only implemented here (C has no complex type). */
|
||||
On the MIPS, R2 R3 and F0 F2 are the only register thus used. */
|
||||
|
||||
static bool
|
||||
mips_function_value_regno_p (const unsigned int regno)
|
||||
{
|
||||
/* Most types only require one GPR or one FPR for return values but for
|
||||
hard-float two FPRs can be used for _Complex types (for all ABIs)
|
||||
and long doubles (for n64). */
|
||||
if (regno == GP_RETURN
|
||||
|| regno == FP_RETURN
|
||||
|| (LONG_DOUBLE_TYPE_SIZE == 128
|
||||
&& FP_RETURN != GP_RETURN
|
||||
|| (FP_RETURN != GP_RETURN
|
||||
&& regno == FP_RETURN + 2))
|
||||
return true;
|
||||
|
||||
/* For o32 FP32, _Complex double will be returned in four 32-bit registers.
|
||||
This does not apply to o32 FPXX as floating-point function argument and
|
||||
return registers are described as 64-bit even though floating-point
|
||||
registers are primarily described as 32-bit internally.
|
||||
See: mips_get_reg_raw_mode. */
|
||||
if ((mips_abi == ABI_32 && TARGET_FLOAT32)
|
||||
&& FP_RETURN != GP_RETURN
|
||||
&& (regno == FP_RETURN + 1
|
||||
|| regno == FP_RETURN + 3))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -6497,7 +6523,10 @@ mips16_call_stub_mode_suffix (machine_mode mode)
|
|||
else if (mode == DCmode)
|
||||
return "dc";
|
||||
else if (mode == V2SFmode)
|
||||
return "df";
|
||||
{
|
||||
gcc_assert (TARGET_PAIRED_SINGLE_FLOAT);
|
||||
return "df";
|
||||
}
|
||||
else
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
@ -6521,13 +6550,27 @@ mips_output_64bit_xfer (char direction, unsigned int gpreg, unsigned int fpreg)
|
|||
if (TARGET_64BIT)
|
||||
fprintf (asm_out_file, "\tdm%cc1\t%s,%s\n", direction,
|
||||
reg_names[gpreg], reg_names[fpreg]);
|
||||
else if (TARGET_FLOAT64)
|
||||
else if (ISA_HAS_MXHC1)
|
||||
{
|
||||
fprintf (asm_out_file, "\tm%cc1\t%s,%s\n", direction,
|
||||
reg_names[gpreg + TARGET_BIG_ENDIAN], reg_names[fpreg]);
|
||||
fprintf (asm_out_file, "\tm%chc1\t%s,%s\n", direction,
|
||||
reg_names[gpreg + TARGET_LITTLE_ENDIAN], reg_names[fpreg]);
|
||||
}
|
||||
else if (TARGET_FLOATXX && direction == 't')
|
||||
{
|
||||
/* Use the argument save area to move via memory. */
|
||||
fprintf (asm_out_file, "\tsw\t%s,0($sp)\n", reg_names[gpreg]);
|
||||
fprintf (asm_out_file, "\tsw\t%s,4($sp)\n", reg_names[gpreg + 1]);
|
||||
fprintf (asm_out_file, "\tldc1\t%s,0($sp)\n", reg_names[fpreg]);
|
||||
}
|
||||
else if (TARGET_FLOATXX && direction == 'f')
|
||||
{
|
||||
/* Use the argument save area to move via memory. */
|
||||
fprintf (asm_out_file, "\tsdc1\t%s,0($sp)\n", reg_names[fpreg]);
|
||||
fprintf (asm_out_file, "\tlw\t%s,0($sp)\n", reg_names[gpreg]);
|
||||
fprintf (asm_out_file, "\tlw\t%s,4($sp)\n", reg_names[gpreg + 1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Move the least-significant word. */
|
||||
|
@ -6935,11 +6978,11 @@ mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code)
|
|||
case SCmode:
|
||||
mips_output_32bit_xfer ('f', GP_RETURN + TARGET_BIG_ENDIAN,
|
||||
TARGET_BIG_ENDIAN
|
||||
? FP_REG_FIRST + MAX_FPRS_PER_FMT
|
||||
? FP_REG_FIRST + 2
|
||||
: FP_REG_FIRST);
|
||||
mips_output_32bit_xfer ('f', GP_RETURN + TARGET_LITTLE_ENDIAN,
|
||||
TARGET_LITTLE_ENDIAN
|
||||
? FP_REG_FIRST + MAX_FPRS_PER_FMT
|
||||
? FP_REG_FIRST + 2
|
||||
: FP_REG_FIRST);
|
||||
if (GET_MODE (retval) == SCmode && TARGET_64BIT)
|
||||
{
|
||||
|
@ -6968,10 +7011,12 @@ mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code)
|
|||
|
||||
case DCmode:
|
||||
mips_output_64bit_xfer ('f', GP_RETURN + (8 / UNITS_PER_WORD),
|
||||
FP_REG_FIRST + MAX_FPRS_PER_FMT);
|
||||
FP_REG_FIRST + 2);
|
||||
/* Fall though. */
|
||||
case DFmode:
|
||||
case V2SFmode:
|
||||
gcc_assert (TARGET_PAIRED_SINGLE_FLOAT
|
||||
|| GET_MODE (retval) != V2SFmode);
|
||||
mips_output_64bit_xfer ('f', GP_RETURN, FP_REG_FIRST);
|
||||
break;
|
||||
|
||||
|
@ -8682,14 +8727,28 @@ mips_dwarf_register_span (rtx reg)
|
|||
rtx high, low;
|
||||
machine_mode mode;
|
||||
|
||||
/* TARGET_FLOATXX is implemented as 32-bit floating-point registers but
|
||||
ensures that double-precision registers are treated as if they were
|
||||
64-bit physical registers. The code will run correctly with 32-bit or
|
||||
64-bit registers which means that dwarf information cannot be precise
|
||||
for all scenarios. We choose to state that the 64-bit values are stored
|
||||
in a single 64-bit 'piece'. This slightly unusual construct can then be
|
||||
interpreted as either a pair of registers if the registers are 32-bit or
|
||||
a single 64-bit register depending on hardware. */
|
||||
mode = GET_MODE (reg);
|
||||
if (FP_REG_P (REGNO (reg))
|
||||
&& TARGET_FLOATXX
|
||||
&& GET_MODE_SIZE (mode) > UNITS_PER_FPREG)
|
||||
{
|
||||
return gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, reg));
|
||||
}
|
||||
/* By default, GCC maps increasing register numbers to increasing
|
||||
memory locations, but paired FPRs are always little-endian,
|
||||
regardless of the prevailing endianness. */
|
||||
mode = GET_MODE (reg);
|
||||
if (FP_REG_P (REGNO (reg))
|
||||
&& TARGET_BIG_ENDIAN
|
||||
&& MAX_FPRS_PER_FMT > 1
|
||||
&& GET_MODE_SIZE (mode) > UNITS_PER_FPREG)
|
||||
else if (FP_REG_P (REGNO (reg))
|
||||
&& TARGET_BIG_ENDIAN
|
||||
&& MAX_FPRS_PER_FMT > 1
|
||||
&& GET_MODE_SIZE (mode) > UNITS_PER_FPREG)
|
||||
{
|
||||
gcc_assert (GET_MODE_SIZE (mode) == UNITS_PER_HWFPVALUE);
|
||||
high = mips_subword (reg, true);
|
||||
|
@ -8700,6 +8759,19 @@ mips_dwarf_register_span (rtx reg)
|
|||
return NULL_RTX;
|
||||
}
|
||||
|
||||
/* Implement TARGET_DWARF_FRAME_REG_MODE. */
|
||||
|
||||
static machine_mode
|
||||
mips_dwarf_frame_reg_mode (int regno)
|
||||
{
|
||||
machine_mode mode = default_dwarf_frame_reg_mode (regno);
|
||||
|
||||
if (FP_REG_P (regno) && mips_abi == ABI_32 && TARGET_FLOAT64)
|
||||
mode = SImode;
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
/* DSP ALU can bypass data with no delays for the following pairs. */
|
||||
enum insn_code dspalu_bypass_table[][2] =
|
||||
{
|
||||
|
@ -8979,6 +9051,31 @@ mips_file_start (void)
|
|||
fprintf (asm_out_file, "\t.nan\t%s\n",
|
||||
mips_nan == MIPS_IEEE_754_2008 ? "2008" : "legacy");
|
||||
|
||||
#ifdef HAVE_AS_DOT_MODULE
|
||||
/* Record the FP ABI. See below for comments. */
|
||||
if (TARGET_NO_FLOAT)
|
||||
#ifdef HAVE_AS_GNU_ATTRIBUTE
|
||||
fputs ("\t.gnu_attribute 4, 0\n", asm_out_file);
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
else if (!TARGET_HARD_FLOAT_ABI)
|
||||
fputs ("\t.module\tsoftfloat\n", asm_out_file);
|
||||
else if (!TARGET_DOUBLE_FLOAT)
|
||||
fputs ("\t.module\tsinglefloat\n", asm_out_file);
|
||||
else if (TARGET_FLOATXX)
|
||||
fputs ("\t.module\tfp=xx\n", asm_out_file);
|
||||
else if (TARGET_FLOAT64)
|
||||
fputs ("\t.module\tfp=64\n", asm_out_file);
|
||||
else
|
||||
fputs ("\t.module\tfp=32\n", asm_out_file);
|
||||
|
||||
if (TARGET_ODD_SPREG)
|
||||
fputs ("\t.module\toddspreg\n", asm_out_file);
|
||||
else
|
||||
fputs ("\t.module\tnooddspreg\n", asm_out_file);
|
||||
|
||||
#else
|
||||
#ifdef HAVE_AS_GNU_ATTRIBUTE
|
||||
{
|
||||
int attr;
|
||||
|
@ -8992,15 +9089,26 @@ mips_file_start (void)
|
|||
/* Single-float code, -msingle-float. */
|
||||
else if (!TARGET_DOUBLE_FLOAT)
|
||||
attr = 2;
|
||||
/* 64-bit FP registers on a 32-bit target, -mips32r2 -mfp64. */
|
||||
else if (!TARGET_64BIT && TARGET_FLOAT64)
|
||||
attr = 4;
|
||||
/* 64-bit FP registers on a 32-bit target, -mips32r2 -mfp64.
|
||||
Reserved attr=4.
|
||||
This case used 12 callee-saved double-precision registers
|
||||
and is deprecated. */
|
||||
/* 64-bit or 32-bit FP registers on a 32-bit target, -mfpxx. */
|
||||
else if (TARGET_FLOATXX)
|
||||
attr = 5;
|
||||
/* 64-bit FP registers on a 32-bit target, -mfp64 -modd-spreg. */
|
||||
else if (mips_abi == ABI_32 && TARGET_FLOAT64 && TARGET_ODD_SPREG)
|
||||
attr = 6;
|
||||
/* 64-bit FP registers on a 32-bit target, -mfp64 -mno-odd-spreg. */
|
||||
else if (mips_abi == ABI_32 && TARGET_FLOAT64)
|
||||
attr = 7;
|
||||
/* Regular FP code, FP regs same size as GP regs, -mdouble-float. */
|
||||
else
|
||||
attr = 1;
|
||||
|
||||
fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n", attr);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* If TARGET_ABICALLS, tell GAS to generate -KPIC code. */
|
||||
|
@ -10491,7 +10599,9 @@ mips_for_each_saved_acc (HOST_WIDE_INT sp_offset, mips_save_restore_fn fn)
|
|||
static void
|
||||
mips_save_reg (rtx reg, rtx mem)
|
||||
{
|
||||
if (GET_MODE (reg) == DFmode && !TARGET_FLOAT64)
|
||||
if (GET_MODE (reg) == DFmode
|
||||
&& (!TARGET_FLOAT64
|
||||
|| mips_abi == ABI_32))
|
||||
{
|
||||
rtx x1, x2;
|
||||
|
||||
|
@ -10649,7 +10759,16 @@ mips_for_each_saved_gpr_and_fpr (HOST_WIDE_INT sp_offset,
|
|||
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);
|
||||
if (!TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT
|
||||
&& (fixed_regs[regno] || fixed_regs[regno + 1]))
|
||||
{
|
||||
if (fixed_regs[regno])
|
||||
mips_save_restore_reg (SFmode, regno + 1, offset, fn);
|
||||
else
|
||||
mips_save_restore_reg (SFmode, regno, offset, fn);
|
||||
}
|
||||
else
|
||||
mips_save_restore_reg (fpr_mode, regno, offset, fn);
|
||||
offset -= GET_MODE_SIZE (fpr_mode);
|
||||
}
|
||||
}
|
||||
|
@ -11420,7 +11539,9 @@ mips_restore_reg (rtx reg, rtx mem)
|
|||
$7 instead and adjust the return insn appropriately. */
|
||||
if (TARGET_MIPS16 && REGNO (reg) == RETURN_ADDR_REGNUM)
|
||||
reg = gen_rtx_REG (GET_MODE (reg), GP_REG_FIRST + 7);
|
||||
else if (GET_MODE (reg) == DFmode && !TARGET_FLOAT64)
|
||||
else if (GET_MODE (reg) == DFmode
|
||||
&& (!TARGET_FLOAT64
|
||||
|| mips_abi == ABI_32))
|
||||
{
|
||||
mips_add_cfa_restore (mips_subword (reg, true));
|
||||
mips_add_cfa_restore (mips_subword (reg, false));
|
||||
|
@ -11770,6 +11891,11 @@ mips_hard_regno_mode_ok_p (unsigned int regno, machine_mode mode)
|
|||
&& (((regno - FP_REG_FIRST) % MAX_FPRS_PER_FMT) == 0
|
||||
|| (MIN_FPRS_PER_FMT == 1 && size <= UNITS_PER_FPREG)))
|
||||
{
|
||||
/* Deny use of odd-numbered registers for 32-bit data for
|
||||
the o32 FP64A ABI. */
|
||||
if (TARGET_O32_FP64A_ABI && size <= 4 && (regno & 1) != 0)
|
||||
return false;
|
||||
|
||||
/* Allow 64-bit vector modes for Loongson-2E/2F. */
|
||||
if (TARGET_LOONGSON_VECTORS
|
||||
&& (mode == V2SImode
|
||||
|
@ -12124,6 +12250,25 @@ mips_memory_move_cost (machine_mode mode, reg_class_t rclass, bool in)
|
|||
+ memory_move_secondary_cost (mode, rclass, in));
|
||||
}
|
||||
|
||||
/* Implement SECONDARY_MEMORY_NEEDED. */
|
||||
|
||||
bool
|
||||
mips_secondary_memory_needed (enum reg_class class1, enum reg_class class2,
|
||||
machine_mode mode)
|
||||
{
|
||||
/* Ignore spilled pseudos. */
|
||||
if (lra_in_progress && (class1 == NO_REGS || class2 == NO_REGS))
|
||||
return false;
|
||||
|
||||
if (((class1 == FP_REGS) != (class2 == FP_REGS))
|
||||
&& ((TARGET_FLOATXX && !ISA_HAS_MXHC1)
|
||||
|| TARGET_O32_FP64A_ABI)
|
||||
&& GET_MODE_SIZE (mode) >= 8)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Return the register class required for a secondary register when
|
||||
copying between one of the registers in RCLASS and value X, which
|
||||
has mode MODE. X is the source of the move if IN_P, otherwise it
|
||||
|
@ -17041,6 +17186,13 @@ mips_option_override (void)
|
|||
target_flags &= ~MASK_FLOAT64;
|
||||
}
|
||||
|
||||
if (mips_abi != ABI_32 && TARGET_FLOATXX)
|
||||
error ("%<-mfpxx%> can only be used with the o32 ABI");
|
||||
else if (ISA_MIPS1 && !TARGET_FLOAT32)
|
||||
error ("%<-march=%s%> requires %<-mfp32%>", mips_arch_info->name);
|
||||
else if (TARGET_FLOATXX && !mips_lra_flag)
|
||||
error ("%<-mfpxx%> requires %<-mlra%>");
|
||||
|
||||
/* End of code shared with GAS. */
|
||||
|
||||
/* The R5900 FPU only supports single precision. */
|
||||
|
@ -17128,6 +17280,28 @@ mips_option_override (void)
|
|||
warning (0, "the %qs architecture does not support madd or msub"
|
||||
" instructions", mips_arch_info->name);
|
||||
|
||||
/* If neither -modd-spreg nor -mno-odd-spreg was given on the command
|
||||
line, set MASK_ODD_SPREG based on the ISA and ABI. */
|
||||
if ((target_flags_explicit & MASK_ODD_SPREG) == 0)
|
||||
{
|
||||
/* Disable TARGET_ODD_SPREG when using the o32 FPXX ABI. */
|
||||
if (!ISA_HAS_ODD_SPREG || TARGET_FLOATXX)
|
||||
target_flags &= ~MASK_ODD_SPREG;
|
||||
else
|
||||
target_flags |= MASK_ODD_SPREG;
|
||||
}
|
||||
else if (TARGET_ODD_SPREG && !ISA_HAS_ODD_SPREG)
|
||||
warning (0, "the %qs architecture does not support odd single-precision"
|
||||
" registers", mips_arch_info->name);
|
||||
|
||||
if (!TARGET_ODD_SPREG && TARGET_64BIT)
|
||||
{
|
||||
error ("unsupported combination: %s", "-mgp64 -mno-odd-spreg");
|
||||
/* Allow compilation to continue further even though invalid output
|
||||
will be produced. */
|
||||
target_flags |= MASK_ODD_SPREG;
|
||||
}
|
||||
|
||||
/* The effect of -mabicalls isn't defined for the EABI. */
|
||||
if (mips_abi == ABI_EABI && TARGET_ABICALLS)
|
||||
{
|
||||
|
@ -17490,8 +17664,10 @@ mips_conditional_register_usage (void)
|
|||
call_really_used_regs[regno] = call_used_regs[regno] = 1;
|
||||
}
|
||||
/* Odd registers in the range $f21-$f31 (inclusive) are call-clobbered
|
||||
for n32. */
|
||||
if (mips_abi == ABI_N32)
|
||||
for n32 and o32 FP64. */
|
||||
if (mips_abi == ABI_N32
|
||||
|| (mips_abi == ABI_32
|
||||
&& TARGET_FLOAT64))
|
||||
{
|
||||
int regno;
|
||||
for (regno = FP_REG_FIRST + 21; regno <= FP_REG_FIRST + 31; regno+=2)
|
||||
|
@ -18824,6 +19000,21 @@ mips_expand_vec_minmax (rtx target, rtx op0, rtx op1,
|
|||
emit_insn (gen_rtx_SET (VOIDmode, target, x));
|
||||
}
|
||||
|
||||
/* Implement HARD_REGNO_CALLER_SAVE_MODE. */
|
||||
|
||||
machine_mode
|
||||
mips_hard_regno_caller_save_mode (unsigned int regno,
|
||||
unsigned int nregs,
|
||||
machine_mode mode)
|
||||
{
|
||||
/* For performance, avoid saving/restoring upper parts of a register
|
||||
by returning MODE as save mode when the mode is known. */
|
||||
if (mode == VOIDmode)
|
||||
return choose_hard_reg_mode (regno, nregs, false);
|
||||
else
|
||||
return mode;
|
||||
}
|
||||
|
||||
/* Implement TARGET_CASE_VALUES_THRESHOLD. */
|
||||
|
||||
unsigned int
|
||||
|
@ -19043,6 +19234,10 @@ mips_lra_p (void)
|
|||
#define TARGET_FUNCTION_ARG_ADVANCE mips_function_arg_advance
|
||||
#undef TARGET_FUNCTION_ARG_BOUNDARY
|
||||
#define TARGET_FUNCTION_ARG_BOUNDARY mips_function_arg_boundary
|
||||
#undef TARGET_GET_RAW_RESULT_MODE
|
||||
#define TARGET_GET_RAW_RESULT_MODE mips_get_reg_raw_mode
|
||||
#undef TARGET_GET_RAW_ARG_MODE
|
||||
#define TARGET_GET_RAW_ARG_MODE mips_get_reg_raw_mode
|
||||
|
||||
#undef TARGET_MODE_REP_EXTENDED
|
||||
#define TARGET_MODE_REP_EXTENDED mips_mode_rep_extended
|
||||
|
@ -19099,6 +19294,8 @@ mips_lra_p (void)
|
|||
#endif
|
||||
#undef TARGET_DWARF_REGISTER_SPAN
|
||||
#define TARGET_DWARF_REGISTER_SPAN mips_dwarf_register_span
|
||||
#undef TARGET_DWARF_FRAME_REG_MODE
|
||||
#define TARGET_DWARF_FRAME_REG_MODE mips_dwarf_frame_reg_mode
|
||||
|
||||
#undef TARGET_ASM_FINAL_POSTSCAN_INSN
|
||||
#define TARGET_ASM_FINAL_POSTSCAN_INSN mips_final_postscan_insn
|
||||
|
|
|
@ -323,6 +323,15 @@ struct mips_cpu_info {
|
|||
#define TARGET_HARD_FLOAT (TARGET_HARD_FLOAT_ABI && !TARGET_MIPS16)
|
||||
#define TARGET_SOFT_FLOAT (TARGET_SOFT_FLOAT_ABI || TARGET_MIPS16)
|
||||
|
||||
/* TARGET_FLOAT64 represents -mfp64 and TARGET_FLOATXX represents
|
||||
-mfpxx, derive TARGET_FLOAT32 to represent -mfp32. */
|
||||
#define TARGET_FLOAT32 (!TARGET_FLOAT64 && !TARGET_FLOATXX)
|
||||
|
||||
/* TARGET_O32_FP64A_ABI represents all the conditions that form the
|
||||
o32 FP64A ABI extension (-mabi=32 -mfp64 -mno-odd-spreg). */
|
||||
#define TARGET_O32_FP64A_ABI (mips_abi == ABI_32 && TARGET_FLOAT64 \
|
||||
&& !TARGET_ODD_SPREG)
|
||||
|
||||
/* False if SC acts as a memory barrier with respect to itself,
|
||||
otherwise a SYNC will be emitted after SC for atomic operations
|
||||
that require ordering between the SC and following loads and
|
||||
|
@ -391,6 +400,8 @@ struct mips_cpu_info {
|
|||
\
|
||||
if (TARGET_FLOAT64) \
|
||||
builtin_define ("__mips_fpr=64"); \
|
||||
else if (TARGET_FLOATXX) \
|
||||
builtin_define ("__mips_fpr=0"); \
|
||||
else \
|
||||
builtin_define ("__mips_fpr=32"); \
|
||||
\
|
||||
|
@ -519,6 +530,8 @@ struct mips_cpu_info {
|
|||
builtin_define_with_int_value ("_MIPS_SZPTR", POINTER_SIZE); \
|
||||
builtin_define_with_int_value ("_MIPS_FPSET", \
|
||||
32 / MAX_FPRS_PER_FMT); \
|
||||
builtin_define_with_int_value ("_MIPS_SPFPSET", \
|
||||
TARGET_ODD_SPREG ? 32 : 16); \
|
||||
\
|
||||
/* These defines reflect the ABI in use, not whether the \
|
||||
FPU is directly accessible. */ \
|
||||
|
@ -754,6 +767,12 @@ struct mips_cpu_info {
|
|||
#define MIPS_32BIT_OPTION_SPEC \
|
||||
"mips1|mips2|mips32*|mgp32"
|
||||
|
||||
/* A spec condition that matches architectures should be targeted with
|
||||
o32 FPXX for compatibility reasons. */
|
||||
#define MIPS_FPXX_OPTION_SPEC \
|
||||
"mips2|mips3|mips4|mips5|mips32|mips32r2|mips32r3|mips32r5| \
|
||||
mips64|mips64r2|mips64r3|mips64r5"
|
||||
|
||||
/* Infer a -msynci setting from a -mips argument, on the assumption that
|
||||
-msynci is desired where possible. */
|
||||
#define MIPS_ISA_SYNCI_SPEC \
|
||||
|
@ -778,7 +797,12 @@ struct mips_cpu_info {
|
|||
--with-abi is ignored if -mabi is specified.
|
||||
--with-float is ignored if -mhard-float or -msoft-float are
|
||||
specified.
|
||||
--with-fpu is ignored if -msoft-float, -msingle-float or -mdouble-float are
|
||||
specified.
|
||||
--with-nan is ignored if -mnan is specified.
|
||||
--with-fp-32 is ignored if -msoft-float, -msingle-float or -mfp are specified.
|
||||
--with-odd-spreg-32 is ignored if -msoft-float, -msingle-float, -modd-spreg
|
||||
or -mno-odd-spreg are specified.
|
||||
--with-divide is ignored if -mdivide-traps or -mdivide-breaks are
|
||||
specified. */
|
||||
#define OPTION_DEFAULT_SPECS \
|
||||
|
@ -790,8 +814,12 @@ struct mips_cpu_info {
|
|||
{"tune_64", "%{" OPT_ARCH64 ":%{!mtune=*:-mtune=%(VALUE)}}" }, \
|
||||
{"abi", "%{!mabi=*:-mabi=%(VALUE)}" }, \
|
||||
{"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" }, \
|
||||
{"fpu", "%{!msingle-float:%{!mdouble-float:-m%(VALUE)-float}}" }, \
|
||||
{"fpu", "%{!msoft-float:%{!msingle-float:%{!mdouble-float:-m%(VALUE)-float}}}" }, \
|
||||
{"nan", "%{!mnan=*:-mnan=%(VALUE)}" }, \
|
||||
{"fp_32", "%{" OPT_ARCH32 \
|
||||
":%{!msoft-float:%{!msingle-float:%{!mfp*:-mfp%(VALUE)}}}}" }, \
|
||||
{"odd_spreg_32", "%{" OPT_ARCH32 ":%{!msoft-float:%{!msingle-float:" \
|
||||
"%{!modd-spreg:%{!mno-odd-spreg:-m%(VALUE)}}}}}" }, \
|
||||
{"divide", "%{!mdivide-traps:%{!mdivide-breaks:-mdivide-%(VALUE)}}" }, \
|
||||
{"llsc", "%{!mllsc:%{!mno-llsc:-m%(VALUE)}}" }, \
|
||||
{"mips-plt", "%{!mplt:%{!mno-plt:-m%(VALUE)}}" }, \
|
||||
|
@ -843,6 +871,12 @@ struct mips_cpu_info {
|
|||
been generated up to this point. */
|
||||
#define ISA_HAS_BRANCHLIKELY (!ISA_MIPS1)
|
||||
|
||||
/* ISA has 32 single-precision registers. */
|
||||
#define ISA_HAS_ODD_SPREG ((mips_isa_rev >= 1 \
|
||||
&& !TARGET_LOONGSON_3A) \
|
||||
|| TARGET_FLOAT64 \
|
||||
|| TARGET_MIPS5900)
|
||||
|
||||
/* ISA has a three-operand multiplication instruction (usually spelt "mul"). */
|
||||
#define ISA_HAS_MUL3 ((TARGET_MIPS3900 \
|
||||
|| TARGET_MIPS5400 \
|
||||
|
@ -1030,7 +1064,8 @@ struct mips_cpu_info {
|
|||
#define ISA_HAS_EXT_INS (mips_isa_rev >= 2 && !TARGET_MIPS16)
|
||||
|
||||
/* ISA has instructions for accessing top part of 64-bit fp regs. */
|
||||
#define ISA_HAS_MXHC1 (TARGET_FLOAT64 && mips_isa_rev >= 2)
|
||||
#define ISA_HAS_MXHC1 (!TARGET_FLOAT32 \
|
||||
&& mips_isa_rev >= 2)
|
||||
|
||||
/* ISA has lwxs instruction (load w/scaled index address. */
|
||||
#define ISA_HAS_LWXS ((TARGET_SMARTMIPS || TARGET_MICROMIPS) \
|
||||
|
@ -1186,7 +1221,8 @@ struct mips_cpu_info {
|
|||
%(subtarget_asm_debugging_spec) \
|
||||
%{mabi=*} %{!mabi=*: %(asm_abi_default_spec)} \
|
||||
%{mgp32} %{mgp64} %{march=*} %{mxgot:-xgot} \
|
||||
%{mfp32} %{mfp64} %{mnan=*} \
|
||||
%{mfp32} %{mfpxx} %{mfp64} %{mnan=*} \
|
||||
%{modd-spreg} %{mno-odd-spreg} \
|
||||
%{mshared} %{mno-shared} \
|
||||
%{msym32} %{mno-sym32} \
|
||||
%{mtune=*} \
|
||||
|
@ -1358,7 +1394,7 @@ struct mips_cpu_info {
|
|||
/* The number of consecutive floating-point registers needed to store the
|
||||
smallest format supported by the FPU. */
|
||||
#define MIN_FPRS_PER_FMT \
|
||||
(mips_isa_rev >= 1 ? 1 : MAX_FPRS_PER_FMT)
|
||||
(TARGET_ODD_SPREG ? 1 : MAX_FPRS_PER_FMT)
|
||||
|
||||
/* The largest size of value that can be held in floating-point
|
||||
registers and moved with a single instruction. */
|
||||
|
@ -1764,6 +1800,16 @@ struct mips_cpu_info {
|
|||
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
|
||||
mips_hard_regno_mode_ok[ (int)(MODE) ][ (REGNO) ]
|
||||
|
||||
/* Select a register mode required for caller save of hard regno REGNO. */
|
||||
#define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \
|
||||
mips_hard_regno_caller_save_mode (REGNO, NREGS, MODE)
|
||||
|
||||
/* Odd-numbered single-precision registers are not considered callee-saved
|
||||
for o32 FPXX as they will be clobbered when run on an FR=1 FPU. */
|
||||
#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \
|
||||
(TARGET_FLOATXX && hard_regno_nregs[REGNO][MODE] == 1 \
|
||||
&& FP_REG_P (REGNO) && ((REGNO) & 1))
|
||||
|
||||
#define MODES_TIEABLE_P mips_modes_tieable_p
|
||||
|
||||
/* Register to use for pushing function arguments. */
|
||||
|
@ -2097,6 +2143,19 @@ enum reg_class
|
|||
#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \
|
||||
mips_secondary_reload_class (CLASS, MODE, X, false)
|
||||
|
||||
/* When targeting the o32 FPXX ABI, all moves with a length of doubleword
|
||||
or greater must be performed by FR-mode-aware instructions.
|
||||
This can be achieved using MFHC1/MTHC1 when these instructions are
|
||||
available but otherwise moves must go via memory.
|
||||
For the o32 FP64A ABI, all odd-numbered moves with a length of
|
||||
doubleword or greater are required to use memory. Using MTC1/MFC1
|
||||
to access the lower-half of these registers would require a forbidden
|
||||
single-precision access. We require all double-word moves to use
|
||||
memory because adding even and odd floating-point registers classes
|
||||
would have a significant impact on the backend. */
|
||||
#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
|
||||
mips_secondary_memory_needed ((CLASS1), (CLASS2), (MODE))
|
||||
|
||||
/* Return the maximum number of consecutive registers
|
||||
needed to represent mode MODE in a register of class CLASS. */
|
||||
|
||||
|
@ -2218,12 +2277,16 @@ enum reg_class
|
|||
(TARGET_MIPS16 ? GP_ARG_FIRST + 2 : PIC_OFFSET_TABLE_REGNUM)
|
||||
|
||||
/* 1 if N is a possible register number for function argument passing.
|
||||
We have no FP argument registers when soft-float. When FP registers
|
||||
are 32 bits, we can't directly reference the odd numbered ones. */
|
||||
We have no FP argument registers when soft-float. Special handling
|
||||
is required for O32 where only even numbered registers are used for
|
||||
O32-FPXX and O32-FP64. */
|
||||
|
||||
#define FUNCTION_ARG_REGNO_P(N) \
|
||||
((IN_RANGE((N), GP_ARG_FIRST, GP_ARG_LAST) \
|
||||
|| (IN_RANGE((N), FP_ARG_FIRST, FP_ARG_LAST))) \
|
||||
|| (IN_RANGE((N), FP_ARG_FIRST, FP_ARG_LAST) \
|
||||
&& (mips_abi != ABI_32 \
|
||||
|| TARGET_FLOAT32 \
|
||||
|| ((N) % 2 == 0)))) \
|
||||
&& !fixed_regs[N])
|
||||
|
||||
/* This structure has to cope with two different argument allocation
|
||||
|
|
|
@ -433,11 +433,17 @@
|
|||
(const_string "none"))
|
||||
|
||||
(define_attr "enabled" "no,yes"
|
||||
(if_then_else (ior (eq_attr "compression" "all,none")
|
||||
(and (eq_attr "compression" "micromips")
|
||||
(match_test "TARGET_MICROMIPS")))
|
||||
(const_string "yes")
|
||||
(const_string "no")))
|
||||
(cond [;; The o32 FPXX and FP64A ABI extensions prohibit direct moves between
|
||||
;; GR_REG and FR_REG for 64-bit values.
|
||||
(and (eq_attr "move_type" "mtc,mfc")
|
||||
(match_test "(TARGET_FLOATXX && !ISA_HAS_MXHC1)
|
||||
|| TARGET_O32_FP64A_ABI")
|
||||
(eq_attr "dword_mode" "yes"))
|
||||
(const_string "no")
|
||||
(and (eq_attr "compression" "micromips")
|
||||
(match_test "!TARGET_MICROMIPS"))
|
||||
(const_string "no")]
|
||||
(const_string "yes")))
|
||||
|
||||
;; The number of individual instructions that a non-branch pattern generates,
|
||||
;; using units of BASE_INSN_LENGTH.
|
||||
|
@ -4997,7 +5003,7 @@
|
|||
rtx low = mips_subword (operands[1], 0);
|
||||
rtx high = mips_subword (operands[1], 1);
|
||||
emit_insn (gen_load_low<mode> (operands[0], low));
|
||||
if (TARGET_FLOAT64 && !TARGET_64BIT)
|
||||
if (ISA_HAS_MXHC1 && !TARGET_64BIT)
|
||||
emit_insn (gen_mthc1<mode> (operands[0], high, operands[0]));
|
||||
else
|
||||
emit_insn (gen_load_high<mode> (operands[0], high, operands[0]));
|
||||
|
@ -5007,7 +5013,7 @@
|
|||
rtx low = mips_subword (operands[0], 0);
|
||||
rtx high = mips_subword (operands[0], 1);
|
||||
emit_insn (gen_store_word<mode> (low, operands[1], const0_rtx));
|
||||
if (TARGET_FLOAT64 && !TARGET_64BIT)
|
||||
if (ISA_HAS_MXHC1 && !TARGET_64BIT)
|
||||
emit_insn (gen_mfhc1<mode> (high, operands[1]));
|
||||
else
|
||||
emit_insn (gen_store_word<mode> (high, operands[1], const1_rtx));
|
||||
|
|
|
@ -197,6 +197,10 @@ mfp32
|
|||
Target Report RejectNegative InverseMask(FLOAT64)
|
||||
Use 32-bit floating-point registers
|
||||
|
||||
mfpxx
|
||||
Target Report RejectNegative Mask(FLOATXX)
|
||||
Conform to the o32 FPXX ABI
|
||||
|
||||
mfp64
|
||||
Target Report RejectNegative Mask(FLOAT64)
|
||||
Use 64-bit floating-point registers
|
||||
|
@ -408,5 +412,9 @@ mxgot
|
|||
Target Report Var(TARGET_XGOT)
|
||||
Lift restrictions on GOT size
|
||||
|
||||
modd-spreg
|
||||
Target Report Mask(ODD_SPREG)
|
||||
Enable use of odd-numbered single-precision registers
|
||||
|
||||
noasmopt
|
||||
Driver
|
||||
|
|
|
@ -34,6 +34,11 @@ along with GCC; see the file COPYING3. If not see
|
|||
or -mgp setting. */ \
|
||||
"%{!mabi=*: %{" MIPS_32BIT_OPTION_SPEC ": -mabi=32;: -mabi=n32}}", \
|
||||
\
|
||||
/* If no FP ABI option is specified, infer one from the \
|
||||
ABI/ISA level. */ \
|
||||
"%{!msoft-float: %{!msingle-float: %{!mfp*: %{mabi=32: %{" \
|
||||
MIPS_FPXX_OPTION_SPEC ": -mfpxx}}}}}", \
|
||||
\
|
||||
/* Make sure that an endian option is always present. This makes \
|
||||
things like LINK_SPEC easier to write. */ \
|
||||
"%{!EB:%{!EL:%(endian_spec)}}", \
|
||||
|
|
|
@ -39,6 +39,11 @@ along with GCC; see the file COPYING3. If not see
|
|||
or -mgp setting. */ \
|
||||
"%{!mabi=*: %{" MIPS_32BIT_OPTION_SPEC ": -mabi=32;: -mabi=n32}}", \
|
||||
\
|
||||
/* If no FP ABI option is specified, infer one from the \
|
||||
ABI/ISA level. */ \
|
||||
"%{!msoft-float: %{!msingle-float: %{!mfp*: %{mabi=32: %{" \
|
||||
MIPS_FPXX_OPTION_SPEC ": -mfpxx}}}}}", \
|
||||
\
|
||||
/* Base SPECs. */ \
|
||||
BASE_DRIVER_SELF_SPECS \
|
||||
\
|
||||
|
|
|
@ -26152,6 +26152,41 @@ $as_echo "#define HAVE_AS_GNU_ATTRIBUTE 1" >>confdefs.h
|
|||
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .module support" >&5
|
||||
$as_echo_n "checking assembler for .module support... " >&6; }
|
||||
if test "${gcc_cv_as_mips_dot_module+set}" = set; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
gcc_cv_as_mips_dot_module=no
|
||||
if test x$gcc_cv_as != x; then
|
||||
$as_echo '.module fp=32' > conftest.s
|
||||
if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
|
||||
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; }; }
|
||||
then
|
||||
gcc_cv_as_mips_dot_module=yes
|
||||
else
|
||||
echo "configure: failed program was" >&5
|
||||
cat conftest.s >&5
|
||||
fi
|
||||
rm -f conftest.o conftest.s
|
||||
fi
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_mips_dot_module" >&5
|
||||
$as_echo "$gcc_cv_as_mips_dot_module" >&6; }
|
||||
if test $gcc_cv_as_mips_dot_module = yes; then
|
||||
|
||||
$as_echo "#define HAVE_AS_DOT_MODULE 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
if test x$gcc_cv_as_mips_dot_module = xno \
|
||||
&& test x$with_fp_32 != x; then
|
||||
as_fn_error "Requesting --with-fp-32= requires assembler support for .module." "$LINENO" 5
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .micromips support" >&5
|
||||
$as_echo_n "checking assembler for .micromips support... " >&6; }
|
||||
if test "${gcc_cv_as_micromips_support+set}" = set; then :
|
||||
|
|
|
@ -4241,6 +4241,17 @@ LCF0:
|
|||
[AC_DEFINE(HAVE_AS_GNU_ATTRIBUTE, 1,
|
||||
[Define if your assembler supports .gnu_attribute.])])
|
||||
|
||||
gcc_GAS_CHECK_FEATURE([.module support],
|
||||
gcc_cv_as_mips_dot_module,,,
|
||||
[.module fp=32],,
|
||||
[AC_DEFINE(HAVE_AS_DOT_MODULE, 1,
|
||||
[Define if your assembler supports .module.])])
|
||||
if test x$gcc_cv_as_mips_dot_module = xno \
|
||||
&& test x$with_fp_32 != x; then
|
||||
AC_MSG_ERROR(
|
||||
[Requesting --with-fp-32= requires assembler support for .module.])
|
||||
fi
|
||||
|
||||
gcc_GAS_CHECK_FEATURE([.micromips support],
|
||||
gcc_cv_as_micromips_support,,[--fatal-warnings],
|
||||
[.set micromips],,
|
||||
|
|
|
@ -1261,6 +1261,32 @@ ISA for floating-point arithmetics. You can select either @samp{sse} which
|
|||
enables @option{-msse2} or @samp{avx} which enables @option{-mavx} by default.
|
||||
This option is only supported on i386 and x86-64 targets.
|
||||
|
||||
@item --with-fp-32=@var{mode}
|
||||
On MIPS targets, set the default value for the @option{-mfp} option when using
|
||||
the o32 ABI. The possibilities for @var{mode} are:
|
||||
@table @code
|
||||
@item 32
|
||||
Use the o32 FP32 ABI extension, as with the @option{-mfp32} command-line
|
||||
option.
|
||||
@item xx
|
||||
Use the o32 FPXX ABI extension, as with the @option{-mfpxx} command-line
|
||||
option.
|
||||
@item 64
|
||||
Use the o32 FP64 ABI extension, as with the @option{-mfp64} command-line
|
||||
option.
|
||||
@end table
|
||||
In the absence of this configuration option the default is to use the o32
|
||||
FP32 ABI extension.
|
||||
|
||||
@item --with-odd-spreg-32
|
||||
On MIPS targets, set the @option{-modd-spreg} option by default when using
|
||||
the o32 ABI.
|
||||
|
||||
@item --without-odd-spreg-32
|
||||
On MIPS targets, set the @option{-mno-odd-spreg} option by default when using
|
||||
the o32 ABI. This is normally used in conjunction with
|
||||
@option{--with-fp-32=64} in order to target the o32 FP64A ABI extension.
|
||||
|
||||
@item --with-nan=@var{encoding}
|
||||
On MIPS targets, set the default encoding convention to use for the
|
||||
special not-a-number (NaN) IEEE 754 floating-point data. The
|
||||
|
|
|
@ -788,8 +788,9 @@ Objective-C and Objective-C++ Dialects}.
|
|||
-minterlink-mips16 -mno-interlink-mips16 @gol
|
||||
-mabi=@var{abi} -mabicalls -mno-abicalls @gol
|
||||
-mshared -mno-shared -mplt -mno-plt -mxgot -mno-xgot @gol
|
||||
-mgp32 -mgp64 -mfp32 -mfp64 -mhard-float -msoft-float @gol
|
||||
-mgp32 -mgp64 -mfp32 -mfpxx -mfp64 -mhard-float -msoft-float @gol
|
||||
-mno-float -msingle-float -mdouble-float @gol
|
||||
-modd-spreg -mno-odd-spreg @gol
|
||||
-mabs=@var{mode} -mnan=@var{encoding} @gol
|
||||
-mdsp -mno-dsp -mdspr2 -mno-dspr2 @gol
|
||||
-mmcu -mmno-mcu @gol
|
||||
|
@ -17745,7 +17746,20 @@ same, but each scalar value is passed in a single 64-bit register
|
|||
rather than a pair of 32-bit registers. For example, scalar
|
||||
floating-point values are returned in @samp{$f0} only, not a
|
||||
@samp{$f0}/@samp{$f1} pair. The set of call-saved registers also
|
||||
remains the same, but all 64 bits are saved.
|
||||
remains the same in that the even-numbered double-precision registers
|
||||
are saved.
|
||||
|
||||
Two additional variants of the o32 ABI are supported to enable
|
||||
a transition from 32-bit to 64-bit registers. These are FPXX
|
||||
(@option{-mfpxx}) and FP64A (@option{-mfp64} @option{-mno-odd-spreg}).
|
||||
The FPXX extension mandates that all code must execute correctly
|
||||
when run using 32-bit or 64-bit registers. The code can be interlinked
|
||||
with either FP32 or FP64, but not both.
|
||||
The FP64A extension is similar to the FP64 extension but forbids the
|
||||
use of odd-numbered single-precision registers. This can be used
|
||||
in conjunction with the @code{FRE} mode of FPUs in MIPS32R5
|
||||
processors and allows both FP32 and FP64A code to interlink and
|
||||
run in the same process without changing FPU modes.
|
||||
|
||||
@item -mabicalls
|
||||
@itemx -mno-abicalls
|
||||
|
@ -17834,6 +17848,10 @@ Assume that floating-point registers are 32 bits wide.
|
|||
@opindex mfp64
|
||||
Assume that floating-point registers are 64 bits wide.
|
||||
|
||||
@item -mfpxx
|
||||
@opindex mfpxx
|
||||
Do not assume the width of floating-point registers.
|
||||
|
||||
@item -mhard-float
|
||||
@opindex mhard-float
|
||||
Use floating-point coprocessor instructions.
|
||||
|
@ -17865,6 +17883,15 @@ operations.
|
|||
Assume that the floating-point coprocessor supports double-precision
|
||||
operations. This is the default.
|
||||
|
||||
@item -modd-spreg
|
||||
@itemx -mno-odd-spreg
|
||||
@opindex modd-spreg
|
||||
@opindex mno-odd-spreg
|
||||
Enable the use of odd-numbered single-precision floating-point registers
|
||||
for the o32 ABI. This is the default for processors that are known to
|
||||
support these registers. When using the o32 FPXX ABI, @code{-mno-odd-spreg}
|
||||
is set by default.
|
||||
|
||||
@item -mabs=2008
|
||||
@itemx -mabs=legacy
|
||||
@opindex mabs=2008
|
||||
|
|
|
@ -1,3 +1,27 @@
|
|||
2014-11-12 Matthew Fortune <matthew.fortune@imgtec.com>
|
||||
|
||||
* gcc.target/mips/args-1.c: Handle __mips_fpr == 0.
|
||||
* gcc.target/mips/call-clobbered-1.c: New.
|
||||
* gcc.target/mips/call-clobbered-2.c: New.
|
||||
* gcc.target/mips/call-clobbered-3.c: New.
|
||||
* gcc.target/mips/call-clobbered-4.c: New.
|
||||
* gcc.target/mips/call-clobbered-5.c: New.
|
||||
* gcc.target/mips/call-saved-4.c: New.
|
||||
* gcc.target/mips/call-saved-5.c: New.
|
||||
* gcc.target/mips/call-saved-6.c: New.
|
||||
* gcc.target/mips/mips.exp: Support -mfpxx, -ffixed-f*,
|
||||
and -m[no-]odd-spreg. Use _MIPS_SPFPSET to determine default
|
||||
odd-spreg option. Account for -modd-spreg in minimum arch code.
|
||||
* gcc.target/mips/movdf-1.c: New.
|
||||
* gcc.target/mips/movdf-2.c: New.
|
||||
* gcc.target/mips/movdf-3.c: New.
|
||||
* gcc.target/mips/oddspreg-1.c: New.
|
||||
* gcc.target/mips/oddspreg-2.c: New.
|
||||
* gcc.target/mips/oddspreg-3.c: New.
|
||||
* gcc.target/mips/oddspreg-4.c: New.
|
||||
* gcc.target/mips/oddspreg-5.c: New.
|
||||
* gcc.target/mips/oddspreg-6.c: New.
|
||||
|
||||
2014-11-12 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/63815
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
const char *compiled_for = _MIPS_ARCH;
|
||||
const char *optimized_for = _MIPS_TUNE;
|
||||
|
||||
#if __mips_fpr != 32 && __mips_fpr != 64
|
||||
#if __mips_fpr != 32 && __mips_fpr != 64 && __mips_fpr != 0
|
||||
#error Bad __mips_fpr
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/* Check that we handle call-clobbered FPRs correctly. */
|
||||
/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
|
||||
/* { dg-options "isa>=2 -mabi=32 -ffixed-f0 -ffixed-f1 -ffixed-f2 -ffixed-f3 -ffixed-f4 -ffixed-f5 -ffixed-f6 -ffixed-f7 -ffixed-f8 -ffixed-f9 -ffixed-f10 -ffixed-f11 -ffixed-f12 -ffixed-f13 -ffixed-f14 -ffixed-f15 -ffixed-f16 -ffixed-f17 -ffixed-f18 -ffixed-f19" } */
|
||||
|
||||
void bar (void);
|
||||
double a;
|
||||
double
|
||||
foo ()
|
||||
{
|
||||
double b = a + 1.0;
|
||||
bar();
|
||||
return b;
|
||||
}
|
||||
/* { dg-final { scan-assembler-not "lwc1" } } */
|
||||
/* { dg-final { scan-assembler-not "swc1" } } */
|
||||
/* { dg-final { scan-assembler-times "sdc1" 2 } } */
|
||||
/* { dg-final { scan-assembler-times "ldc1" 4 } } */
|
||||
/* { dg-final { scan-assembler-not "mtc" } } */
|
||||
/* { dg-final { scan-assembler-not "mfc" } } */
|
||||
/* { dg-final { scan-assembler-not "mthc" } } */
|
||||
/* { dg-final { scan-assembler-not "mfhc" } } */
|
|
@ -0,0 +1,21 @@
|
|||
/* Check that we handle call-clobbered FPRs correctly. */
|
||||
/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
|
||||
/* { dg-options "-mabi=32 -modd-spreg -mfp32 -ffixed-f0 -ffixed-f1 -ffixed-f2 -ffixed-f3 -ffixed-f4 -ffixed-f5 -ffixed-f6 -ffixed-f7 -ffixed-f8 -ffixed-f9 -ffixed-f10 -ffixed-f11 -ffixed-f12 -ffixed-f13 -ffixed-f14 -ffixed-f15 -ffixed-f16 -ffixed-f17 -ffixed-f18 -ffixed-f19 -ffixed-f20 -ffixed-f22 -ffixed-f24 -ffixed-f26 -ffixed-f28 -ffixed-f30" } */
|
||||
|
||||
void bar (void);
|
||||
float a;
|
||||
float
|
||||
foo ()
|
||||
{
|
||||
float b = a + 1.0f;
|
||||
bar();
|
||||
return b;
|
||||
}
|
||||
/* { dg-final { scan-assembler-times "lwc1" 4 } } */
|
||||
/* { dg-final { scan-assembler-times "swc1" 2 } } */
|
||||
/* { dg-final { scan-assembler-not "mtc" } } */
|
||||
/* { dg-final { scan-assembler-not "mfc" } } */
|
||||
/* { dg-final { scan-assembler-not "mthc" } } */
|
||||
/* { dg-final { scan-assembler-not "mfhc" } } */
|
||||
/* { dg-final { scan-assembler-not "sdc1" } } */
|
||||
/* { dg-final { scan-assembler-not "ldc1" } } */
|
|
@ -0,0 +1,23 @@
|
|||
/* Check that we handle call-clobbered FPRs correctly. */
|
||||
/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
|
||||
/* Refer to call-clobbered-4.c to see the expected output from -Os builds. */
|
||||
/* { dg-skip-if "uses callee-saved GPR" { *-*-* } { "-Os" } { "" } } */
|
||||
/* { dg-options "-mabi=32 -modd-spreg -mfpxx -ffixed-f0 -ffixed-f1 -ffixed-f2 -ffixed-f3 -ffixed-f4 -ffixed-f5 -ffixed-f6 -ffixed-f7 -ffixed-f8 -ffixed-f9 -ffixed-f10 -ffixed-f11 -ffixed-f12 -ffixed-f13 -ffixed-f14 -ffixed-f15 -ffixed-f16 -ffixed-f17 -ffixed-f18 -ffixed-f19 -ffixed-f20 -ffixed-f22 -ffixed-f24 -ffixed-f26 -ffixed-f28 -ffixed-f30" } */
|
||||
|
||||
void bar (void);
|
||||
float a;
|
||||
float
|
||||
foo ()
|
||||
{
|
||||
float b = a + 1.0f;
|
||||
bar();
|
||||
return b;
|
||||
}
|
||||
/* { dg-final { scan-assembler-times "lwc1" 5 } } */
|
||||
/* { dg-final { scan-assembler-times "swc1" 3 } } */
|
||||
/* { dg-final { scan-assembler-not "mtc" } } */
|
||||
/* { dg-final { scan-assembler-not "mfc" } } */
|
||||
/* { dg-final { scan-assembler-not "mthc" } } */
|
||||
/* { dg-final { scan-assembler-not "mfhc" } } */
|
||||
/* { dg-final { scan-assembler-not "ldc1" } } */
|
||||
/* { dg-final { scan-assembler-not "sdc1" } } */
|
|
@ -0,0 +1,23 @@
|
|||
/* Check that we handle call-clobbered FPRs correctly.
|
||||
This test differs from call-clobbered-3.c because when optimising for size
|
||||
a callee-saved GPR is used for 'b' to cross the call. */
|
||||
/* { dg-skip-if "code quality test" { *-*-* } { "*" } { "-Os" } } */
|
||||
/* { dg-options "-mabi=32 -modd-spreg -mfpxx -ffixed-f0 -ffixed-f1 -ffixed-f2 -ffixed-f3 -ffixed-f4 -ffixed-f5 -ffixed-f6 -ffixed-f7 -ffixed-f8 -ffixed-f9 -ffixed-f10 -ffixed-f11 -ffixed-f12 -ffixed-f13 -ffixed-f14 -ffixed-f15 -ffixed-f16 -ffixed-f17 -ffixed-f18 -ffixed-f19 -ffixed-f20 -ffixed-f22 -ffixed-f24 -ffixed-f26 -ffixed-f28 -ffixed-f30" } */
|
||||
|
||||
void bar (void);
|
||||
float a;
|
||||
float
|
||||
foo ()
|
||||
{
|
||||
float b = a + 1.0f;
|
||||
bar();
|
||||
return b;
|
||||
}
|
||||
/* { dg-final { scan-assembler-times "lwc1" 4 } } */
|
||||
/* { dg-final { scan-assembler-times "swc1" 2 } } */
|
||||
/* { dg-final { scan-assembler-times "mtc" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "mfc" 1 } } */
|
||||
/* { dg-final { scan-assembler-not "mthc" } } */
|
||||
/* { dg-final { scan-assembler-not "mfhc" } } */
|
||||
/* { dg-final { scan-assembler-not "ldc1" } } */
|
||||
/* { dg-final { scan-assembler-not "sdc1" } } */
|
|
@ -0,0 +1,21 @@
|
|||
/* Check that we handle call-clobbered FPRs correctly. */
|
||||
/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
|
||||
/* { dg-options "-mabi=32 -mfp64 -ffixed-f0 -ffixed-f1 -ffixed-f2 -ffixed-f3 -ffixed-f4 -ffixed-f5 -ffixed-f6 -ffixed-f7 -ffixed-f8 -ffixed-f9 -ffixed-f10 -ffixed-f11 -ffixed-f12 -ffixed-f13 -ffixed-f14 -ffixed-f15 -ffixed-f16 -ffixed-f17 -ffixed-f18 -ffixed-f19 -ffixed-f20 -ffixed-f22 -ffixed-f24 -ffixed-f26 -ffixed-f28 -ffixed-f30" } */
|
||||
|
||||
void bar (void);
|
||||
float a;
|
||||
float
|
||||
foo ()
|
||||
{
|
||||
float b = a + 1.0f;
|
||||
bar();
|
||||
return b;
|
||||
}
|
||||
/* { dg-final { scan-assembler-times "lwc1" 3 } } */
|
||||
/* { dg-final { scan-assembler-times "swc1" 1 } } */
|
||||
/* { dg-final { scan-assembler-not "sdc1" } } */
|
||||
/* { dg-final { scan-assembler-not "ldc1" } } */
|
||||
/* { dg-final { scan-assembler-not "mtc" } } */
|
||||
/* { dg-final { scan-assembler-not "mfc" } } */
|
||||
/* { dg-final { scan-assembler-not "mthc" } } */
|
||||
/* { dg-final { scan-assembler-not "mfhc" } } */
|
|
@ -0,0 +1,32 @@
|
|||
/* Check that we save the correct call-saved GPRs and FPRs. */
|
||||
/* { dg-options "isa>=2 -mabi=32 -mfp32" } */
|
||||
|
||||
void bar (void);
|
||||
|
||||
void
|
||||
foo (int x)
|
||||
{
|
||||
__builtin_unwind_init ();
|
||||
__builtin_eh_return (x, bar);
|
||||
}
|
||||
/* { dg-final { scan-assembler "\\\$16" } } */
|
||||
/* { dg-final { scan-assembler "\\\$17" } } */
|
||||
/* { dg-final { scan-assembler "\\\$18" } } */
|
||||
/* { dg-final { scan-assembler "\\\$19" } } */
|
||||
/* { dg-final { scan-assembler "\\\$20" } } */
|
||||
/* { dg-final { scan-assembler "\\\$21" } } */
|
||||
/* { dg-final { scan-assembler "\\\$22" } } */
|
||||
/* { dg-final { scan-assembler "\\\$23" } } */
|
||||
/* { dg-final { scan-assembler "\\\$(30|fp)" } } */
|
||||
/* { dg-final { scan-assembler "\\\$f20" } } */
|
||||
/* { dg-final { scan-assembler "\\\$f22" } } */
|
||||
/* { dg-final { scan-assembler "\\\$f24" } } */
|
||||
/* { dg-final { scan-assembler "\\\$f26" } } */
|
||||
/* { dg-final { scan-assembler "\\\$f28" } } */
|
||||
/* { dg-final { scan-assembler "\\\$f30" } } */
|
||||
/* { dg-final { scan-assembler-not "\\\$f21" } } */
|
||||
/* { dg-final { scan-assembler-not "\\\$f23" } } */
|
||||
/* { dg-final { scan-assembler-not "\\\$f25" } } */
|
||||
/* { dg-final { scan-assembler-not "\\\$f27" } } */
|
||||
/* { dg-final { scan-assembler-not "\\\$f29" } } */
|
||||
/* { dg-final { scan-assembler-not "\\\$f31" } } */
|
|
@ -0,0 +1,32 @@
|
|||
/* Check that we save the correct call-saved GPRs and FPRs. */
|
||||
/* { dg-options "-mabi=32 -mfpxx" } */
|
||||
|
||||
void bar (void);
|
||||
|
||||
void
|
||||
foo (int x)
|
||||
{
|
||||
__builtin_unwind_init ();
|
||||
__builtin_eh_return (x, bar);
|
||||
}
|
||||
/* { dg-final { scan-assembler "\\\$16" } } */
|
||||
/* { dg-final { scan-assembler "\\\$17" } } */
|
||||
/* { dg-final { scan-assembler "\\\$18" } } */
|
||||
/* { dg-final { scan-assembler "\\\$19" } } */
|
||||
/* { dg-final { scan-assembler "\\\$20" } } */
|
||||
/* { dg-final { scan-assembler "\\\$21" } } */
|
||||
/* { dg-final { scan-assembler "\\\$22" } } */
|
||||
/* { dg-final { scan-assembler "\\\$23" } } */
|
||||
/* { dg-final { scan-assembler "\\\$(30|fp)" } } */
|
||||
/* { dg-final { scan-assembler "\\\$f20" } } */
|
||||
/* { dg-final { scan-assembler "\\\$f22" } } */
|
||||
/* { dg-final { scan-assembler "\\\$f24" } } */
|
||||
/* { dg-final { scan-assembler "\\\$f26" } } */
|
||||
/* { dg-final { scan-assembler "\\\$f28" } } */
|
||||
/* { dg-final { scan-assembler "\\\$f30" } } */
|
||||
/* { dg-final { scan-assembler-not "\\\$f21" } } */
|
||||
/* { dg-final { scan-assembler-not "\\\$f23" } } */
|
||||
/* { dg-final { scan-assembler-not "\\\$f25" } } */
|
||||
/* { dg-final { scan-assembler-not "\\\$f27" } } */
|
||||
/* { dg-final { scan-assembler-not "\\\$f29" } } */
|
||||
/* { dg-final { scan-assembler-not "\\\$f31" } } */
|
|
@ -0,0 +1,32 @@
|
|||
/* Check that we save the correct call-saved GPRs and FPRs. */
|
||||
/* { dg-options "-mabi=32 -mfp64" } */
|
||||
|
||||
void bar (void);
|
||||
|
||||
void
|
||||
foo (int x)
|
||||
{
|
||||
__builtin_unwind_init ();
|
||||
__builtin_eh_return (x, bar);
|
||||
}
|
||||
/* { dg-final { scan-assembler "\\\$16" } } */
|
||||
/* { dg-final { scan-assembler "\\\$17" } } */
|
||||
/* { dg-final { scan-assembler "\\\$18" } } */
|
||||
/* { dg-final { scan-assembler "\\\$19" } } */
|
||||
/* { dg-final { scan-assembler "\\\$20" } } */
|
||||
/* { dg-final { scan-assembler "\\\$21" } } */
|
||||
/* { dg-final { scan-assembler "\\\$22" } } */
|
||||
/* { dg-final { scan-assembler "\\\$23" } } */
|
||||
/* { dg-final { scan-assembler "\\\$(30|fp)" } } */
|
||||
/* { dg-final { scan-assembler "\\\$f20" } } */
|
||||
/* { dg-final { scan-assembler "\\\$f22" } } */
|
||||
/* { dg-final { scan-assembler "\\\$f24" } } */
|
||||
/* { dg-final { scan-assembler "\\\$f26" } } */
|
||||
/* { dg-final { scan-assembler "\\\$f28" } } */
|
||||
/* { dg-final { scan-assembler "\\\$f30" } } */
|
||||
/* { dg-final { scan-assembler-not "\\\$f21" } } */
|
||||
/* { dg-final { scan-assembler-not "\\\$f23" } } */
|
||||
/* { dg-final { scan-assembler-not "\\\$f25" } } */
|
||||
/* { dg-final { scan-assembler-not "\\\$f27" } } */
|
||||
/* { dg-final { scan-assembler-not "\\\$f29" } } */
|
||||
/* { dg-final { scan-assembler-not "\\\$f31" } } */
|
|
@ -235,7 +235,7 @@ set mips_option_groups {
|
|||
endianness "-E(L|B)|-me(l|b)"
|
||||
float "-m(hard|soft)-float"
|
||||
forbid_cpu "forbid_cpu=.*"
|
||||
fp "-mfp(32|64)"
|
||||
fp "-mfp(32|xx|64)"
|
||||
gp "-mgp(32|64)"
|
||||
long "-mlong(32|64)"
|
||||
micromips "-mmicromips|-mno-micromips"
|
||||
|
@ -248,6 +248,10 @@ set mips_option_groups {
|
|||
dump "-fdump-.*"
|
||||
}
|
||||
|
||||
for { set option 0 } { $option < 32 } { incr option } {
|
||||
lappend mips_option_groups "fixed-f$option" "-ffixed-f$option"
|
||||
}
|
||||
|
||||
# Add -mfoo/-mno-foo options to mips_option_groups.
|
||||
foreach option {
|
||||
abicalls
|
||||
|
@ -270,6 +274,7 @@ foreach option {
|
|||
synci
|
||||
relax-pic-calls
|
||||
mcount-ra-address
|
||||
odd-spreg
|
||||
} {
|
||||
lappend mips_option_groups $option "-m(no-|)$option"
|
||||
}
|
||||
|
@ -723,8 +728,12 @@ proc mips-dg-init {} {
|
|||
#if __mips_fpr == 64
|
||||
"-mfp64",
|
||||
#else
|
||||
#if __mips_fpr == 0
|
||||
"-mfpxx",
|
||||
#else
|
||||
"-mfp32",
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __mips64
|
||||
"-mgp64",
|
||||
|
@ -756,6 +765,12 @@ proc mips-dg-init {} {
|
|||
"-mno-paired-single",
|
||||
#endif
|
||||
|
||||
#if _MIPS_SPFPSET == 32
|
||||
"-modd-spreg",
|
||||
#else
|
||||
"-mno-odd-spreg",
|
||||
#endif
|
||||
|
||||
#if __mips_abicalls
|
||||
"-mabicalls",
|
||||
#else
|
||||
|
@ -841,6 +856,8 @@ proc mips-dg-finish {} {
|
|||
# | |
|
||||
# -mfp64 -mfp32
|
||||
# | |
|
||||
# -modd-spreg -mno-odd-spreg
|
||||
# | |
|
||||
# -mabs=2008/-mabs=legacy <no option>
|
||||
# | |
|
||||
# -mhard-float -msoft-float
|
||||
|
@ -930,6 +947,7 @@ proc mips-dg-options { args } {
|
|||
mips_option_dependency options "-mips3d" "-mpaired-single"
|
||||
mips_option_dependency options "-mpaired-single" "-mfp64"
|
||||
mips_option_dependency options "-mfp64" "-mhard-float"
|
||||
mips_option_dependency options "-mfp64" "-modd-spreg"
|
||||
mips_option_dependency options "-mabs=2008" "-mhard-float"
|
||||
mips_option_dependency options "-mabs=legacy" "-mhard-float"
|
||||
mips_option_dependency options "-mrelax-pic-calls" "-mno-plt"
|
||||
|
@ -1046,10 +1064,13 @@ proc mips-dg-options { args } {
|
|||
# We need a MIPS32 or MIPS64 ISA for:
|
||||
#
|
||||
# - paired-single instructions(*)
|
||||
# - odd numbered single precision registers
|
||||
#
|
||||
# (*) Note that we don't support MIPS V at the moment.
|
||||
} elseif { $isa_rev < 1
|
||||
&& [mips_have_test_option_p options "-mpaired-single"] } {
|
||||
&& ([mips_have_test_option_p options "-mpaired-single"]
|
||||
|| ([mips_have_test_option_p options "-modd-spreg"]
|
||||
&& ![mips_have_test_option_p options "-mfp64"]))} {
|
||||
if { $gp_size == 32 } {
|
||||
mips_make_test_option options "-mips32"
|
||||
} else {
|
||||
|
@ -1071,7 +1092,9 @@ proc mips-dg-options { args } {
|
|||
# (*) needed by both -mbranch-likely and -mfix-r10000
|
||||
} elseif { $isa < 2
|
||||
&& ([mips_have_test_option_p options "-mbranch-likely"]
|
||||
|| [mips_have_test_option_p options "-mfix-r10000"]) } {
|
||||
|| [mips_have_test_option_p options "-mfix-r10000"]
|
||||
|| ($gp_size == 32
|
||||
&& [mips_have_test_option_p options "-mfpxx"])) } {
|
||||
mips_make_test_option options "-mips2"
|
||||
# Check whether we need to switch from a 32-bit processor to the
|
||||
# "nearest" 64-bit processor.
|
||||
|
@ -1122,6 +1145,9 @@ proc mips-dg-options { args } {
|
|||
} elseif { [mips_have_test_option_p options "-mlong64"]
|
||||
&& [mips_long32_abi_p $abi] } {
|
||||
set force_abi 1
|
||||
} elseif { [mips_have_test_option_p options "-mfpxx"]
|
||||
&& ![mips_same_option_p $abi "-mabi=32"] } {
|
||||
set force_abi 1
|
||||
} else {
|
||||
set force_abi 0
|
||||
}
|
||||
|
@ -1193,6 +1219,9 @@ proc mips-dg-options { args } {
|
|||
}
|
||||
if { $isa_rev < 1 } {
|
||||
mips_make_test_option options "-mno-paired-single"
|
||||
if { ![mips_have_test_option_p options "-mgp64"] } {
|
||||
mips_make_test_option options "-mno-odd-spreg"
|
||||
}
|
||||
}
|
||||
if { $isa_rev < 2 } {
|
||||
if { $gp_size == 32 } {
|
||||
|
@ -1223,6 +1252,7 @@ proc mips-dg-options { args } {
|
|||
mips_option_dependency options "-mplt" "-mno-shared"
|
||||
mips_option_dependency options "-mno-shared" "-fno-pic"
|
||||
mips_option_dependency options "-mfp32" "-mno-paired-single"
|
||||
mips_option_dependency options "-mfpxx" "-mno-paired-single"
|
||||
mips_option_dependency options "-msoft-float" "-mno-paired-single"
|
||||
mips_option_dependency options "-mno-paired-single" "-mno-mips3d"
|
||||
|
||||
|
@ -1244,7 +1274,9 @@ proc mips-dg-options { args } {
|
|||
foreach group $mips_abi_groups {
|
||||
set old_option [mips_original_option $group]
|
||||
set new_option [mips_option options $group]
|
||||
if { ![mips_same_option_p $old_option $new_option] } {
|
||||
if { ![mips_same_option_p $old_option $new_option]
|
||||
&& ![mips_same_option_p $old_option "-mfpxx"]
|
||||
&& ![mips_same_option_p $new_option "-mfpxx"] } {
|
||||
switch -- [lindex $do_what 0] {
|
||||
link -
|
||||
run {
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
/* Check that we move DFmode values via memory between FP and GP. */
|
||||
/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
|
||||
/* { dg-options "-mabi=32 -mfpxx isa=2" } */
|
||||
|
||||
void bar (void);
|
||||
|
||||
double
|
||||
foo (int x, double a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
/* { dg-final { scan-assembler-not "mthc1" } } */
|
||||
/* { dg-final { scan-assembler-not "mtc1" } } */
|
||||
/* { dg-final { scan-assembler-times "ldc1" 1 } } */
|
|
@ -0,0 +1,14 @@
|
|||
/* Check that we move DFmode values using mthc between FP and GP. */
|
||||
/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
|
||||
/* { dg-options "-mabi=32 -mfpxx isa_rev=2" } */
|
||||
|
||||
void bar (void);
|
||||
|
||||
double
|
||||
foo (int x, double a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
/* { dg-final { scan-assembler "mthc1" } } */
|
||||
/* { dg-final { scan-assembler "mtc1" } } */
|
||||
/* { dg-final { scan-assembler-not "ldc1" } } */
|
|
@ -0,0 +1,13 @@
|
|||
/* Check that we move DFmode values using mtc1 between FP and GP. */
|
||||
/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
|
||||
/* { dg-options "-mabi=32 -mfp32 isa=2" } */
|
||||
|
||||
void bar (void);
|
||||
|
||||
double
|
||||
foo (int x, double a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
/* { dg-final { scan-assembler-times "mtc1" 2 } } */
|
||||
/* { dg-final { scan-assembler-not "ldc1" } } */
|
|
@ -0,0 +1,13 @@
|
|||
/* Check that we enable odd-numbered single precision registers. */
|
||||
/* { dg-options "-mabi=32 -modd-spreg -mhard-float" } */
|
||||
|
||||
#if _MIPS_SPFPSET != 32
|
||||
#error "Incorrect number of single-precision registers reported"
|
||||
#endif
|
||||
|
||||
void
|
||||
foo ()
|
||||
{
|
||||
register float foo asm ("$f1");
|
||||
asm volatile ("" : "=f" (foo));
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/* Check that we disable odd-numbered single precision registers. */
|
||||
/* { dg-skip-if "needs asm output" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */
|
||||
/* { dg-options "-mabi=32 -mno-odd-spreg -mhard-float" } */
|
||||
|
||||
void
|
||||
foo ()
|
||||
{
|
||||
register float foo asm ("$f1"); /* { dg-error "isn't suitable for" } */
|
||||
asm volatile ("" : "=f" (foo));
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/* Check that we disable odd-numbered single precision registers. */
|
||||
/* { dg-skip-if "needs asm output" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */
|
||||
/* { dg-options "-mabi=32 -mfp32 -march=loongson3a -mhard-float" } */
|
||||
|
||||
void
|
||||
foo ()
|
||||
{
|
||||
register float foo asm ("$f1"); /* { dg-error "isn't suitable for" } */
|
||||
asm volatile ("" : "=f" (foo));
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
/* Check that we disable odd-numbered single precision registers and can
|
||||
still generate code. */
|
||||
/* { dg-options "-mabi=32 -mno-odd-spreg -mhard-float" } */
|
||||
|
||||
#if _MIPS_SPFPSET != 16
|
||||
#error "Incorrect number of single-precision registers reported"
|
||||
#endif
|
||||
|
||||
float a;
|
||||
float
|
||||
foo ()
|
||||
{
|
||||
float b = a + 1.0f;
|
||||
return b;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
/* Check that -mno-odd-spreg is not supported with -mabi=64. */
|
||||
/* { dg-options "-mabi=64 -mno-odd-spreg -mhard-float" } */
|
||||
/* { dg-error "unsupported combination" "" { target *-*-* } 0 } */
|
||||
|
||||
float a;
|
||||
float
|
||||
foo ()
|
||||
{
|
||||
float b = a + 1.0f;
|
||||
return b;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/* Check that we disable odd-numbered single precision registers for FPXX. */
|
||||
/* { dg-skip-if "needs asm output" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */
|
||||
/* { dg-options "-mabi=32 -mfpxx -mhard-float" } */
|
||||
|
||||
void
|
||||
foo ()
|
||||
{
|
||||
register float foo asm ("$f1"); /* { dg-error "isn't suitable for" } */
|
||||
asm volatile ("" : "=f" (foo));
|
||||
}
|
|
@ -1,3 +1,9 @@
|
|||
2014-11-12 Matthew Fortune <matthew.fortune@imgtec.com>
|
||||
|
||||
* config/mips/mips16.S: Set .module when supported. Update O32
|
||||
FP64 calling convention and use for FPXX when possible. Add FPXX
|
||||
calling convention fallback case.
|
||||
|
||||
2014-11-06 Bernd Schmidt <bernds@codesourcery.com>
|
||||
|
||||
* config.host: Handle nvptx-*-*.
|
||||
|
|
|
@ -21,6 +21,8 @@ a copy of the GCC Runtime Library Exception along with this program;
|
|||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "auto-host.h"
|
||||
|
||||
#if defined(__mips_micromips) || defined(__mips_soft_float)
|
||||
/* Do nothing because this code is only needed when linking
|
||||
against mips16 hard-float objects. Neither micromips code
|
||||
|
@ -29,6 +31,16 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|||
for those cases. */
|
||||
#else
|
||||
|
||||
#if defined(HAVE_AS_MODULE)
|
||||
#if __mips_fpr == 32
|
||||
.module fp=32
|
||||
#elif __mips_fpr == 0
|
||||
.module fp=xx
|
||||
#elif __mips_fpr == 64
|
||||
.module fp=64
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* This file contains mips16 floating point support functions. These
|
||||
functions are called by mips16 code to handle floating point when
|
||||
-msoft-float is not used. They accept the arguments and return
|
||||
|
@ -152,8 +164,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|||
/* The high 32 bits of $2 correspond to the second word in memory;
|
||||
i.e. the imaginary part. */
|
||||
#define MOVE_SC_RET(D, T) MERGE_GPR##D ($2, $f1, $f0); jr T
|
||||
#elif __mips_fpr == 64
|
||||
#define MOVE_SC_RET(D, T) m##D##c1 $2,$f0; DELAY##D (T, m##D##c1 $3,$f1)
|
||||
#else
|
||||
#define MOVE_SC_RET(D, T) m##D##c1 $2,$f0; DELAY##D (T, m##D##c1 $3,$f2)
|
||||
#endif
|
||||
|
@ -174,16 +184,29 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|||
#define MOVE_DF_BYTE8(D) dm##D##c1 $5,$f13
|
||||
#define MOVE_DF_RET(D, T) DELAY##D (T, dm##D##c1 $2,$f0)
|
||||
#define MOVE_DC_RET(D, T) dm##D##c1 $3,$f1; MOVE_DF_RET (D, T)
|
||||
#elif __mips_fpr == 64 && defined(__MIPSEB__)
|
||||
#elif __mips_fpr != 32 && __mips_isa_rev >= 2 && defined(__MIPSEB__)
|
||||
#define MOVE_DF_BYTE0(D) m##D##c1 $5,$f12; m##D##hc1 $4,$f12
|
||||
#define MOVE_DF_BYTE8(D) m##D##c1 $7,$f14; m##D##hc1 $6,$f14
|
||||
#define MOVE_DF_RET(D, T) m##D##c1 $3,$f0; DELAY##D (T, m##D##hc1 $2,$f0)
|
||||
#define MOVE_DC_RET(D, T) m##D##c1 $5,$f1; m##D##hc1 $4,$f1; MOVE_DF_RET (D, T)
|
||||
#elif __mips_fpr == 64
|
||||
#define MOVE_DC_RET(D, T) m##D##c1 $5,$f2; m##D##hc1 $4,$f2; MOVE_DF_RET (D, T)
|
||||
#elif __mips_fpr != 32 && __mips_isa_rev >= 2
|
||||
#define MOVE_DF_BYTE0(D) m##D##c1 $4,$f12; m##D##hc1 $5,$f12
|
||||
#define MOVE_DF_BYTE8(D) m##D##c1 $6,$f14; m##D##hc1 $7,$f14
|
||||
#define MOVE_DF_RET(D, T) m##D##c1 $2,$f0; DELAY##D (T, m##D##hc1 $3,$f0)
|
||||
#define MOVE_DC_RET(D, T) m##D##c1 $4,$f1; m##D##hc1 $5,$f1; MOVE_DF_RET (D, T)
|
||||
#define MOVE_DC_RET(D, T) m##D##c1 $4,$f2; m##D##hc1 $5,$f2; MOVE_DF_RET (D, T)
|
||||
#elif __mips_fpr == 0
|
||||
#define MOVE_DF_BYTE0t sw $4, 0($29); sw $5, 4($29); ldc1 $f12, 0($29)
|
||||
#define MOVE_DF_BYTE0f sdc1 $f12, 0($29); lw $4, 0($29); lw $5, 4($29)
|
||||
#define MOVE_DF_BYTE0(D) MOVE_DF_BYTE0##D
|
||||
#define MOVE_DF_BYTE8t sw $6, 8($29); sw $7, 12($29); ldc1 $f14, 8($29)
|
||||
#define MOVE_DF_BYTE8f sdc1 $f14, 8($29); lw $6, 8($29); lw $7, 12($29)
|
||||
#define MOVE_DF_BYTE8(D) MOVE_DF_BYTE8##D
|
||||
#define MOVE_DF_RETt(T) sw $2, 0($29); sw $3, 4($29); DELAYt (T, ldc1 $f0, 0($29))
|
||||
#define MOVE_DF_RETf(T) sdc1 $f0, 0($29); lw $2, 0($29); DELAYf (T, lw $3, 4($29))
|
||||
#define MOVE_DF_RET(D, T) MOVE_DF_RET##D(T)
|
||||
#define MOVE_DC_RETt(T) sw $4, 8($29); sw $5, 12($29); ldc1 $f2, 8($29); MOVE_DF_RETt(T)
|
||||
#define MOVE_DC_RETf(T) sdc1 $f2, 8($29); lw $4, 8($29); lw $5, 12($29); MOVE_DF_RETf(T)
|
||||
#define MOVE_DC_RET(D, T) MOVE_DF_RET##D(T)
|
||||
#elif defined(__MIPSEB__)
|
||||
/* FPRs are little-endian. */
|
||||
#define MOVE_DF_BYTE0(D) m##D##c1 $4,$f13; m##D##c1 $5,$f12
|
||||
|
|
Loading…
Reference in New Issue