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....@gmail.com> Michael Meissner <meiss...@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. -- Michael Meissner, IBM IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA email: meiss...@linux.vnet.ibm.com, phone: +1 (978) 899-4797
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