This patch like the previous 2 pages combines the decimal and binary floating
point moves, this time for 128-bit floating point.

In doing this patch, I discovered that I left out the code in the previous
patch to enable the wg constraint to enable -mcpu=power6x to utilize the direct
move instructions.  So, I added the code in this patch, and also created a test
to make sure that direct moves are generated in the future.

I also added the reload helper for DDmode to rs6000_vector_reload that was
missed in the last patch.  This was harmless, since that is only used with an
undocumented debug switch.  Hopefully sometime in the future, I will scalar
floating point to be able to be loaded in the upper 32 VSX registers that are
overlaid over the Altivec registers.

Like the previous 2 patches, I've bootstrapped this, and ran make check with no
regressions.  Is it ok to apply when GCC 4.9 opens up?

I have one more patch in the insn combination to post, combining movdi on
systems with normal floating point and with the power6 direct move
instructions.

[gcc]
2013-01-30  Michael Meissner  <meiss...@linux.vnet.ibm.com>

        * config/rs6000/rs6000.c (rs6000_debug_reg_global): Print out wg
        constraint if -mdebug=reg.
        (rs6000_initi_hard_regno_mode_ok): Enable wg constraint if
        -mfpgpr.  Enable using dd reload support if needed.

        * config/rs6000/dfp.md (movtd): Delete, combine with 128-bit
        binary and decimal floating point moves in rs6000.md.
        (movtd_internal): Likewise.

        * config/rs6000/rs6000.md (FMOVE128): Combine 128-bit binary and
        decimal floating point moves.
        (movtf): Likewise.
        (movtf_internal): Likewise.
        (mov<mode>_internal, TDmode/TFmode): Likewise.
        (movtf_softfloat): Likewise.
        (mov<mode>_softfloat, TDmode/TFmode): Likewise.

[gcc/testsuite]
2013-01-30  Michael Meissner  <meiss...@linux.vnet.ibm.com>

        * gcc.target/powerpc/mmfpgpr.c: New test.

-- 
Michael Meissner, IBM
5 Technology Place Drive, M/S 2757, Westford, MA 01886-3141, USA
meiss...@linux.vnet.ibm.com     fax +1 (978) 399-6899
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 195586)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -1737,6 +1737,7 @@ rs6000_debug_reg_global (void)
           "wa reg_class = %s\n"
           "wd reg_class = %s\n"
           "wf reg_class = %s\n"
+          "wg reg_class = %s\n"
           "wl reg_class = %s\n"
           "ws reg_class = %s\n"
           "wx reg_class = %s\n"
@@ -1748,6 +1749,7 @@ rs6000_debug_reg_global (void)
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
+          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wg]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wl]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wx]],
@@ -2120,6 +2122,9 @@ rs6000_init_hard_regno_mode_ok (bool glo
   if (TARGET_ALTIVEC)
     rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
 
+  if (TARGET_MFPGPR)
+    rs6000_constraints[RS6000_CONSTRAINT_wg] = FLOAT_REGS;
+
   if (TARGET_LFIWAX)
     rs6000_constraints[RS6000_CONSTRAINT_wl] = FLOAT_REGS;
 
@@ -2150,6 +2155,8 @@ rs6000_init_hard_regno_mode_ok (bool glo
            {
              rs6000_vector_reload[DFmode][0]  = CODE_FOR_reload_df_di_store;
              rs6000_vector_reload[DFmode][1]  = CODE_FOR_reload_df_di_load;
+             rs6000_vector_reload[DDmode][0]  = CODE_FOR_reload_dd_di_store;
+             rs6000_vector_reload[DDmode][1]  = CODE_FOR_reload_dd_di_load;
            }
        }
       else
@@ -2170,6 +2177,8 @@ rs6000_init_hard_regno_mode_ok (bool glo
            {
              rs6000_vector_reload[DFmode][0]  = CODE_FOR_reload_df_si_store;
              rs6000_vector_reload[DFmode][1]  = CODE_FOR_reload_df_si_load;
+             rs6000_vector_reload[DDmode][0]  = CODE_FOR_reload_dd_si_store;
+             rs6000_vector_reload[DDmode][1]  = CODE_FOR_reload_dd_si_load;
            }
        }
     }
Index: gcc/config/rs6000/dfp.md
===================================================================
--- gcc/config/rs6000/dfp.md    (revision 195590)
+++ gcc/config/rs6000/dfp.md    (working copy)
@@ -144,27 +144,6 @@ (define_insn "*nabstd2_fpr"
   "fnabs %0,%1"
   [(set_attr "type" "fp")])
 
-(define_expand "movtd"
-  [(set (match_operand:TD 0 "general_operand" "")
-       (match_operand:TD 1 "any_operand" ""))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS"
-  "{ rs6000_emit_move (operands[0], operands[1], TDmode); DONE; }")
-
-; It's important to list the Y->r and r->Y moves before r->r because
-; otherwise reload, given m->r, will try to pick r->r and reload it,
-; which doesn't make progress.
-(define_insn_and_split "*movtd_internal"
-  [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
-       (match_operand:TD 1 "input_operand"         "d,m,d,r,YGHF,r"))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS
-   && (gpc_reg_operand (operands[0], TDmode)
-       || gpc_reg_operand (operands[1], TDmode))"
-  "#"
-  "&& reload_completed"
-  [(pc)]
-{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
-  [(set_attr "length" "8,8,8,20,20,16")])
-
 ;; Hardware support for decimal floating point operations.
 
 (define_insn "extendddtd2"
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md (revision 195590)
+++ gcc/config/rs6000/rs6000.md (working copy)
@@ -257,6 +257,8 @@ (define_mode_iterator FMA_F [
 (define_mode_iterator FMOVE32 [SF SD])
 (define_mode_iterator FMOVE64 [DF DD])
 (define_mode_iterator FMOVE64X [DI DF DD])
+(define_mode_iterator FMOVE128 [(TF "!TARGET_IEEEQUAD && 
TARGET_LONG_DOUBLE_128")
+                               (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
 
 ; Whether a floating point move is ok, don't allow SD without hardware FP
 (define_mode_attr fmove_ok [(SF "")
@@ -8148,35 +8150,33 @@ (define_insn "*mov<mode>_softfloat64"
   [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
 
-(define_expand "movtf"
-  [(set (match_operand:TF 0 "general_operand" "")
-       (match_operand:TF 1 "any_operand" ""))]
-  "!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128"
-  "{ rs6000_emit_move (operands[0], operands[1], TFmode); DONE; }")
+(define_expand "mov<mode>"
+  [(set (match_operand:FMOVE128 0 "general_operand" "")
+       (match_operand:FMOVE128 1 "any_operand" ""))]
+  ""
+  "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
 
 ;; It's important to list Y->r and r->Y before r->r because otherwise
 ;; reload, given m->r, will try to pick r->r and reload it, which
 ;; doesn't make progress.
-(define_insn_and_split "*movtf_internal"
-  [(set (match_operand:TF 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
-       (match_operand:TF 1 "input_operand" "d,m,d,r,YGHF,r"))]
-  "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
-   && (gpc_reg_operand (operands[0], TFmode)
-       || gpc_reg_operand (operands[1], TFmode))"
+(define_insn_and_split "*mov<mode>_internal"
+  [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
+       (match_operand:FMOVE128 1 "input_operand" "d,m,d,r,YGHF,r"))]
+  "TARGET_HARD_FLOAT && TARGET_FPRS
+   && (gpc_reg_operand (operands[0], <MODE>mode)
+       || gpc_reg_operand (operands[1], <MODE>mode))"
   "#"
   "&& reload_completed"
   [(pc)]
 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
   [(set_attr "length" "8,8,8,20,20,16")])
 
-(define_insn_and_split "*movtf_softfloat"
-  [(set (match_operand:TF 0 "rs6000_nonimmediate_operand" "=Y,r,r")
-       (match_operand:TF 1 "input_operand"         "r,YGHF,r"))]
-  "!TARGET_IEEEQUAD
-   && (TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_LONG_DOUBLE_128
-   && (gpc_reg_operand (operands[0], TFmode)
-       || gpc_reg_operand (operands[1], TFmode))"
+(define_insn_and_split "*mov<mode>_softfloat"
+  [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
+       (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
+  "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
+   && (gpc_reg_operand (operands[0], <MODE>mode)
+       || gpc_reg_operand (operands[1], <MODE>mode))"
   "#"
   "&& reload_completed"
   [(pc)]
Index: gcc/testsuite/gcc.target/powerpc/mmfpgpr.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/mmfpgpr.c  (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/mmfpgpr.c  (revision 0)
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-O2 -mcpu=power6x -mmfpgpr" } */
+/* { dg-final { scan-assembler "mffgpr" } } */
+/* { dg-final { scan-assembler "mftgpr" } } */
+
+/* Test that we generate the instructions to move between the GPR and FPR
+   registers under power6x.  */
+
+extern long return_long (void);
+extern double return_double (void);
+
+double return_double2 (void)
+{
+  return (double) return_long ();
+}
+
+long return_long2 (void)
+{
+  return (long) return_double ();
+}

Reply via email to