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 "abs2" "") (define_insn "*abs2_fpr" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=,") - (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" ",")))] + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=,") + (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" ",")))] "TARGET__FPR" "@ fabs %0,%1 @@ -4309,10 +4318,10 @@ (define_insn "*abs2_fpr" (set_attr "fp_type" "fp_addsub_")]) (define_insn "*nabs2_fpr" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=,") + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=,") (neg:SFDF (abs:SFDF - (match_operand:SFDF 1 "gpc_reg_operand" ","))))] + (match_operand:SFDF 1 "gpc_reg_operand" ","))))] "TARGET__FPR" "@ fnabs %0,%1 @@ -4327,8 +4336,8 @@ (define_expand "neg2" "") (define_insn "*neg2_fpr" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=,") - (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" ",")))] + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=,") + (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" ",")))] "TARGET__FPR" "@ fneg %0,%1 @@ -4557,9 +4566,9 @@ (define_expand "copysign3" ;; Use an unspec rather providing an if-then-else in RTL, to prevent the ;; compiler from optimizing -0.0 (define_insn "copysign3_fcpsgn" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=,") - (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" ",") - (match_operand:SFDF 2 "gpc_reg_operand" ",")] + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=,") + (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" ",") + (match_operand:SFDF 2 "gpc_reg_operand" ",")] UNSPEC_COPYSIGN))] "TARGET__FPR && TARGET_CMPB" "@ @@ -4593,9 +4602,9 @@ (define_expand "smax3" }) (define_insn "*smax3_vsx" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=,") - (smax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%,") - (match_operand:SFDF 2 "gpc_reg_operand" ",")))] + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=,") + (smax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%,") + (match_operand:SFDF 2 "gpc_reg_operand" ",")))] "TARGET__FPR && TARGET_VSX" "xsmaxdp %x0,%x1,%x2" [(set_attr "type" "fp")]) @@ -4613,9 +4622,9 @@ (define_expand "smin3" }) (define_insn "*smin3_vsx" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=,") - (smin:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%,") - (match_operand:SFDF 2 "gpc_reg_operand" ",")))] + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=,") + (smin:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%,") + (match_operand:SFDF 2 "gpc_reg_operand" ",")))] "TARGET__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 "floatsi2_lfiwax" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=") + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=") (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 "floatunssi2_lfiwzx" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=") + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=") (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_truncdi2_fct ; before the instruction. (define_insn "fctiwz_" [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") - (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" ","))] + (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" ","))] UNSPEC_FCTIWZ))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "@ @@ -5357,7 +5366,7 @@ (define_insn "fctiwz_" (define_insn "fctiwuz_" [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") (unspec:DI [(unsigned_fix:SI - (match_operand:SFDF 1 "gpc_reg_operand" ","))] + (match_operand:SFDF 1 "gpc_reg_operand" ","))] UNSPEC_FCTIWUZ))] "TARGET_HARD_FLOAT && TARGET_FPRS && && TARGET_FCTIWUZ" "@ @@ -5458,8 +5467,8 @@ (define_insn "lrintdi2" [(set_attr "type" "fp")]) (define_insn "btrunc2" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=,") - (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" ",")] + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=,") + (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" ",")] UNSPEC_FRIZ))] "TARGET__FPR && TARGET_FPRND" "@ @@ -5469,8 +5478,8 @@ (define_insn "btrunc2" (set_attr "fp_type" "fp_addsub_")]) (define_insn "ceil2" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=,") - (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" ",")] + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=,") + (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" ",")] UNSPEC_FRIP))] "TARGET__FPR && TARGET_FPRND" "@ @@ -5480,8 +5489,8 @@ (define_insn "ceil2" (set_attr "fp_type" "fp_addsub_")]) (define_insn "floor2" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=,") - (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" ",")] + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=,") + (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" ",")] UNSPEC_FRIM))] "TARGET__FPR && TARGET_FPRND" "@ @@ -5500,6 +5509,27 @@ (define_insn "round2" [(set_attr "type" "fp") (set_attr "fp_type" "fp_addsub_")]) +(define_insn "*xsrdpi2" + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=") + (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")] + UNSPEC_XSRDPI))] + "TARGET__FPR && TARGET_VSX" + "xsrdpi %x0,%x1" + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_addsub_")]) + +(define_expand "lrounddi2" + [(set (match_dup 2) + (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")] + UNSPEC_XSRDPI)) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (unspec:DI [(match_dup 2)] + UNSPEC_FCTID))] + "TARGET__FPR && TARGET_VSX" +{ + operands[2] = gen_reg_rtx (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")