diff mbox

lround for PowerPC

Message ID 20151123215623.GA21427@ibm-tiger.the-meissners.org
State New
Headers show

Commit Message

Michael Meissner Nov. 23, 2015, 9:56 p.m. UTC
David ping'ed me on internal IRC, and I had a thinko in terms of the use of the
<Fv> mode attribute.  In some of the uses (such as abs, smax, etc.) we want to
use ISA 2.06 instructions on SFmode, while in other uses (add, mul, etc.) we
want to use it only if we have the ISA 2.07 instrucitons.

I have split these mode attributes into Fv and Fv2 and gone through all of the
uses in the compiler to use the appropriate attribute.  I have built a cross
compiler on x86, but it blew up on a big endian power7 with a segmentation
violation that I need to look into.  I'm also building on a little endian
power8 right now, and it has gotten further.

2015-11-23  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>2): Likewise.

Comments

David Edelsohn Nov. 24, 2015, 12:04 a.m. UTC | #1
On Mon, Nov 23, 2015 at 4:56 PM, Michael Meissner
<meissner@linux.vnet.ibm.com> wrote:
> David ping'ed me on internal IRC, and I had a thinko in terms of the use of the
> <Fv> mode attribute.  In some of the uses (such as abs, smax, etc.) we want to
> use ISA 2.06 instructions on SFmode, while in other uses (add, mul, etc.) we
> want to use it only if we have the ISA 2.07 instrucitons.
>
> I have split these mode attributes into Fv and Fv2 and gone through all of the
> uses in the compiler to use the appropriate attribute.  I have built a cross
> compiler on x86, but it blew up on a big endian power7 with a segmentation
> violation that I need to look into.  I'm also building on a little endian
> power8 right now, and it has gotten further.
>
> 2015-11-23  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>2): Likewise.

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.

Thanks, David
Michael Meissner Nov. 24, 2015, 10:42 p.m. UTC | #2
On Mon, Nov 23, 2015 at 07:04:33PM -0500, David Edelsohn wrote:
> Okay with those changes, after the cause of the SEGV is diagnosed and fixed.

It must have a temporary failure (either in the source, or perhaps something
was amiss on the machine I was building on).  I checked out a new trunk, and
bootstrapped it with the host compiler, and it no longer fails.
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,9 +492,17 @@  (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
+; 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 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 Fv2		[(SF "ww") (DF "ws") (DI "wi")])
+
 ; SF/DF constraint for arithmetic on altivec registers
 (define_mode_attr Fa		[(SF "wu") (DF "wv")])
 
@@ -4299,8 +4308,8 @@  (define_expand "abs<mode>2"
   "")
 
 (define_insn "*abs<mode>2_fpr"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
-	(abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
+	(abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
   "TARGET_<MODE>_FPR"
   "@
    fabs %0,%1
@@ -4309,10 +4318,10 @@  (define_insn "*abs<mode>2_fpr"
    (set_attr "fp_type" "fp_addsub_<Fs>")])
 
 (define_insn "*nabs<mode>2_fpr"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
 	(neg:SFDF
 	 (abs:SFDF
-	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
+	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>"))))]
   "TARGET_<MODE>_FPR"
   "@
    fnabs %0,%1
@@ -4327,8 +4336,8 @@  (define_expand "neg<mode>2"
   "")
 
 (define_insn "*neg<mode>2_fpr"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
-	(neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
+	(neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
   "TARGET_<MODE>_FPR"
   "@
    fneg %0,%1
@@ -4557,9 +4566,9 @@  (define_expand "copysign<mode>3"
 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
 ;; compiler from optimizing -0.0
 (define_insn "copysign<mode>3_fcpsgn"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
-	(unspec: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>")
+	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
+		      (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")]
 		     UNSPEC_COPYSIGN))]
   "TARGET_<MODE>_FPR && TARGET_CMPB"
   "@
@@ -4593,9 +4602,9 @@  (define_expand "smax<mode>3"
 })
 
 (define_insn "*smax<mode>3_vsx"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
-	(smax: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>")
+	(smax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
+		   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
   "TARGET_<MODE>_FPR && TARGET_VSX"
   "xsmaxdp %x0,%x1,%x2"
   [(set_attr "type" "fp")])
@@ -4613,9 +4622,9 @@  (define_expand "smin<mode>3"
 })
 
 (define_insn "*smin<mode>3_vsx"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
-	(smin: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>")
+	(smin:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
+		   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
   "TARGET_<MODE>_FPR && TARGET_VSX"
   "xsmindp %x0,%x1,%x2"
   [(set_attr "type" "fp")])
@@ -4836,7 +4845,7 @@  (define_insn "lfiwax"
 ; not be needed and also in case the insns are deleted as dead code.
 
 (define_insn_and_split "floatsi<mode>2_lfiwax"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv2>")
 	(float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
    (clobber (match_scratch:DI 2 "=wj"))]
   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
@@ -4911,7 +4920,7 @@  (define_insn "lfiwzx"
   [(set_attr "type" "fpload,fpload,mftgpr")])
 
 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
-  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv2>")
 	(unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
    (clobber (match_scratch:DI 2 "=wj"))]
   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
@@ -5346,7 +5355,7 @@  (define_insn "*fixuns_trunc<mode>di2_fct
 ; before the instruction.
 (define_insn "fctiwz_<mode>"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
-	(unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
+	(unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>"))]
 		   UNSPEC_FCTIWZ))]
   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
   "@
@@ -5357,7 +5366,7 @@  (define_insn "fctiwz_<mode>"
 (define_insn "fctiwuz_<mode>"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
 	(unspec:DI [(unsigned_fix:SI
-		     (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
+		     (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>"))]
 		   UNSPEC_FCTIWUZ))]
   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
   "@
@@ -5458,8 +5467,8 @@  (define_insn "lrint<mode>di2"
   [(set_attr "type" "fp")])
 
 (define_insn "btrunc<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_FRIZ))]
   "TARGET_<MODE>_FPR && TARGET_FPRND"
   "@
@@ -5469,8 +5478,8 @@  (define_insn "btrunc<mode>2"
    (set_attr "fp_type" "fp_addsub_<Fs>")])
 
 (define_insn "ceil<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_FRIP))]
   "TARGET_<MODE>_FPR && TARGET_FPRND"
   "@
@@ -5480,8 +5489,8 @@  (define_insn "ceil<mode>2"
    (set_attr "fp_type" "fp_addsub_<Fs>")])
 
 (define_insn "floor<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_FRIM))]
   "TARGET_<MODE>_FPR && TARGET_FPRND"
   "@
@@ -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" "=<Fv2>")
+	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv2>")]
+		     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")