OSDN Git Service

Allows a single-precision FP register to contain a SImode value.
authoreager <eager@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 15 Apr 2009 16:46:14 +0000 (16:46 +0000)
committereager <eager@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 15 Apr 2009 16:46:14 +0000 (16:46 +0000)
This is only active when TARGET_SINGLE_FPU is true (e.g., --target=powerpc-xilinx-eabi).

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

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md

index 7df2ef9..47f1ce6 100644 (file)
@@ -1,3 +1,11 @@
+2009-04-15  Michael Eager <eager@eagercon.com>
+
+       * config/rs6000/rs6000.c: rs6000_function_value: set function return
+       reg for single-precision FPU
+       * config/rs6000/rs6000.md: (movsi_internal1): only for !TARGET_SINGLE_FPU
+       (movsi_internal1_single): New: add pattern to move SI values to/from
+       single-precision FP regs.
+
 2009-04-15  Richard Guenther  <rguenther@suse.de>
 
        * omp-low.c (lower_rec_input_clauses): Build correct address
index 6500cc7..b99f371 100644 (file)
@@ -22600,7 +22600,8 @@ rs6000_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED)
   if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
     /* _Decimal128 must use an even/odd register pair.  */
     regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
-  else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
+  else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
+          && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
     regno = FP_ARG_RETURN;
   else if (TREE_CODE (valtype) == COMPLEX_TYPE
           && targetm.calls.split_complex_arg)
index c2f05e5..3195b67 100644 (file)
 (define_insn "*movsi_internal1"
   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,r,*q,*c*l,*h,*h")
        (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,R,*h,r,r,r,0"))]
-  "gpc_reg_operand (operands[0], SImode)
-   || gpc_reg_operand (operands[1], SImode)"
+  "!TARGET_SINGLE_FPU &&
+   gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode)"
   "@
    mr %0,%1
    {cal|la} %0,%a1
   [(set_attr "type" "*,*,load,store,*,*,*,*,mfjmpr,*,mtjmpr,*,*")
    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
 
+(define_insn "*movsi_internal1_single"
+  [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,r,*q,*c*l,*h,*h,m,*f")
+        (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,R,*h,r,r,r,0,f,m"))]
+  "TARGET_SINGLE_FPU &&
+   gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode)"
+  "@
+   mr %0,%1
+   {cal|la} %0,%a1
+   {l%U1%X1|lwz%U1%X1} %0,%1
+   {st%U0%X0|stw%U0%X0} %1,%0
+   {lil|li} %0,%1
+   {liu|lis} %0,%v1
+   #
+   {cal|la} %0,%a1
+   mf%1 %0
+   mt%0 %1
+   mt%0 %1
+   mt%0 %1
+   {cror 0,0,0|nop}
+   stfs%U0%X0 %1, %0
+   lfs%U1%X1 %0, %1"
+  [(set_attr "type" "*,*,load,store,*,*,*,*,mfjmpr,*,mtjmpr,*,*,*,*")
+   (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4,4,4")])
+
 ;; Split a load of a large constant into the appropriate two-insn
 ;; sequence.