[PATCH,spu]: generate inline code for divdf3

Sa Liu SALIU@de.ibm.com
Fri Dec 14 15:54:00 GMT 2007


Similar to the int-to-double conversion patch 
(http://gcc.gnu.org/ml/gcc-patches/2007-09/msg01161.html), this patch is 
about to genetate inline code for double division. The implementation 
doesn't handle INF or NAN, therefore it only applies when 
-ffinite-math-only is given.

No regression found in gcc test suites. OK for mainline?

Thanks!
Sa

Index: gcc/gcc/config/spu/spu.md
===================================================================
--- gcc.orig/gcc/config/spu/spu.md
+++ gcc/gcc/config/spu/spu.md
@@ -1735,6 +1735,58 @@
     DONE;
   })
 
+;; Taken from STI's gcc
+;; Does not correctly handle INF or NAN.
+(define_expand "divdf3"
+  [(set (match_operand:DF 0 "register_operand" "=r")
+        (div:DF (match_operand:DF 1 "register_operand" "r")
+                (match_operand:DF 2 "register_operand" "r")))]
+  "flag_finite_math_only"
+  "{ 
+    /*
+    double
+    divdf3 (double x, double y)
+    {
+        float x0;
+        float y_f = (float) y;
+        double x1, x2;
+
+        x0 = spu_extract(spu_re(spu_promote(y_f, 0)), 0);
+        x1 = (double)(x0 * (2.0f - y_f * x0)); 
+        x2 = x1 * (2.0 - y * x1);
+        return (x * x2 * (2.0 - y * x2));
+    }
+    */
+
+    rtx dst = operands[0];
+    rtx x   = operands[1];
+    rtx y   = operands[2];
+    rtx y_f = gen_reg_rtx(SFmode);
+    rtx x0_f = gen_reg_rtx(SFmode);
+    rtx x1_f = gen_reg_rtx(SFmode);
+    rtx x1 = gen_reg_rtx(DFmode);
+    rtx x2 = gen_reg_rtx(DFmode);
+    rtx t1_f = gen_reg_rtx(SFmode);
+    rtx t1 = gen_reg_rtx(DFmode);
+    rtx two = gen_reg_rtx(DFmode);
+    rtx two_f = gen_reg_rtx(SFmode);
+
+    emit_insn (gen_truncdfsf2 (y_f, y));
+    emit_insn (gen_frest_sf (x0_f, y_f));
+    emit_insn (gen_fi_sf (x0_f, y_f, x0_f));
+    emit_insn (gen_movsf (two_f, spu_float_const(\"2.0\",SFmode)));
+    emit_insn (gen_fnms_sf (t1_f, y_f, x0_f, two_f));
+    emit_insn (gen_mulsf3 (x1_f, t1_f, x0_f));
+    emit_insn (gen_extendsfdf2 (x1, x1_f));
+    emit_insn (gen_extendsfdf2 (two, two_f));
+    emit_insn (gen_movdf (t1, two));
+    emit_insn (gen_fnms_df (t1, y, x1, t1));
+    emit_insn (gen_muldf3 (x2, x1, t1));
+    emit_insn (gen_fnms_df (two, y, x2, two));
+    emit_insn (gen_muldf3 (dst, x2, two));
+    emit_insn (gen_muldf3 (dst, dst, x));
+    DONE;
+}")
 

 ;; sqrt
 




More information about the Gcc-patches mailing list