This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH,spu]: generate inline code for divdf3
- From: trevor_smigiel at playstation dot sony dot com
- To: Sa Liu <SALIU at de dot ibm dot com>
- Cc: gcc-patches at gcc dot gnu dot org, Andrew_Pinski at playstation dot sony dot com
- Date: Mon, 17 Dec 2007 11:56:30 -0800
- Subject: Re: [PATCH,spu]: generate inline code for divdf3
- References: <OFC4A8054B.F395E4FB-ONC12573B1.0056021D-C12573B1.005747B0@de.ibm.com>
OK.
Trevor
* Sa Liu <SALIU@de.ibm.com> [2007-12-14 08:30]:
> 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
>
>
>