@@ -474,7 +474,7 @@
/* Define if the assembler understands .module. */
#ifndef USED_FOR_TARGET
-#undef HAVE_AS_MODULE
+#undef HAVE_AS_DOT_MODULE
#endif
@@ -5466,7 +5466,7 @@ mips_function_arg_boundary (machine_mode mode, const_tree type)
static machine_mode
mips_get_reg_raw_mode (int regno)
{
- if (mips_abi == ABI_32 && !TARGET_FLOAT32 && FP_REG_P (regno))
+ if (TARGET_FLOATXX && FP_REG_P (regno))
return DFmode;
return default_get_reg_raw_mode (regno);
}
@@ -5796,19 +5796,24 @@ mips_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
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
- || regno == FP_RETURN + 2
- || (LONG_DOUBLE_TYPE_SIZE == 128
- && FP_RETURN != GP_RETURN
+ || (FP_RETURN != GP_RETURN
&& regno == FP_RETURN + 2))
return true;
- if ((regno == FP_RETURN + 1
- || regno == FP_RETURN + 3)
+ /* 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
- && (mips_abi == ABI_32 && TARGET_FLOAT32)
- && FP_REG_P (regno))
+ && (regno == FP_RETURN + 1
+ || regno == FP_RETURN + 3))
return true;
return false;
@@ -8723,14 +8728,13 @@ mips_dwarf_register_span (rtx reg)
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
+ 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 precisely
- correct 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. */
+ 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
@@ -9047,7 +9051,7 @@ mips_file_start (void)
fprintf (asm_out_file, "\t.nan\t%s\n",
mips_nan == MIPS_IEEE_754_2008 ? "2008" : "legacy");
-#ifdef HAVE_AS_MODULE
+#ifdef HAVE_AS_DOT_MODULE
/* Record the FP ABI. See below for comments. */
if (TARGET_NO_FLOAT)
#ifdef HAVE_AS_GNU_ATTRIBUTE
@@ -9087,7 +9091,7 @@ mips_file_start (void)
attr = 2;
/* 64-bit FP registers on a 32-bit target, -mips32r2 -mfp64.
Reserved attr=4.
- This case used 12 callee save double precision registers
+ 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)
@@ -11888,9 +11892,8 @@ mips_hard_regno_mode_ok_p (unsigned int regno, machine_mode mode)
|| (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 (mips_abi == ABI_32 && TARGET_FLOAT64 && !TARGET_ODD_SPREG
- && size <= 4 && (regno & 1) != 0)
+ 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. */
@@ -12259,7 +12262,7 @@ mips_secondary_memory_needed (enum reg_class class1, enum reg_class class2,
if (((class1 == FP_REGS) != (class2 == FP_REGS))
&& ((TARGET_FLOATXX && !ISA_HAS_MXHC1)
- || (mips_abi == ABI_32 && TARGET_FLOAT64 && !TARGET_ODD_SPREG))
+ || TARGET_O32_FP64A_ABI)
&& GET_MODE_SIZE (mode) >= 8)
return true;
@@ -17281,7 +17284,7 @@ mips_option_override (void)
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. */
+ /* Disable TARGET_ODD_SPREG when using the o32 FPXX ABI. */
if (!ISA_HAS_ODD_SPREG || TARGET_FLOATXX)
target_flags &= ~MASK_ODD_SPREG;
else
@@ -17294,6 +17297,8 @@ mips_option_override (void)
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;
}
@@ -327,6 +327,11 @@ struct mips_cpu_info {
-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
@@ -762,8 +767,8 @@ struct mips_cpu_info {
#define MIPS_32BIT_OPTION_SPEC \
"mips1|mips2|mips32*|mgp32"
-/* A spec condition that matches architectures should be targetted with
- O32 FPXX for compatibility reasons. */
+/* 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"
@@ -792,9 +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 -mfp is specified.
- --with-odd-spreg-32 is ignored if -modd-spreg or -mno-odd-spreg are 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 \
@@ -806,10 +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 ":%{!mfp*:-mfp%(VALUE)}}" }, \
- {"odd_spreg_32", "%{" OPT_ARCH32 ":%{!modd-spreg:%{!mno-odd-spreg:-m%(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)}}" }, \
@@ -1794,11 +1804,11 @@ struct mips_cpu_info {
#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 call saved
- for O32 FPXX as they will be clobbered when run on an FR=1 FPU. */
+/* 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))
+ && FP_REG_P (REGNO) && ((REGNO) & 1))
#define MODES_TIEABLE_P mips_modes_tieable_p
@@ -2133,19 +2143,16 @@ enum reg_class
#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \
mips_secondary_reload_class (CLASS, MODE, X, false)
-/* When targetting the O32 FPXX ABI then all doubleword or greater moves
- to/from FP registers must be performed by FR-mode-aware instructions.
- This can be achieved using mfhc1/mthc1 when these instructions are
+/* 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 then all odd-numbered doubleword or greater
- moves to/from FP registers must move via memory as it is not permitted
- to access the lower-half of these registers with mtc1/mfc1 since that
- constitutes a single-precision access (which is forbidden). This is
- implemented by requiring all double-word moves to move via memory
- as this check is register class based and not register based.
- Splitting the FP_REGS into even and odd classes would allow the
- precise restriction to be represented but this would have a
- significant effect on other areas of the backend. */
+ 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))
@@ -433,17 +433,13 @@ (define_attr "compression" "none,all,micromips"
(const_string "none"))
(define_attr "enabled" "no,yes"
- (cond [;; The O32 FPXX and FP64A ABI extensions prohibit direct moves between
+ (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)
- || (mips_abi == ABI_32
- && TARGET_FLOAT64 && !TARGET_ODD_SPREG)")
+ || TARGET_O32_FP64A_ABI")
(eq_attr "dword_mode" "yes"))
(const_string "no")
-
- ;; The micromips compressed instruction alternatives should only be
- ;; considered when targetting micromips.
(and (eq_attr "compression" "micromips")
(match_test "!TARGET_MICROMIPS"))
(const_string "no")]
@@ -199,7 +199,7 @@ Use 32-bit floating-point registers
mfpxx
Target Report RejectNegative Mask(FLOATXX)
-Follow the O32 FPXX ABI
+Conform to the o32 FPXX ABI
mfp64
Target Report RejectNegative Mask(FLOAT64)
@@ -34,8 +34,10 @@ 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 option is specified, infer one from the ABI/ISA level. */\
- "%{!mfp*: %{mabi=32: %{" MIPS_FPXX_OPTION_SPEC ": -mfpxx}}}", \
+ /* 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. */ \
@@ -39,8 +39,10 @@ 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 option is specified, infer one from the ABI/ISA level. */\
- "%{!mfp*: %{mabi=32: %{" MIPS_FPXX_OPTION_SPEC ": -mfpxx}}}", \
+ /* 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 \
@@ -26118,10 +26118,10 @@ 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_module+set}" = set; then :
+if test "${gcc_cv_as_mips_dot_module+set}" = set; then :
$as_echo_n "(cached) " >&6
else
- gcc_cv_as_mips_module=no
+ 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'
@@ -26131,7 +26131,7 @@ else
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; }
then
- gcc_cv_as_mips_module=yes
+ gcc_cv_as_mips_dot_module=yes
else
echo "configure: failed program was" >&5
cat conftest.s >&5
@@ -26139,16 +26139,16 @@ else
rm -f conftest.o conftest.s
fi
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_mips_module" >&5
-$as_echo "$gcc_cv_as_mips_module" >&6; }
-if test $gcc_cv_as_mips_module = yes; then
+{ $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_MODULE 1" >>confdefs.h
+$as_echo "#define HAVE_AS_DOT_MODULE 1" >>confdefs.h
fi
- if test x$gcc_cv_as_mips_module = xno \
- && test x$with_fp != x; then
- as_fn_error "Requesting --with-fp= requires assembler support for .module." "$LINENO" 5
+ 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
@@ -4238,14 +4238,14 @@ LCF0:
[Define if your assembler supports .gnu_attribute.])])
gcc_GAS_CHECK_FEATURE([.module support],
- gcc_cv_as_mips_module,,,
+ gcc_cv_as_mips_dot_module,,,
[.module fp=32],,
- [AC_DEFINE(HAVE_AS_MODULE, 1,
- [Define if yout assembler supports .module.])])
- if test x$gcc_cv_as_mips_module = xno \
- && test x$with_fp != x; then
+ [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= requires assembler support for .module.])
+ [Requesting --with-fp-32= requires assembler support for .module.])
fi
gcc_GAS_CHECK_FEATURE([.micromips support],
@@ -786,7 +786,7 @@ 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 mfpxx -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
@@ -17717,12 +17717,12 @@ floating-point values are returned in @samp{$f0} only, not a
remains the same in that the even-numbered double-precision registers
are saved.
-A further two variants of the o32 ABI are also supported to enable
+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
-whether run using 32-bit or 64-bit registers. The code can also
-interlink with either FP32 or FP64, but not both simulataneously.
+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
@@ -17818,8 +17818,7 @@ Assume that floating-point registers are 64 bits wide.
@item -mfpxx
@opindex mfpxx
-Do not assume that floating-point registers are specifically 32 bits or
-64 bits wide.
+Do not assume the width of floating-point registers.
@item -mhard-float
@opindex mhard-float
@@ -17857,9 +17856,9 @@ operations. This is the default.
@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 specific processors that are
-known to support these registers, however the o32 FPXX extension sets
-@code{-mno-odd-spreg} by default.
+for the o32 ABI. This is the default for processors that are known to
+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
@@ -1,6 +1,6 @@
/* Check that we disable odd-numbered single precision registers. */
/* { dg-skip-if "needs asm output" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */
-/* { dg-options "-mabi=32 -march=loongson3a -mhard-float" } */
+/* { dg-options "-mabi=32 -mfp32 -march=loongson3a -mhard-float" } */
void
foo ()