diff mbox

lround for PowerPC

Message ID 20151124185013.GA8088@ibm-tiger.the-meissners.org
State New
Headers show

Commit Message

Michael Meissner Nov. 24, 2015, 6:50 p.m. UTC
On Mon, Nov 23, 2015 at 07:04:33PM -0500, David Edelsohn wrote:
> I would prefer that you reverse the meaning of "Fv" and "Fv2".  "Fv"
> corresponds to VSX2 and "Fv2" corresponds to VSX, which is confusing
> for anyone trying to make sense of this in the future.
> 
> Also, the lround<mode>di2 pattern should use "Fv" not "wa" from my
> original patch.  And the ChangeLog entry should list lround<mode>di2.
> 
> Okay with those changes, after the cause of the SEGV is diagnosed and fixed.

I checked in the following patch.  Note, the segfault is independent of the
patch.  I will look into it shortly.

I will back port this patch to GCC 5 as we discussed.

2015-11-24  David Edelsohn  <dje.gcc@gmail.com>
	    Michael Meissner  <meissner@linux.vnet.ibm.com>

	* config/rs6000/rs6000.md (UNSPEC_XSRDPI): New unspec.
	(Fv2): New mode attribute to be used when ISA 2.06 instructions
	are used on SF/DF values.
	(abs<mode>2_fpr): Use <Fv2> instead of <Fv>.
	(nabs<mode>2_fpr): Likewise.
	(neg<mode>2_fpr): Likewise.
	(copysign<mode>3_fcpsgn): Likewise.
	(smax<mode>3_vsx): Likewise.
	(smin<mode>3_vsx): Likewise.
	(floatsi<mode>2_lfiwax): Likewise.
	(floatunssi<mode>2_lfiwz): Likewise.
	(fctiwz_<mode>): Likewise.
	(fctiwuz_<mode>): Likewise.
	(btrunc<mode>2): Likewise.
	(ceil<mode>2): Likewise.
	(floor<mode>2): Likewise.
	(xsrdpi<mode>): Add support for the lround function.
	(lround<mode>di2): Likewise.

Comments

Michael Meissner Nov. 24, 2015, 6:55 p.m. UTC | #1
Whoops, I forgot to update the ChangeLog after reversing Fv and Fv2.

2015-11-24  David Edelsohn  <dje.gcc@gmail.com>
	    Michael Meissner  <meissner@linux.vnet.ibm.com>

	* config/rs6000/rs6000.md (UNSPEC_XSRDPI): New unspec.
	(Fv2): New mode attribute to be used when ISA 2.07 instructions
	are used on SF values, and ISA 2.06 instructions on DF values.
	(add<mode>3_fpr): Use <Fv2> instead of <Fv>.
	(sub<mode>3_fpr): Use <Fv2> instead of <Fv>.
	(mul<mode>3_fpr): Use <Fv2> instead of <Fv>.
	(div<mode>3_fpr): Use <Fv2> instead of <Fv>.
	(sqrt<mode>2): Use <Fv2> instead of <Fv>.
	(fre<Fs>): Use <Fv2> instead of <Fv>.
	(rsqrt<mode>2): Use <Fv2> instead of <Fv>.
	(cmp<mode>_fpr): Use <Fv2> instead of <Fv>.
	(xsrdpi<mode>): Add support for the lround function.
	(lround<mode>di2): Likewise.
	(fma<mode>4_fpr): Use <Fv2> instead of <Fv>.
	(fms<mode>4_fpr): Use <Fv2> instead of <Fv>.
	(nfma<mode>4_fpr): Use <Fv2> instead of <Fv>.
	(nfms<mode>4_fpr): Use <Fv2> instead of <Fv>.
David Edelsohn Nov. 24, 2015, 7:05 p.m. UTC | #2
On Tue, Nov 24, 2015 at 1:55 PM, Michael Meissner
<meissner@linux.vnet.ibm.com> wrote:
> Whoops, I forgot to update the ChangeLog after reversing Fv and Fv2.
>
> 2015-11-24  David Edelsohn  <dje.gcc@gmail.com>
>             Michael Meissner  <meissner@linux.vnet.ibm.com>
>
>         * config/rs6000/rs6000.md (UNSPEC_XSRDPI): New unspec.
>         (Fv2): New mode attribute to be used when ISA 2.07 instructions
>         are used on SF values, and ISA 2.06 instructions on DF values.
>         (add<mode>3_fpr): Use <Fv2> instead of <Fv>.
>         (sub<mode>3_fpr): Use <Fv2> instead of <Fv>.
>         (mul<mode>3_fpr): Use <Fv2> instead of <Fv>.
>         (div<mode>3_fpr): Use <Fv2> instead of <Fv>.
>         (sqrt<mode>2): Use <Fv2> instead of <Fv>.
>         (fre<Fs>): Use <Fv2> instead of <Fv>.
>         (rsqrt<mode>2): Use <Fv2> instead of <Fv>.

Why are the above instructions converted to Fv2?  xsadd, xssub, xsmul,
xsdiv, xsre, and xsrsqrte are Power7 instructions.

xssqrt and the ones below are Power8.

>         (cmp<mode>_fpr): Use <Fv2> instead of <Fv>.
>         (xsrdpi<mode>): Add support for the lround function.
>         (lround<mode>di2): Likewise.
>         (fma<mode>4_fpr): Use <Fv2> instead of <Fv>.
>         (fms<mode>4_fpr): Use <Fv2> instead of <Fv>.
>         (nfma<mode>4_fpr): Use <Fv2> instead of <Fv>.
>         (nfms<mode>4_fpr): Use <Fv2> instead of <Fv>.

Thanks, David
diff mbox

Patch

Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(revision 230768)
+++ gcc/config/rs6000/rs6000.md	(working copy)
@@ -77,6 +77,7 @@  (define_c_enum "unspec"
    UNSPEC_FRIN
    UNSPEC_FRIP
    UNSPEC_FRIZ
+   UNSPEC_XSRDPI
    UNSPEC_LD_MPIC		; load_macho_picbase
    UNSPEC_RELD_MPIC		; re-load_macho_picbase
    UNSPEC_MPIC_CORRECT		; macho_correct_pic
@@ -491,8 +492,16 @@  (define_mode_attr Fvsx		[(SF "sp") (DF	"
 ; SF/DF constraint for arithmetic on traditional floating point registers
 (define_mode_attr Ff		[(SF "f") (DF "d") (DI "d")])
 
-; SF/DF constraint for arithmetic on VSX registers
-(define_mode_attr Fv		[(SF "wy") (DF "ws") (DI "wi")])
+; SF/DF constraint for arithmetic on VSX registers using instructions added in
+; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
+; but are used on SFmode, since internally SFmode values are kept in the DFmode
+; format.
+(define_mode_attr Fv		[(SF "ww") (DF "ws") (DI "wi")])
+
+; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
+; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
+; instructions added in ISA 2.07 (power8)
+(define_mode_attr Fv2		[(SF "wy") (DF "ws") (DI "wi")])
 
 ; SF/DF constraint for arithmetic on altivec registers
 (define_mode_attr Fa		[(SF "wu") (DF "wv")])
@@ -4344,9 +4353,9 @@  (define_expand "add<mode>3"
   "")
 
 (define_insn "*add<mode>3_fpr"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
-	(plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
-		   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
+	(plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
+		   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
   "TARGET_<MODE>_FPR"
   "@
    fadd<Ftrad> %0,%1,%2
@@ -4362,9 +4371,9 @@  (define_expand "sub<mode>3"
   "")
 
 (define_insn "*sub<mode>3_fpr"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
-	(minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
-		    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
+	(minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
+		    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
   "TARGET_<MODE>_FPR"
   "@
    fsub<Ftrad> %0,%1,%2
@@ -4380,9 +4389,9 @@  (define_expand "mul<mode>3"
   "")
 
 (define_insn "*mul<mode>3_fpr"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
-	(mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
-		   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
+	(mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
+		   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
   "TARGET_<MODE>_FPR"
   "@
    fmul<Ftrad> %0,%1,%2
@@ -4398,9 +4407,9 @@  (define_expand "div<mode>3"
   "")
 
 (define_insn "*div<mode>3_fpr"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
-	(div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
-		  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
+	(div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
+		  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
   "@
    fdiv<Ftrad> %0,%1,%2
@@ -4409,8 +4418,8 @@  (define_insn "*div<mode>3_fpr"
    (set_attr "fp_type" "fp_div_<Fs>")])
 
 (define_insn "sqrt<mode>2"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
-	(sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
+	(sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
   "@
@@ -4421,8 +4430,8 @@  (define_insn "sqrt<mode>2"
 
 ;; Floating point reciprocal approximation
 (define_insn "fre<Fs>"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
-	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
+	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
 		     UNSPEC_FRES))]
   "TARGET_<FFRE>"
   "@
@@ -4431,8 +4440,8 @@  (define_insn "fre<Fs>"
   [(set_attr "type" "fp")])
 
 (define_insn "*rsqrt<mode>2"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
-	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
+	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
 		     UNSPEC_RSQRT))]
   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
   "@
@@ -4443,8 +4452,8 @@  (define_insn "*rsqrt<mode>2"
 ;; Floating point comparisons
 (define_insn "*cmp<mode>_fpr"
   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
-	(compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
-		      (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
+	(compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
+		      (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
   "TARGET_<MODE>_FPR"
   "@
    fcmpu %0,%1,%2
@@ -5500,6 +5509,27 @@  (define_insn "round<mode>2"
   [(set_attr "type" "fp")
    (set_attr "fp_type" "fp_addsub_<Fs>")])
 
+(define_insn "*xsrdpi<mode>2"
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
+	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
+		     UNSPEC_XSRDPI))]
+  "TARGET_<MODE>_FPR && TARGET_VSX"
+  "xsrdpi %x0,%x1"
+  [(set_attr "type" "fp")
+   (set_attr "fp_type" "fp_addsub_<Fs>")])
+
+(define_expand "lround<mode>di2"
+  [(set (match_dup 2)
+	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "wa")]
+		     UNSPEC_XSRDPI))
+   (set (match_operand:DI 0 "gpc_reg_operand" "=d")
+	(unspec:DI [(match_dup 2)]
+		   UNSPEC_FCTID))]
+  "TARGET_<MODE>_FPR && TARGET_VSX"
+{
+  operands[2] = gen_reg_rtx (<MODE>mode);
+})
+
 ; An UNSPEC is used so we don't have to support SImode in FP registers.
 (define_insn "stfiwx"
   [(set (match_operand:SI 0 "memory_operand" "=Z")
@@ -12468,11 +12498,11 @@  (define_expand "fma<mode>4"
   "")
 
 (define_insn "*fma<mode>4_fpr"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
 	(fma:SFDF
-	  (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>,<Fv>")
-	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
-	  (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>")))]
+	  (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
+	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
+	  (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
   "TARGET_<MODE>_FPR"
   "@
    fmadd<Ftrad> %0,%1,%2,%3
@@ -12492,11 +12522,11 @@  (define_expand "fms<mode>4"
   "")
 
 (define_insn "*fms<mode>4_fpr"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
 	(fma:SFDF
-	 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>")
-	 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
-	 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>"))))]
+	 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
+	 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
+	 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
   "TARGET_<MODE>_FPR"
   "@
    fmsub<Ftrad> %0,%1,%2,%3
@@ -12539,12 +12569,12 @@  (define_expand "nfma<mode>4"
   "")
 
 (define_insn "*nfma<mode>4_fpr"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
 	(neg:SFDF
 	 (fma:SFDF
-	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>")
-	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
-	  (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>"))))]
+	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
+	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
+	  (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
   "TARGET_<MODE>_FPR"
   "@
    fnmadd<Ftrad> %0,%1,%2,%3
@@ -12565,13 +12595,13 @@  (define_expand "nfms<mode>4"
   "")
 
 (define_insn "*nfmssf4_fpr"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
 	(neg:SFDF
 	 (fma:SFDF
-	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>")
-	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
+	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
+	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
 	  (neg:SFDF
-	   (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>")))))]
+	   (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
   "TARGET_<MODE>_FPR"
   "@
    fnmsub<Ftrad> %0,%1,%2,%3