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> 2010-07-17 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR target/44805 PR target/44805
......
...@@ -6318,19 +6318,28 @@ mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code) ...@@ -6318,19 +6318,28 @@ mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code)
switch (GET_MODE (retval)) switch (GET_MODE (retval))
{ {
case SCmode: case SCmode:
mips_output_32bit_xfer ('f', GP_RETURN + 1, mips_output_32bit_xfer ('f', GP_RETURN + TARGET_BIG_ENDIAN,
FP_REG_FIRST + MAX_FPRS_PER_FMT); TARGET_BIG_ENDIAN
/* Fall though. */ ? FP_REG_FIRST + MAX_FPRS_PER_FMT
case SFmode: : FP_REG_FIRST);
mips_output_32bit_xfer ('f', GP_RETURN, 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) if (GET_MODE (retval) == SCmode && TARGET_64BIT)
{ {
/* On 64-bit targets, complex floats are returned in /* On 64-bit targets, complex floats are returned in
a single GPR, such that "sd" on a suitably-aligned a single GPR, such that "sd" on a suitably-aligned
target would store the value correctly. */ target would store the value correctly. */
fprintf (asm_out_file, "\tdsll\t%s,%s,32\n", 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],
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", fprintf (asm_out_file, "\tor\t%s,%s,%s\n",
reg_names[GP_RETURN], reg_names[GP_RETURN],
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) ...@@ -6338,6 +6347,10 @@ mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code)
} }
break; break;
case SFmode:
mips_output_32bit_xfer ('f', GP_RETURN, FP_REG_FIRST);
break;
case DCmode: case DCmode:
mips_output_64bit_xfer ('f', GP_RETURN + (8 / UNITS_PER_WORD), mips_output_64bit_xfer ('f', GP_RETURN + (8 / UNITS_PER_WORD),
FP_REG_FIRST + MAX_FPRS_PER_FMT); FP_REG_FIRST + MAX_FPRS_PER_FMT);
......
...@@ -61,9 +61,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ...@@ -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. */ and so that its low 32 bits contain LOW_FPR. */
#define MERGE_GPRf(GPR, HIGH_FPR, LOW_FPR) \ #define MERGE_GPRf(GPR, HIGH_FPR, LOW_FPR) \
.set noat; \ .set noat; \
mfc1 GPR, HIGH_FPR; \
mfc1 $1, LOW_FPR; \ mfc1 $1, LOW_FPR; \
mfc1 GPR, HIGH_FPR; \
dsll $1, $1, 32; \
dsll GPR, GPR, 32; \ dsll GPR, GPR, 32; \
dsrl $1, $1, 32; \
or GPR, GPR, $1; \ or GPR, GPR, $1; \
.set at .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> 2010-07-17 Iain Sandoe <iains@gcc.gnu.org>
PR testsuite/44418 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