OSDN Git Service

gcc/
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 18 Jul 2010 12:14:26 +0000 (12:14 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 18 Jul 2010 12:14:26 +0000 (12:14 +0000)
* 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
gcc/config/mips/mips.c
gcc/config/mips/mips16.S
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/mips/mips16-attributes-4.c [new file with mode: 0644]

index ddfdc91..a789ecd 100644 (file)
@@ -1,3 +1,10 @@
+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
index 3d4ffae..c216297 100644 (file)
@@ -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);
index bab7b79..b9550ad 100644 (file)
@@ -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
 
index 3be3964..b09492d 100644 (file)
@@ -1,3 +1,7 @@
+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
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 (file)
index 0000000..de7cb43
--- /dev/null
@@ -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;
+}