From db6eecb09fcb627bea59217bd7bb7314011461a7 Mon Sep 17 00:00:00 2001 From: rsandifo Date: Sun, 18 Jul 2010 12:14:26 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@162283 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 +++++++ gcc/config/mips/mips.c | 23 +++++++++++++++++----- gcc/config/mips/mips16.S | 4 +++- gcc/testsuite/ChangeLog | 4 ++++ .../gcc.target/mips/mips16-attributes-4.c | 17 ++++++++++++++++ 5 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.target/mips/mips16-attributes-4.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ddfdc91..a789ecd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2010-07-18 Richard Sandiford + + * 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 PR target/44805 diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 3d4ffae..c216297 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -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); diff --git a/gcc/config/mips/mips16.S b/gcc/config/mips/mips16.S index bab7b79..b9550ad 100644 --- a/gcc/config/mips/mips16.S +++ b/gcc/config/mips/mips16.S @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3be3964..b09492d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-07-18 Richard Sandiford + + * gcc.target/mips/mips16-attributes-4.c: New test. + 2010-07-17 Iain Sandoe PR testsuite/44418 diff --git a/gcc/testsuite/gcc.target/mips/mips16-attributes-4.c b/gcc/testsuite/gcc.target/mips/mips16-attributes-4.c new file mode 100644 index 0000000..de7cb43 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/mips16-attributes-4.c @@ -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; +} -- 2.7.4