Commit 93f63c68 by Richard Sandiford Committed by Richard Sandiford

mips.c (mips16_build_call_stub): Zero-extend the low half of a single-register…

mips.c (mips16_build_call_stub): Zero-extend the low half of a single-register SCmode return value before ORing...

gcc/
	* config/mips/mips.c (mips16_build_call_stub): Zero-extend the
	low half of a single-register SCmode return value before ORing
	it with the high half.
	* config/mips/mips16.S (MERGE_GPRf): Likewise.

gcc/testsuite/
	* gcc.target/mips/mips16-attributes-4.c: New test.

From-SVN: r162283
parent 0e789461
2010-07-18 Richard Sandiford <rdsandiford@googlemail.com>
* config/mips/mips.c (mips16_build_call_stub): Zero-extend the
low half of a single-register SCmode return value before ORing
it with the high half.
* config/mips/mips16.S (MERGE_GPRf): Likewise.
2010-07-17 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR target/44805
......
......@@ -6318,19 +6318,28 @@ mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code)
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 *fn_ptr, rtx args_size, int fp_code)
}
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.RUNTIME respectively. If not, see
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
......
2010-07-18 Richard Sandiford <rdsandiford@googlemail.com>
* gcc.target/mips/mips16-attributes-4.c: New test.
2010-07-17 Iain Sandoe <iains@gcc.gnu.org>
PR testsuite/44418
......
/* { 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment