===================================================================
@@ -6318,19 +6318,28 @@ mips16_build_call_stub (rtx retval, rtx
switch (GET_MODE (retval))
{
case SCmode:
- mips_output_32bit_xfer ('f', GP_RETURN + 1,
- FP_REG_FIRST + MAX_FPRS_PER_FMT);
- /* Fall though. */
- case SFmode:
- mips_output_32bit_xfer ('f', GP_RETURN, FP_REG_FIRST);
+ mips_output_32bit_xfer ('f', GP_RETURN + TARGET_BIG_ENDIAN,
+ TARGET_BIG_ENDIAN
+ ? FP_REG_FIRST + MAX_FPRS_PER_FMT
+ : 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);
if (GET_MODE (retval) == SCmode && TARGET_64BIT)
{
/* On 64-bit targets, complex floats are returned in
a single GPR, such that "sd" on a suitably-aligned
target would store the value correctly. */
fprintf (asm_out_file, "\tdsll\t%s,%s,32\n",
+ reg_names[GP_RETURN + TARGET_BIG_ENDIAN],
+ reg_names[GP_RETURN + TARGET_BIG_ENDIAN]);
+ fprintf (asm_out_file, "\tdsll\t%s,%s,32\n",
reg_names[GP_RETURN + TARGET_LITTLE_ENDIAN],
reg_names[GP_RETURN + TARGET_LITTLE_ENDIAN]);
+ fprintf (asm_out_file, "\tdsrl\t%s,%s,32\n",
+ reg_names[GP_RETURN + TARGET_BIG_ENDIAN],
+ reg_names[GP_RETURN + TARGET_BIG_ENDIAN]);
fprintf (asm_out_file, "\tor\t%s,%s,%s\n",
reg_names[GP_RETURN],
reg_names[GP_RETURN],
@@ -6338,6 +6347,10 @@ mips16_build_call_stub (rtx retval, rtx
}
break;
+ case SFmode:
+ mips_output_32bit_xfer ('f', GP_RETURN, FP_REG_FIRST);
+ break;
+
case DCmode:
mips_output_64bit_xfer ('f', GP_RETURN + (8 / UNITS_PER_WORD),
FP_REG_FIRST + MAX_FPRS_PER_FMT);
===================================================================
@@ -61,9 +61,11 @@ see the files COPYING3 and COPYING.RUNTI
and so that its low 32 bits contain LOW_FPR. */
#define MERGE_GPRf(GPR, HIGH_FPR, LOW_FPR) \
.set noat; \
- mfc1 GPR, HIGH_FPR; \
mfc1 $1, LOW_FPR; \
+ mfc1 GPR, HIGH_FPR; \
+ dsll $1, $1, 32; \
dsll GPR, GPR, 32; \
+ dsrl $1, $1, 32; \
or GPR, GPR, $1; \
.set at
===================================================================
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+/* { dg-options "(-mips16)" } */
+
+extern void abort (void);
+
+__complex float f = { -1.0 + -1.0i };
+__complex float __attribute__((nomips16)) foo (void) { return f; }
+__complex float (*volatile foop) (void) = foo;
+__complex float __attribute__((mips16, noinline)) bar (void) { return foop (); }
+
+int
+main (void)
+{
+ if (bar () != f)
+ abort ();
+ return 0;
+}