OSDN Git Service

gcc/
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 Oct 2007 08:30:31 +0000 (08:30 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 Oct 2007 08:30:31 +0000 (08:30 +0000)
* config/mips/mips.c (mips_output_32bit_xfer): New function.
(mips_output_64bit_xfer): Likewise.
(mips16_fp_args): Rename to...
(mips_output_args_xfer): ...this and replace the FROM_FP_P argument
with a DIRECTION argument.  Use mips_output_32bit_xfer and
mips_output_64bit_xfer.
(build_mips16_function_stub): Update accordingly.
(mips16_fpret_double): Delete.
(build_mips16_call_stub): Update after above changes.
Use mips_output_32bit_xfer.  Use mips_output_64bit_xfer instead
of mips16_fpret_double.  Use GP_REG_RETURN.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@129475 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/mips/mips.c

index a113b56..de27aee 100644 (file)
@@ -1,5 +1,19 @@
 2007-10-19  Richard Sandiford  <rsandifo@nildram.co.uk>
 
+       * config/mips/mips.c (mips_output_32bit_xfer): New function.
+       (mips_output_64bit_xfer): Likewise.
+       (mips16_fp_args): Rename to...
+       (mips_output_args_xfer): ...this and replace the FROM_FP_P argument
+       with a DIRECTION argument.  Use mips_output_32bit_xfer and
+       mips_output_64bit_xfer.
+       (build_mips16_function_stub): Update accordingly.
+       (mips16_fpret_double): Delete.
+       (build_mips16_call_stub): Update after above changes.
+       Use mips_output_32bit_xfer.  Use mips_output_64bit_xfer instead
+       of mips16_fpret_double.  Use GP_REG_RETURN.
+
+2007-10-19  Richard Sandiford  <rsandifo@nildram.co.uk>
+
        * config/mips/mips.c (mips16_fp_args): Remove the FILE argument and
        use asm_out_file instead.
        (build_mips16_function_stub): Likewise.
index 23a318a..21abe73 100644 (file)
@@ -5067,28 +5067,57 @@ mips16_call_stub_mode_suffix (enum machine_mode mode)
     gcc_unreachable ();
 }
 
-/* Write out code to move floating point arguments in or out of
+/* Write instructions to move a 32-bit value between general register
+   GPREG and floating-point register FPREG.  DIRECTION is 't' to move
+   from GPREG to FPREG and 'f' to move in the opposite direction.  */
+
+static void
+mips_output_32bit_xfer (char direction, unsigned int gpreg, unsigned int fpreg)
+{
+  fprintf (asm_out_file, "\tm%cc1\t%s,%s\n", direction,
+          reg_names[gpreg], reg_names[fpreg]);
+}
+
+/* Likewise for 64-bit values.  */
+
+static void
+mips_output_64bit_xfer (char direction, unsigned int gpreg, unsigned int fpreg)
+{
+  if (TARGET_64BIT)
+    fprintf (asm_out_file, "\tdm%cc1\t%s,%s\n", direction,
+            reg_names[gpreg], reg_names[fpreg]);
+  else if (TARGET_FLOAT64)
+    {
+      fprintf (asm_out_file, "\tm%cc1\t%s,%s\n", direction,
+              reg_names[gpreg + TARGET_BIG_ENDIAN], reg_names[fpreg]);
+      fprintf (asm_out_file, "\tm%chc1\t%s,%s\n", direction,
+              reg_names[gpreg + TARGET_LITTLE_ENDIAN], reg_names[fpreg]);
+    }
+  else
+    {
+      /* Move the least-significant word.  */
+      fprintf (asm_out_file, "\tm%cc1\t%s,%s\n", direction,
+              reg_names[gpreg + TARGET_BIG_ENDIAN], reg_names[fpreg]);
+      /* ...then the most significant word.  */
+      fprintf (asm_out_file, "\tm%cc1\t%s,%s\n", direction,
+              reg_names[gpreg + TARGET_LITTLE_ENDIAN], reg_names[fpreg + 1]);
+    }
+}
+
+/* Write out code to move floating-point arguments into or out of
    general registers.  FP_CODE is the code describing which arguments
-   are present (see the comment at the definition of CUMULATIVE_ARGS in
-   mips.h).  FROM_FP_P is nonzero if we are copying from the floating
-   point registers.  */
+   are present (see the comment above the definition of CUMULATIVE_ARGS
+   in mips.h).  DIRECTION is as for mips_output_32bit_xfer.  */
 
 static void
-mips16_fp_args (int fp_code, int from_fp_p)
+mips_output_args_xfer (int fp_code, char direction)
 {
-  const char *s;
-  int gparg, fparg;
-  unsigned int f;
+  unsigned int gparg, fparg, f;
   CUMULATIVE_ARGS cum;
 
   /* This code only works for the original 32-bit ABI and the O64 ABI.  */
   gcc_assert (TARGET_OLDABI);
 
-  if (from_fp_p)
-    s = "mfc1";
-  else
-    s = "mtc1";
-
   init_cumulative_args (&cum, NULL, NULL);
 
   for (f = (unsigned int) fp_code; f != 0; f >>= 2)
@@ -5108,28 +5137,9 @@ mips16_fp_args (int fp_code, int from_fp_p)
       fparg = mips_arg_regno (&info, true);
 
       if (mode == SFmode)
-       fprintf (asm_out_file, "\t%s\t%s,%s\n", s,
-                reg_names[gparg], reg_names[fparg]);
-      else if (TARGET_64BIT)
-       fprintf (asm_out_file, "\td%s\t%s,%s\n", s,
-                reg_names[gparg], reg_names[fparg]);
-      else if (ISA_HAS_MXHC1)
-       /* -mips32r2 -mfp64 */
-       fprintf (asm_out_file, "\t%s\t%s,%s\n\t%s\t%s,%s\n",
-                s,
-                reg_names[gparg + (WORDS_BIG_ENDIAN ? 1 : 0)],
-                reg_names[fparg],
-                from_fp_p ? "mfhc1" : "mthc1",
-                reg_names[gparg + (WORDS_BIG_ENDIAN ? 0 : 1)],
-                reg_names[fparg]);
-      else if (TARGET_BIG_ENDIAN)
-       fprintf (asm_out_file, "\t%s\t%s,%s\n\t%s\t%s,%s\n", s,
-                reg_names[gparg], reg_names[fparg + 1], s,
-                reg_names[gparg + 1], reg_names[fparg]);
+       mips_output_32bit_xfer (direction, gparg, fparg);
       else
-       fprintf (asm_out_file, "\t%s\t%s,%s\n\t%s\t%s,%s\n", s,
-                reg_names[gparg], reg_names[fparg], s,
-                reg_names[gparg + 1], reg_names[fparg + 1]);
+       mips_output_64bit_xfer (direction, gparg, fparg);
 
       function_arg_advance (&cum, mode, NULL, true);
     }
@@ -5193,7 +5203,7 @@ build_mips16_function_stub (void)
   /* We don't want the assembler to insert any nops here.  */
   fprintf (asm_out_file, "\t.set\tnoreorder\n");
 
-  mips16_fp_args (current_function_args_info.fp_code, 1);
+  mips_output_args_xfer (current_function_args_info.fp_code, 'f');
 
   fprintf (asm_out_file, "\t.set\tnoat\n");
   fprintf (asm_out_file, "\tla\t%s,", reg_names[GP_REG_FIRST + 1]);
@@ -5221,47 +5231,6 @@ build_mips16_function_stub (void)
   switch_to_section (function_section (current_function_decl));
 }
 
-/* Emit code to return a double value from a mips16 stub.  GPREG is the
-   first GP reg to use, FPREG is the first FP reg to use.  */
-
-static void
-mips16_fpret_double (int gpreg, int fpreg)
-{
-  if (TARGET_64BIT)
-    fprintf (asm_out_file, "\tdmfc1\t%s,%s\n",
-            reg_names[gpreg], reg_names[fpreg]);
-  else if (TARGET_FLOAT64)
-    {
-      fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
-              reg_names[gpreg + WORDS_BIG_ENDIAN],
-              reg_names[fpreg]);
-      fprintf (asm_out_file, "\tmfhc1\t%s,%s\n",
-              reg_names[gpreg + !WORDS_BIG_ENDIAN],
-              reg_names[fpreg]);
-    }
-  else
-    {
-      if (TARGET_BIG_ENDIAN)
-       {
-         fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
-                  reg_names[gpreg + 0],
-                  reg_names[fpreg + 1]);
-         fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
-                  reg_names[gpreg + 1],
-                  reg_names[fpreg + 0]);
-       }
-      else
-       {
-         fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
-                  reg_names[gpreg + 0],
-                  reg_names[fpreg + 0]);
-         fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
-                  reg_names[gpreg + 1],
-                  reg_names[fpreg + 1]);
-       }
-    }
-}
-
 /* Build a call stub for a mips16 call.  A stub is needed if we are
    passing any floating point values which should go into the floating
    point registers.  If we are, and the call turns out to be to a
@@ -5452,7 +5421,7 @@ build_mips16_call_stub (rtx retval, rtx fn, rtx arg_size, int fp_code)
       /* We don't want the assembler to insert any nops here.  */
       fprintf (asm_out_file, "\t.set\tnoreorder\n");
 
-      mips16_fp_args (fp_code, 0);
+      mips_output_args_xfer (fp_code, 't');
 
       if (! fpret)
        {
@@ -5478,36 +5447,33 @@ build_mips16_call_stub (rtx retval, rtx fn, rtx arg_size, int fp_code)
          switch (GET_MODE (retval))
            {
            case SCmode:
-             fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
-                      reg_names[GP_REG_FIRST + 3],
-                      reg_names[FP_REG_FIRST + MAX_FPRS_PER_FMT]);
+             mips_output_32bit_xfer ('f', GP_RETURN + 1,
+                                     FP_REG_FIRST + MAX_FPRS_PER_FMT);
              /* Fall though.  */
            case SFmode:
-             fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
-                      reg_names[GP_REG_FIRST + 2],
-                      reg_names[FP_REG_FIRST + 0]);
+             mips_output_32bit_xfer ('f', GP_RETURN, 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_REG_FIRST + 2 + TARGET_LITTLE_ENDIAN],
-                          reg_names[GP_REG_FIRST + 2 + TARGET_LITTLE_ENDIAN]);
+                          reg_names[GP_RETURN + TARGET_LITTLE_ENDIAN],
+                          reg_names[GP_RETURN + TARGET_LITTLE_ENDIAN]);
                  fprintf (asm_out_file, "\tor\t%s,%s,%s\n",
-                          reg_names[GP_REG_FIRST + 2],
-                          reg_names[GP_REG_FIRST + 2],
-                          reg_names[GP_REG_FIRST + 3]);
+                          reg_names[GP_RETURN],
+                          reg_names[GP_RETURN],
+                          reg_names[GP_RETURN + 1]);
                }
              break;
 
            case DCmode:
-             mips16_fpret_double (GP_REG_FIRST + 2 + (8 / UNITS_PER_WORD),
-                                  FP_REG_FIRST + MAX_FPRS_PER_FMT);
+             mips_output_64bit_xfer ('f', GP_RETURN + (8 / UNITS_PER_WORD),
+                                     FP_REG_FIRST + MAX_FPRS_PER_FMT);
              /* Fall though.  */
            case DFmode:
            case V2SFmode:
-             mips16_fpret_double (GP_REG_FIRST + 2, FP_REG_FIRST + 0);
+             mips_output_64bit_xfer ('f', GP_RETURN, FP_REG_FIRST);
              break;
 
            default: