10b57cec5SDimitry Andric//===- README_P9.txt - Notes for improving Power9 code gen ----------------===//
20b57cec5SDimitry Andric
30b57cec5SDimitry AndricTODO: Instructions Need Implement Instrinstics or Map to LLVM IR
40b57cec5SDimitry Andric
50b57cec5SDimitry AndricAltivec:
60b57cec5SDimitry Andric- Vector Compare Not Equal (Zero):
70b57cec5SDimitry Andric  vcmpneb(.) vcmpneh(.) vcmpnew(.)
80b57cec5SDimitry Andric  vcmpnezb(.) vcmpnezh(.) vcmpnezw(.)
90b57cec5SDimitry Andric  . Same as other VCMP*, use VCMP/VCMPo form (support intrinsic)
100b57cec5SDimitry Andric
110b57cec5SDimitry Andric- Vector Extract Unsigned: vextractub vextractuh vextractuw vextractd
120b57cec5SDimitry Andric  . Don't use llvm extractelement because they have different semantics
130b57cec5SDimitry Andric  . Use instrinstics:
140b57cec5SDimitry Andric    (set v2i64:$vD, (int_ppc_altivec_vextractub v16i8:$vA, imm:$UIMM))
150b57cec5SDimitry Andric    (set v2i64:$vD, (int_ppc_altivec_vextractuh v8i16:$vA, imm:$UIMM))
160b57cec5SDimitry Andric    (set v2i64:$vD, (int_ppc_altivec_vextractuw v4i32:$vA, imm:$UIMM))
170b57cec5SDimitry Andric    (set v2i64:$vD, (int_ppc_altivec_vextractd  v2i64:$vA, imm:$UIMM))
180b57cec5SDimitry Andric
190b57cec5SDimitry Andric- Vector Extract Unsigned Byte Left/Right-Indexed:
200b57cec5SDimitry Andric  vextublx vextubrx vextuhlx vextuhrx vextuwlx vextuwrx
210b57cec5SDimitry Andric  . Use instrinstics:
220b57cec5SDimitry Andric    // Left-Indexed
230b57cec5SDimitry Andric    (set i64:$rD, (int_ppc_altivec_vextublx i64:$rA, v16i8:$vB))
240b57cec5SDimitry Andric    (set i64:$rD, (int_ppc_altivec_vextuhlx i64:$rA, v8i16:$vB))
250b57cec5SDimitry Andric    (set i64:$rD, (int_ppc_altivec_vextuwlx i64:$rA, v4i32:$vB))
260b57cec5SDimitry Andric
270b57cec5SDimitry Andric    // Right-Indexed
280b57cec5SDimitry Andric    (set i64:$rD, (int_ppc_altivec_vextubrx i64:$rA, v16i8:$vB))
290b57cec5SDimitry Andric    (set i64:$rD, (int_ppc_altivec_vextuhrx i64:$rA, v8i16:$vB))
300b57cec5SDimitry Andric    (set i64:$rD, (int_ppc_altivec_vextuwrx i64:$rA, v4i32:$vB))
310b57cec5SDimitry Andric
320b57cec5SDimitry Andric- Vector Insert Element Instructions: vinsertb vinsertd vinserth vinsertw
330b57cec5SDimitry Andric    (set v16i8:$vD, (int_ppc_altivec_vinsertb v16i8:$vA, imm:$UIMM))
340b57cec5SDimitry Andric    (set v8i16:$vD, (int_ppc_altivec_vinsertd v8i16:$vA, imm:$UIMM))
350b57cec5SDimitry Andric    (set v4i32:$vD, (int_ppc_altivec_vinserth v4i32:$vA, imm:$UIMM))
360b57cec5SDimitry Andric    (set v2i64:$vD, (int_ppc_altivec_vinsertw v2i64:$vA, imm:$UIMM))
370b57cec5SDimitry Andric
380b57cec5SDimitry Andric- Vector Count Leading/Trailing Zero LSB. Result is placed into GPR[rD]:
390b57cec5SDimitry Andric  vclzlsbb vctzlsbb
400b57cec5SDimitry Andric  . Use intrinsic:
410b57cec5SDimitry Andric    (set i64:$rD, (int_ppc_altivec_vclzlsbb v16i8:$vB))
420b57cec5SDimitry Andric    (set i64:$rD, (int_ppc_altivec_vctzlsbb v16i8:$vB))
430b57cec5SDimitry Andric
440b57cec5SDimitry Andric- Vector Count Trailing Zeros: vctzb vctzh vctzw vctzd
450b57cec5SDimitry Andric  . Map to llvm cttz
460b57cec5SDimitry Andric    (set v16i8:$vD, (cttz v16i8:$vB))     // vctzb
470b57cec5SDimitry Andric    (set v8i16:$vD, (cttz v8i16:$vB))     // vctzh
480b57cec5SDimitry Andric    (set v4i32:$vD, (cttz v4i32:$vB))     // vctzw
490b57cec5SDimitry Andric    (set v2i64:$vD, (cttz v2i64:$vB))     // vctzd
500b57cec5SDimitry Andric
510b57cec5SDimitry Andric- Vector Extend Sign: vextsb2w vextsh2w vextsb2d vextsh2d vextsw2d
520b57cec5SDimitry Andric  . vextsb2w:
530b57cec5SDimitry Andric    (set v4i32:$vD, (sext v4i8:$vB))
540b57cec5SDimitry Andric
550b57cec5SDimitry Andric    // PowerISA_V3.0:
560b57cec5SDimitry Andric    do i = 0 to 3
570b57cec5SDimitry Andric       VR[VRT].word[i] ← EXTS32(VR[VRB].word[i].byte[3])
580b57cec5SDimitry Andric    end
590b57cec5SDimitry Andric
600b57cec5SDimitry Andric  . vextsh2w:
610b57cec5SDimitry Andric    (set v4i32:$vD, (sext v4i16:$vB))
620b57cec5SDimitry Andric
630b57cec5SDimitry Andric    // PowerISA_V3.0:
640b57cec5SDimitry Andric    do i = 0 to 3
650b57cec5SDimitry Andric       VR[VRT].word[i] ← EXTS32(VR[VRB].word[i].hword[1])
660b57cec5SDimitry Andric    end
670b57cec5SDimitry Andric
680b57cec5SDimitry Andric  . vextsb2d
690b57cec5SDimitry Andric    (set v2i64:$vD, (sext v2i8:$vB))
700b57cec5SDimitry Andric
710b57cec5SDimitry Andric    // PowerISA_V3.0:
720b57cec5SDimitry Andric    do i = 0 to 1
730b57cec5SDimitry Andric       VR[VRT].dword[i] ← EXTS64(VR[VRB].dword[i].byte[7])
740b57cec5SDimitry Andric    end
750b57cec5SDimitry Andric
760b57cec5SDimitry Andric  . vextsh2d
770b57cec5SDimitry Andric    (set v2i64:$vD, (sext v2i16:$vB))
780b57cec5SDimitry Andric
790b57cec5SDimitry Andric    // PowerISA_V3.0:
800b57cec5SDimitry Andric    do i = 0 to 1
810b57cec5SDimitry Andric       VR[VRT].dword[i] ← EXTS64(VR[VRB].dword[i].hword[3])
820b57cec5SDimitry Andric    end
830b57cec5SDimitry Andric
840b57cec5SDimitry Andric  . vextsw2d
850b57cec5SDimitry Andric    (set v2i64:$vD, (sext v2i32:$vB))
860b57cec5SDimitry Andric
870b57cec5SDimitry Andric    // PowerISA_V3.0:
880b57cec5SDimitry Andric    do i = 0 to 1
890b57cec5SDimitry Andric       VR[VRT].dword[i] ← EXTS64(VR[VRB].dword[i].word[1])
900b57cec5SDimitry Andric    end
910b57cec5SDimitry Andric
920b57cec5SDimitry Andric- Vector Integer Negate: vnegw vnegd
930b57cec5SDimitry Andric  . Map to llvm ineg
940b57cec5SDimitry Andric    (set v4i32:$rT, (ineg v4i32:$rA))       // vnegw
950b57cec5SDimitry Andric    (set v2i64:$rT, (ineg v2i64:$rA))       // vnegd
960b57cec5SDimitry Andric
970b57cec5SDimitry Andric- Vector Parity Byte: vprtybw vprtybd vprtybq
980b57cec5SDimitry Andric  . Use intrinsic:
990b57cec5SDimitry Andric    (set v4i32:$rD, (int_ppc_altivec_vprtybw v4i32:$vB))
1000b57cec5SDimitry Andric    (set v2i64:$rD, (int_ppc_altivec_vprtybd v2i64:$vB))
1010b57cec5SDimitry Andric    (set v1i128:$rD, (int_ppc_altivec_vprtybq v1i128:$vB))
1020b57cec5SDimitry Andric
1030b57cec5SDimitry Andric- Vector (Bit) Permute (Right-indexed):
1040b57cec5SDimitry Andric  . vbpermd: Same as "vbpermq", use VX1_Int_Ty2:
1050b57cec5SDimitry Andric    VX1_Int_Ty2<1484, "vbpermd", int_ppc_altivec_vbpermd, v2i64, v2i64>;
1060b57cec5SDimitry Andric
1070b57cec5SDimitry Andric  . vpermr: use VA1a_Int_Ty3
1080b57cec5SDimitry Andric    VA1a_Int_Ty3<59, "vpermr", int_ppc_altivec_vpermr, v16i8, v16i8, v16i8>;
1090b57cec5SDimitry Andric
1100b57cec5SDimitry Andric- Vector Rotate Left Mask/Mask-Insert: vrlwnm vrlwmi vrldnm vrldmi
1110b57cec5SDimitry Andric  . Use intrinsic:
1120b57cec5SDimitry Andric    VX1_Int_Ty<389, "vrlwnm", int_ppc_altivec_vrlwnm, v4i32>;
1130b57cec5SDimitry Andric    VX1_Int_Ty<133, "vrlwmi", int_ppc_altivec_vrlwmi, v4i32>;
1140b57cec5SDimitry Andric    VX1_Int_Ty<453, "vrldnm", int_ppc_altivec_vrldnm, v2i64>;
1150b57cec5SDimitry Andric    VX1_Int_Ty<197, "vrldmi", int_ppc_altivec_vrldmi, v2i64>;
1160b57cec5SDimitry Andric
1170b57cec5SDimitry Andric- Vector Shift Left/Right: vslv vsrv
1180b57cec5SDimitry Andric  . Use intrinsic, don't map to llvm shl and lshr, because they have different
1190b57cec5SDimitry Andric    semantics, e.g. vslv:
1200b57cec5SDimitry Andric
1210b57cec5SDimitry Andric      do i = 0 to 15
1220b57cec5SDimitry Andric         sh ← VR[VRB].byte[i].bit[5:7]
1230b57cec5SDimitry Andric         VR[VRT].byte[i] ← src.byte[i:i+1].bit[sh:sh+7]
1240b57cec5SDimitry Andric      end
1250b57cec5SDimitry Andric
1260b57cec5SDimitry Andric    VR[VRT].byte[i] is composed of 2 bytes from src.byte[i:i+1]
1270b57cec5SDimitry Andric
1280b57cec5SDimitry Andric  . VX1_Int_Ty<1860, "vslv", int_ppc_altivec_vslv, v16i8>;
1290b57cec5SDimitry Andric    VX1_Int_Ty<1796, "vsrv", int_ppc_altivec_vsrv, v16i8>;
1300b57cec5SDimitry Andric
1310b57cec5SDimitry Andric- Vector Multiply-by-10 (& Write Carry) Unsigned Quadword:
1320b57cec5SDimitry Andric  vmul10uq vmul10cuq
1330b57cec5SDimitry Andric  . Use intrinsic:
1340b57cec5SDimitry Andric    VX1_Int_Ty<513, "vmul10uq",   int_ppc_altivec_vmul10uq,  v1i128>;
1350b57cec5SDimitry Andric    VX1_Int_Ty<  1, "vmul10cuq",  int_ppc_altivec_vmul10cuq, v1i128>;
1360b57cec5SDimitry Andric
1370b57cec5SDimitry Andric- Vector Multiply-by-10 Extended (& Write Carry) Unsigned Quadword:
1380b57cec5SDimitry Andric  vmul10euq vmul10ecuq
1390b57cec5SDimitry Andric  . Use intrinsic:
1400b57cec5SDimitry Andric    VX1_Int_Ty<577, "vmul10euq",  int_ppc_altivec_vmul10euq, v1i128>;
1410b57cec5SDimitry Andric    VX1_Int_Ty< 65, "vmul10ecuq", int_ppc_altivec_vmul10ecuq, v1i128>;
1420b57cec5SDimitry Andric
1430b57cec5SDimitry Andric- Decimal Convert From/to National/Zoned/Signed-QWord:
1440b57cec5SDimitry Andric  bcdcfn. bcdcfz. bcdctn. bcdctz. bcdcfsq. bcdctsq.
1450b57cec5SDimitry Andric  . Use instrinstics:
1460b57cec5SDimitry Andric    (set v1i128:$vD, (int_ppc_altivec_bcdcfno  v1i128:$vB, i1:$PS))
1470b57cec5SDimitry Andric    (set v1i128:$vD, (int_ppc_altivec_bcdcfzo  v1i128:$vB, i1:$PS))
1480b57cec5SDimitry Andric    (set v1i128:$vD, (int_ppc_altivec_bcdctno  v1i128:$vB))
1490b57cec5SDimitry Andric    (set v1i128:$vD, (int_ppc_altivec_bcdctzo  v1i128:$vB, i1:$PS))
1500b57cec5SDimitry Andric    (set v1i128:$vD, (int_ppc_altivec_bcdcfsqo v1i128:$vB, i1:$PS))
1510b57cec5SDimitry Andric    (set v1i128:$vD, (int_ppc_altivec_bcdctsqo v1i128:$vB))
1520b57cec5SDimitry Andric
1530b57cec5SDimitry Andric- Decimal Copy-Sign/Set-Sign: bcdcpsgn. bcdsetsgn.
1540b57cec5SDimitry Andric  . Use instrinstics:
1550b57cec5SDimitry Andric    (set v1i128:$vD, (int_ppc_altivec_bcdcpsgno v1i128:$vA, v1i128:$vB))
1560b57cec5SDimitry Andric    (set v1i128:$vD, (int_ppc_altivec_bcdsetsgno v1i128:$vB, i1:$PS))
1570b57cec5SDimitry Andric
1580b57cec5SDimitry Andric- Decimal Shift/Unsigned-Shift/Shift-and-Round: bcds. bcdus. bcdsr.
1590b57cec5SDimitry Andric  . Use instrinstics:
1600b57cec5SDimitry Andric    (set v1i128:$vD, (int_ppc_altivec_bcdso  v1i128:$vA, v1i128:$vB, i1:$PS))
1610b57cec5SDimitry Andric    (set v1i128:$vD, (int_ppc_altivec_bcduso v1i128:$vA, v1i128:$vB))
1620b57cec5SDimitry Andric    (set v1i128:$vD, (int_ppc_altivec_bcdsro v1i128:$vA, v1i128:$vB, i1:$PS))
1630b57cec5SDimitry Andric
1640b57cec5SDimitry Andric  . Note! Their VA is accessed only 1 byte, i.e. VA.byte[7]
1650b57cec5SDimitry Andric
1660b57cec5SDimitry Andric- Decimal (Unsigned) Truncate: bcdtrunc. bcdutrunc.
1670b57cec5SDimitry Andric  . Use instrinstics:
1680b57cec5SDimitry Andric    (set v1i128:$vD, (int_ppc_altivec_bcdso  v1i128:$vA, v1i128:$vB, i1:$PS))
1690b57cec5SDimitry Andric    (set v1i128:$vD, (int_ppc_altivec_bcduso v1i128:$vA, v1i128:$vB))
1700b57cec5SDimitry Andric
1710b57cec5SDimitry Andric  . Note! Their VA is accessed only 2 byte, i.e. VA.hword[3] (VA.bit[48:63])
1720b57cec5SDimitry Andric
1730b57cec5SDimitry AndricVSX:
1740b57cec5SDimitry Andric- QP Copy Sign: xscpsgnqp
1750b57cec5SDimitry Andric  . Similar to xscpsgndp
1760b57cec5SDimitry Andric  . (set f128:$vT, (fcopysign f128:$vB, f128:$vA)
1770b57cec5SDimitry Andric
1780b57cec5SDimitry Andric- QP Absolute/Negative-Absolute/Negate: xsabsqp xsnabsqp xsnegqp
1790b57cec5SDimitry Andric  . Similar to xsabsdp/xsnabsdp/xsnegdp
1800b57cec5SDimitry Andric  . (set f128:$vT, (fabs f128:$vB))             // xsabsqp
1810b57cec5SDimitry Andric    (set f128:$vT, (fneg (fabs f128:$vB)))      // xsnabsqp
1820b57cec5SDimitry Andric    (set f128:$vT, (fneg f128:$vB))             // xsnegqp
1830b57cec5SDimitry Andric
1840b57cec5SDimitry Andric- QP Add/Divide/Multiply/Subtract/Square-Root:
1850b57cec5SDimitry Andric  xsaddqp xsdivqp xsmulqp xssubqp xssqrtqp
1860b57cec5SDimitry Andric  . Similar to xsadddp
1870b57cec5SDimitry Andric  . isCommutable = 1
1880b57cec5SDimitry Andric    (set f128:$vT, (fadd f128:$vA, f128:$vB))   // xsaddqp
1890b57cec5SDimitry Andric    (set f128:$vT, (fmul f128:$vA, f128:$vB))   // xsmulqp
1900b57cec5SDimitry Andric
1910b57cec5SDimitry Andric  . isCommutable = 0
1920b57cec5SDimitry Andric    (set f128:$vT, (fdiv f128:$vA, f128:$vB))   // xsdivqp
1930b57cec5SDimitry Andric    (set f128:$vT, (fsub f128:$vA, f128:$vB))   // xssubqp
1940b57cec5SDimitry Andric    (set f128:$vT, (fsqrt f128:$vB)))           // xssqrtqp
1950b57cec5SDimitry Andric
1960b57cec5SDimitry Andric- Round to Odd of QP Add/Divide/Multiply/Subtract/Square-Root:
1970b57cec5SDimitry Andric  xsaddqpo xsdivqpo xsmulqpo xssubqpo xssqrtqpo
1980b57cec5SDimitry Andric  . Similar to xsrsqrtedp??
1990b57cec5SDimitry Andric      def XSRSQRTEDP : XX2Form<60, 74,
2000b57cec5SDimitry Andric                               (outs vsfrc:$XT), (ins vsfrc:$XB),
2010b57cec5SDimitry Andric                               "xsrsqrtedp $XT, $XB", IIC_VecFP,
2020b57cec5SDimitry Andric                               [(set f64:$XT, (PPCfrsqrte f64:$XB))]>;
2030b57cec5SDimitry Andric
2040b57cec5SDimitry Andric  . Define DAG Node in PPCInstrInfo.td:
2050b57cec5SDimitry Andric    def PPCfaddrto: SDNode<"PPCISD::FADDRTO", SDTFPBinOp, []>;
2060b57cec5SDimitry Andric    def PPCfdivrto: SDNode<"PPCISD::FDIVRTO", SDTFPBinOp, []>;
2070b57cec5SDimitry Andric    def PPCfmulrto: SDNode<"PPCISD::FMULRTO", SDTFPBinOp, []>;
2080b57cec5SDimitry Andric    def PPCfsubrto: SDNode<"PPCISD::FSUBRTO", SDTFPBinOp, []>;
2090b57cec5SDimitry Andric    def PPCfsqrtrto: SDNode<"PPCISD::FSQRTRTO", SDTFPUnaryOp, []>;
2100b57cec5SDimitry Andric
2110b57cec5SDimitry Andric    DAG patterns of each instruction (PPCInstrVSX.td):
2120b57cec5SDimitry Andric    . isCommutable = 1
2130b57cec5SDimitry Andric      (set f128:$vT, (PPCfaddrto f128:$vA, f128:$vB))   // xsaddqpo
2140b57cec5SDimitry Andric      (set f128:$vT, (PPCfmulrto f128:$vA, f128:$vB))   // xsmulqpo
2150b57cec5SDimitry Andric
2160b57cec5SDimitry Andric    . isCommutable = 0
2170b57cec5SDimitry Andric      (set f128:$vT, (PPCfdivrto f128:$vA, f128:$vB))   // xsdivqpo
2180b57cec5SDimitry Andric      (set f128:$vT, (PPCfsubrto f128:$vA, f128:$vB))   // xssubqpo
2190b57cec5SDimitry Andric      (set f128:$vT, (PPCfsqrtrto f128:$vB))            // xssqrtqpo
2200b57cec5SDimitry Andric
2210b57cec5SDimitry Andric- QP (Negative) Multiply-{Add/Subtract}: xsmaddqp xsmsubqp xsnmaddqp xsnmsubqp
2220b57cec5SDimitry Andric  . Ref: xsmaddadp/xsmsubadp/xsnmaddadp/xsnmsubadp
2230b57cec5SDimitry Andric
2240b57cec5SDimitry Andric  . isCommutable = 1
2250b57cec5SDimitry Andric    // xsmaddqp
2260b57cec5SDimitry Andric    [(set f128:$vT, (fma f128:$vA, f128:$vB, f128:$vTi))]>,
2270b57cec5SDimitry Andric    RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">,
2280b57cec5SDimitry Andric    AltVSXFMARel;
2290b57cec5SDimitry Andric
2300b57cec5SDimitry Andric    // xsmsubqp
2310b57cec5SDimitry Andric    [(set f128:$vT, (fma f128:$vA, f128:$vB, (fneg f128:$vTi)))]>,
2320b57cec5SDimitry Andric    RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">,
2330b57cec5SDimitry Andric    AltVSXFMARel;
2340b57cec5SDimitry Andric
2350b57cec5SDimitry Andric    // xsnmaddqp
2360b57cec5SDimitry Andric    [(set f128:$vT, (fneg (fma f128:$vA, f128:$vB, f128:$vTi)))]>,
2370b57cec5SDimitry Andric    RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">,
2380b57cec5SDimitry Andric    AltVSXFMARel;
2390b57cec5SDimitry Andric
2400b57cec5SDimitry Andric    // xsnmsubqp
2410b57cec5SDimitry Andric    [(set f128:$vT, (fneg (fma f128:$vA, f128:$vB, (fneg f128:$vTi))))]>,
2420b57cec5SDimitry Andric    RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">,
2430b57cec5SDimitry Andric    AltVSXFMARel;
2440b57cec5SDimitry Andric
2450b57cec5SDimitry Andric- Round to Odd of QP (Negative) Multiply-{Add/Subtract}:
2460b57cec5SDimitry Andric  xsmaddqpo xsmsubqpo xsnmaddqpo xsnmsubqpo
2470b57cec5SDimitry Andric  . Similar to xsrsqrtedp??
2480b57cec5SDimitry Andric
2490b57cec5SDimitry Andric  . Define DAG Node in PPCInstrInfo.td:
2500b57cec5SDimitry Andric    def PPCfmarto: SDNode<"PPCISD::FMARTO", SDTFPTernaryOp, []>;
2510b57cec5SDimitry Andric
2520b57cec5SDimitry Andric    It looks like we only need to define "PPCfmarto" for these instructions,
2530b57cec5SDimitry Andric    because according to PowerISA_V3.0, these instructions perform RTO on
2540b57cec5SDimitry Andric    fma's result:
2550b57cec5SDimitry Andric        xsmaddqp(o)
2560b57cec5SDimitry Andric        v      ← bfp_MULTIPLY_ADD(src1, src3, src2)
2570b57cec5SDimitry Andric        rnd    ← bfp_ROUND_TO_BFP128(RO, FPSCR.RN, v)
2580b57cec5SDimitry Andric        result ← bfp_CONVERT_TO_BFP128(rnd)
2590b57cec5SDimitry Andric
2600b57cec5SDimitry Andric        xsmsubqp(o)
2610b57cec5SDimitry Andric        v      ← bfp_MULTIPLY_ADD(src1, src3, bfp_NEGATE(src2))
2620b57cec5SDimitry Andric        rnd    ← bfp_ROUND_TO_BFP128(RO, FPSCR.RN, v)
2630b57cec5SDimitry Andric        result ← bfp_CONVERT_TO_BFP128(rnd)
2640b57cec5SDimitry Andric
2650b57cec5SDimitry Andric        xsnmaddqp(o)
2660b57cec5SDimitry Andric        v      ← bfp_MULTIPLY_ADD(src1,src3,src2)
2670b57cec5SDimitry Andric        rnd    ← bfp_NEGATE(bfp_ROUND_TO_BFP128(RO, FPSCR.RN, v))
2680b57cec5SDimitry Andric        result ← bfp_CONVERT_TO_BFP128(rnd)
2690b57cec5SDimitry Andric
2700b57cec5SDimitry Andric        xsnmsubqp(o)
2710b57cec5SDimitry Andric        v      ← bfp_MULTIPLY_ADD(src1, src3, bfp_NEGATE(src2))
2720b57cec5SDimitry Andric        rnd    ← bfp_NEGATE(bfp_ROUND_TO_BFP128(RO, FPSCR.RN, v))
2730b57cec5SDimitry Andric        result ← bfp_CONVERT_TO_BFP128(rnd)
2740b57cec5SDimitry Andric
2750b57cec5SDimitry Andric    DAG patterns of each instruction (PPCInstrVSX.td):
2760b57cec5SDimitry Andric    . isCommutable = 1
2770b57cec5SDimitry Andric      // xsmaddqpo
2780b57cec5SDimitry Andric      [(set f128:$vT, (PPCfmarto f128:$vA, f128:$vB, f128:$vTi))]>,
2790b57cec5SDimitry Andric      RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">,
2800b57cec5SDimitry Andric      AltVSXFMARel;
2810b57cec5SDimitry Andric
2820b57cec5SDimitry Andric      // xsmsubqpo
2830b57cec5SDimitry Andric      [(set f128:$vT, (PPCfmarto f128:$vA, f128:$vB, (fneg f128:$vTi)))]>,
2840b57cec5SDimitry Andric      RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">,
2850b57cec5SDimitry Andric      AltVSXFMARel;
2860b57cec5SDimitry Andric
2870b57cec5SDimitry Andric      // xsnmaddqpo
2880b57cec5SDimitry Andric      [(set f128:$vT, (fneg (PPCfmarto f128:$vA, f128:$vB, f128:$vTi)))]>,
2890b57cec5SDimitry Andric      RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">,
2900b57cec5SDimitry Andric      AltVSXFMARel;
2910b57cec5SDimitry Andric
2920b57cec5SDimitry Andric      // xsnmsubqpo
2930b57cec5SDimitry Andric      [(set f128:$vT, (fneg (PPCfmarto f128:$vA, f128:$vB, (fneg f128:$vTi))))]>,
2940b57cec5SDimitry Andric      RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">,
2950b57cec5SDimitry Andric      AltVSXFMARel;
2960b57cec5SDimitry Andric
2970b57cec5SDimitry Andric- QP Compare Ordered/Unordered: xscmpoqp xscmpuqp
2980b57cec5SDimitry Andric  . ref: XSCMPUDP
2990b57cec5SDimitry Andric      def XSCMPUDP : XX3Form_1<60, 35,
3000b57cec5SDimitry Andric                               (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
3010b57cec5SDimitry Andric                               "xscmpudp $crD, $XA, $XB", IIC_FPCompare, []>;
3020b57cec5SDimitry Andric
3030b57cec5SDimitry Andric  . No SDAG, intrinsic, builtin are required??
3040b57cec5SDimitry Andric    Or llvm fcmp order/unorder compare??
3050b57cec5SDimitry Andric
3060b57cec5SDimitry Andric- DP/QP Compare Exponents: xscmpexpdp xscmpexpqp
3070b57cec5SDimitry Andric  . No SDAG, intrinsic, builtin are required?
3080b57cec5SDimitry Andric
3090b57cec5SDimitry Andric- DP Compare ==, >=, >, !=: xscmpeqdp xscmpgedp xscmpgtdp xscmpnedp
3100b57cec5SDimitry Andric  . I checked existing instruction "XSCMPUDP". They are different in target
3110b57cec5SDimitry Andric    register. "XSCMPUDP" write to CR field, xscmp*dp write to VSX register
3120b57cec5SDimitry Andric
31381ad6265SDimitry Andric  . Use intrinsic:
3140b57cec5SDimitry Andric    (set i128:$XT, (int_ppc_vsx_xscmpeqdp f64:$XA, f64:$XB))
3150b57cec5SDimitry Andric    (set i128:$XT, (int_ppc_vsx_xscmpgedp f64:$XA, f64:$XB))
3160b57cec5SDimitry Andric    (set i128:$XT, (int_ppc_vsx_xscmpgtdp f64:$XA, f64:$XB))
3170b57cec5SDimitry Andric    (set i128:$XT, (int_ppc_vsx_xscmpnedp f64:$XA, f64:$XB))
3180b57cec5SDimitry Andric
3190b57cec5SDimitry Andric- Vector Compare Not Equal: xvcmpnedp xvcmpnedp. xvcmpnesp xvcmpnesp.
3200b57cec5SDimitry Andric  . Similar to xvcmpeqdp:
3210b57cec5SDimitry Andric      defm XVCMPEQDP : XX3Form_Rcr<60, 99,
3220b57cec5SDimitry Andric                                 "xvcmpeqdp", "$XT, $XA, $XB", IIC_VecFPCompare,
3230b57cec5SDimitry Andric                                 int_ppc_vsx_xvcmpeqdp, v2i64, v2f64>;
3240b57cec5SDimitry Andric
32581ad6265SDimitry Andric  . So we should use "XX3Form_Rcr" to implement intrinsic
3260b57cec5SDimitry Andric
3270b57cec5SDimitry Andric- Convert DP -> QP: xscvdpqp
3280b57cec5SDimitry Andric  . Similar to XSCVDPSP:
3290b57cec5SDimitry Andric      def XSCVDPSP : XX2Form<60, 265,
3300b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XB),
3310b57cec5SDimitry Andric                          "xscvdpsp $XT, $XB", IIC_VecFP, []>;
3320b57cec5SDimitry Andric  . So, No SDAG, intrinsic, builtin are required??
3330b57cec5SDimitry Andric
3340b57cec5SDimitry Andric- Round & Convert QP -> DP (dword[1] is set to zero): xscvqpdp xscvqpdpo
3350b57cec5SDimitry Andric  . Similar to XSCVDPSP
3360b57cec5SDimitry Andric  . No SDAG, intrinsic, builtin are required??
3370b57cec5SDimitry Andric
3380b57cec5SDimitry Andric- Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero):
3390b57cec5SDimitry Andric  xscvqpsdz xscvqpswz xscvqpudz xscvqpuwz
3400b57cec5SDimitry Andric  . According to PowerISA_V3.0, these are similar to "XSCVDPSXDS", "XSCVDPSXWS",
3410b57cec5SDimitry Andric    "XSCVDPUXDS", "XSCVDPUXWS"
3420b57cec5SDimitry Andric
3430b57cec5SDimitry Andric  . DAG patterns:
3440b57cec5SDimitry Andric    (set f128:$XT, (PPCfctidz f128:$XB))    // xscvqpsdz
3450b57cec5SDimitry Andric    (set f128:$XT, (PPCfctiwz f128:$XB))    // xscvqpswz
3460b57cec5SDimitry Andric    (set f128:$XT, (PPCfctiduz f128:$XB))   // xscvqpudz
3470b57cec5SDimitry Andric    (set f128:$XT, (PPCfctiwuz f128:$XB))   // xscvqpuwz
3480b57cec5SDimitry Andric
3490b57cec5SDimitry Andric- Convert (Un)Signed DWord -> QP: xscvsdqp xscvudqp
3500b57cec5SDimitry Andric  . Similar to XSCVSXDSP
3510b57cec5SDimitry Andric  . (set f128:$XT, (PPCfcfids f64:$XB))     // xscvsdqp
3520b57cec5SDimitry Andric    (set f128:$XT, (PPCfcfidus f64:$XB))    // xscvudqp
3530b57cec5SDimitry Andric
3540b57cec5SDimitry Andric- (Round &) Convert DP <-> HP: xscvdphp xscvhpdp
3550b57cec5SDimitry Andric  . Similar to XSCVDPSP
3560b57cec5SDimitry Andric  . No SDAG, intrinsic, builtin are required??
3570b57cec5SDimitry Andric
3580b57cec5SDimitry Andric- Vector HP -> SP: xvcvhpsp xvcvsphp
3590b57cec5SDimitry Andric  . Similar to XVCVDPSP:
3600b57cec5SDimitry Andric      def XVCVDPSP : XX2Form<60, 393,
3610b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XB),
3620b57cec5SDimitry Andric                          "xvcvdpsp $XT, $XB", IIC_VecFP, []>;
3630b57cec5SDimitry Andric  . No SDAG, intrinsic, builtin are required??
3640b57cec5SDimitry Andric
3650b57cec5SDimitry Andric- Round to Quad-Precision Integer: xsrqpi xsrqpix
3660b57cec5SDimitry Andric  . These are combination of "XSRDPI", "XSRDPIC", "XSRDPIM", .., because you
3670b57cec5SDimitry Andric    need to assign rounding mode in instruction
3680b57cec5SDimitry Andric  . Provide builtin?
3690b57cec5SDimitry Andric    (set f128:$vT, (int_ppc_vsx_xsrqpi f128:$vB))
3700b57cec5SDimitry Andric    (set f128:$vT, (int_ppc_vsx_xsrqpix f128:$vB))
3710b57cec5SDimitry Andric
3720b57cec5SDimitry Andric- Round Quad-Precision to Double-Extended Precision (fp80): xsrqpxp
3730b57cec5SDimitry Andric  . Provide builtin?
3740b57cec5SDimitry Andric    (set f128:$vT, (int_ppc_vsx_xsrqpxp f128:$vB))
3750b57cec5SDimitry Andric
3760b57cec5SDimitry AndricFixed Point Facility:
3770b57cec5SDimitry Andric
3780b57cec5SDimitry Andric- Exploit cmprb and cmpeqb (perhaps for something like
3790b57cec5SDimitry Andric  isalpha/isdigit/isupper/islower and isspace respectivelly). This can
3800b57cec5SDimitry Andric  perhaps be done through a builtin.
3810b57cec5SDimitry Andric
3820b57cec5SDimitry Andric- Provide testing for cnttz[dw]
3830b57cec5SDimitry Andric- Insert Exponent DP/QP: xsiexpdp xsiexpqp
3840b57cec5SDimitry Andric  . Use intrinsic?
3850b57cec5SDimitry Andric  . xsiexpdp:
3860b57cec5SDimitry Andric    // Note: rA and rB are the unsigned integer value.
3870b57cec5SDimitry Andric    (set f128:$XT, (int_ppc_vsx_xsiexpdp i64:$rA, i64:$rB))
3880b57cec5SDimitry Andric
3890b57cec5SDimitry Andric  . xsiexpqp:
3900b57cec5SDimitry Andric    (set f128:$vT, (int_ppc_vsx_xsiexpqp f128:$vA, f64:$vB))
3910b57cec5SDimitry Andric
3920b57cec5SDimitry Andric- Extract Exponent/Significand DP/QP: xsxexpdp xsxsigdp xsxexpqp xsxsigqp
3930b57cec5SDimitry Andric  . Use intrinsic?
3940b57cec5SDimitry Andric  . (set i64:$rT, (int_ppc_vsx_xsxexpdp f64$XB))    // xsxexpdp
3950b57cec5SDimitry Andric    (set i64:$rT, (int_ppc_vsx_xsxsigdp f64$XB))    // xsxsigdp
3960b57cec5SDimitry Andric    (set f128:$vT, (int_ppc_vsx_xsxexpqp f128$vB))  // xsxexpqp
3970b57cec5SDimitry Andric    (set f128:$vT, (int_ppc_vsx_xsxsigqp f128$vB))  // xsxsigqp
3980b57cec5SDimitry Andric
3990b57cec5SDimitry Andric- Vector Insert Word: xxinsertw
4000b57cec5SDimitry Andric  - Useful for inserting f32/i32 elements into vectors (the element to be
4010b57cec5SDimitry Andric    inserted needs to be prepared)
4020b57cec5SDimitry Andric  . Note: llvm has insertelem in "Vector Operations"
4030b57cec5SDimitry Andric    ; yields <n x <ty>>
4040b57cec5SDimitry Andric    <result> = insertelement <n x <ty>> <val>, <ty> <elt>, <ty2> <idx>
4050b57cec5SDimitry Andric
4060b57cec5SDimitry Andric    But how to map to it??
4070b57cec5SDimitry Andric    [(set v1f128:$XT, (insertelement v1f128:$XTi, f128:$XB, i4:$UIMM))]>,
4080b57cec5SDimitry Andric    RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4090b57cec5SDimitry Andric
4100b57cec5SDimitry Andric  . Or use intrinsic?
4110b57cec5SDimitry Andric    (set v1f128:$XT, (int_ppc_vsx_xxinsertw v1f128:$XTi, f128:$XB, i4:$UIMM))
4120b57cec5SDimitry Andric
4130b57cec5SDimitry Andric- Vector Extract Unsigned Word: xxextractuw
4140b57cec5SDimitry Andric  - Not useful for extraction of f32 from v4f32 (the current pattern is better -
4150b57cec5SDimitry Andric    shift->convert)
4160b57cec5SDimitry Andric  - It is useful for (uint_to_fp (vector_extract v4i32, N))
4170b57cec5SDimitry Andric  - Unfortunately, it can't be used for (sint_to_fp (vector_extract v4i32, N))
4180b57cec5SDimitry Andric  . Note: llvm has extractelement in "Vector Operations"
4190b57cec5SDimitry Andric    ; yields <ty>
4200b57cec5SDimitry Andric    <result> = extractelement <n x <ty>> <val>, <ty2> <idx>
4210b57cec5SDimitry Andric
4220b57cec5SDimitry Andric    How to map to it??
4230b57cec5SDimitry Andric    [(set f128:$XT, (extractelement v1f128:$XB, i4:$UIMM))]
4240b57cec5SDimitry Andric
4250b57cec5SDimitry Andric  . Or use intrinsic?
4260b57cec5SDimitry Andric    (set f128:$XT, (int_ppc_vsx_xxextractuw v1f128:$XB, i4:$UIMM))
4270b57cec5SDimitry Andric
4280b57cec5SDimitry Andric- Vector Insert Exponent DP/SP: xviexpdp xviexpsp
4290b57cec5SDimitry Andric  . Use intrinsic
4300b57cec5SDimitry Andric    (set v2f64:$XT, (int_ppc_vsx_xviexpdp v2f64:$XA, v2f64:$XB))
4310b57cec5SDimitry Andric    (set v4f32:$XT, (int_ppc_vsx_xviexpsp v4f32:$XA, v4f32:$XB))
4320b57cec5SDimitry Andric
4330b57cec5SDimitry Andric- Vector Extract Exponent/Significand DP/SP: xvxexpdp xvxexpsp xvxsigdp xvxsigsp
4340b57cec5SDimitry Andric  . Use intrinsic
4350b57cec5SDimitry Andric    (set v2f64:$XT, (int_ppc_vsx_xvxexpdp v2f64:$XB))
4360b57cec5SDimitry Andric    (set v4f32:$XT, (int_ppc_vsx_xvxexpsp v4f32:$XB))
4370b57cec5SDimitry Andric    (set v2f64:$XT, (int_ppc_vsx_xvxsigdp v2f64:$XB))
4380b57cec5SDimitry Andric    (set v4f32:$XT, (int_ppc_vsx_xvxsigsp v4f32:$XB))
4390b57cec5SDimitry Andric
4400b57cec5SDimitry Andric- Test Data Class SP/DP/QP: xststdcsp xststdcdp xststdcqp
4410b57cec5SDimitry Andric  . No SDAG, intrinsic, builtin are required?
4420b57cec5SDimitry Andric    Because it seems that we have no way to map BF field?
4430b57cec5SDimitry Andric
4440b57cec5SDimitry Andric    Instruction Form: [PO T XO B XO BX TX]
4450b57cec5SDimitry Andric    Asm: xststd* BF,XB,DCMX
4460b57cec5SDimitry Andric
4470b57cec5SDimitry Andric    BF is an index to CR register field.
4480b57cec5SDimitry Andric
4490b57cec5SDimitry Andric- Vector Test Data Class SP/DP: xvtstdcsp xvtstdcdp
4500b57cec5SDimitry Andric  . Use intrinsic
4510b57cec5SDimitry Andric    (set v4f32:$XT, (int_ppc_vsx_xvtstdcsp v4f32:$XB, i7:$DCMX))
4520b57cec5SDimitry Andric    (set v2f64:$XT, (int_ppc_vsx_xvtstdcdp v2f64:$XB, i7:$DCMX))
4530b57cec5SDimitry Andric
4540b57cec5SDimitry Andric- Maximum/Minimum Type-C/Type-J DP: xsmaxcdp xsmaxjdp xsmincdp xsminjdp
4550b57cec5SDimitry Andric  . PowerISA_V3.0:
4560b57cec5SDimitry Andric    "xsmaxcdp can be used to implement the C/C++/Java conditional operation
4570b57cec5SDimitry Andric     (x>y)?x:y for single-precision and double-precision arguments."
4580b57cec5SDimitry Andric
4590b57cec5SDimitry Andric    Note! c type and j type have different behavior when:
4600b57cec5SDimitry Andric    1. Either input is NaN
4610b57cec5SDimitry Andric    2. Both input are +-Infinity, +-Zero
4620b57cec5SDimitry Andric
4630b57cec5SDimitry Andric  . dtype map to llvm fmaxnum/fminnum
4640b57cec5SDimitry Andric    jtype use intrinsic
4650b57cec5SDimitry Andric
4660b57cec5SDimitry Andric  . xsmaxcdp xsmincdp
4670b57cec5SDimitry Andric    (set f64:$XT, (fmaxnum f64:$XA, f64:$XB))
4680b57cec5SDimitry Andric    (set f64:$XT, (fminnum f64:$XA, f64:$XB))
4690b57cec5SDimitry Andric
4700b57cec5SDimitry Andric  . xsmaxjdp xsminjdp
4710b57cec5SDimitry Andric    (set f64:$XT, (int_ppc_vsx_xsmaxjdp f64:$XA, f64:$XB))
4720b57cec5SDimitry Andric    (set f64:$XT, (int_ppc_vsx_xsminjdp f64:$XA, f64:$XB))
4730b57cec5SDimitry Andric
4740b57cec5SDimitry Andric- Vector Byte-Reverse H/W/D/Q Word: xxbrh xxbrw xxbrd xxbrq
4750b57cec5SDimitry Andric  . Use intrinsic
4760b57cec5SDimitry Andric    (set v8i16:$XT, (int_ppc_vsx_xxbrh v8i16:$XB))
4770b57cec5SDimitry Andric    (set v4i32:$XT, (int_ppc_vsx_xxbrw v4i32:$XB))
4780b57cec5SDimitry Andric    (set v2i64:$XT, (int_ppc_vsx_xxbrd v2i64:$XB))
4790b57cec5SDimitry Andric    (set v1i128:$XT, (int_ppc_vsx_xxbrq v1i128:$XB))
4800b57cec5SDimitry Andric
4810b57cec5SDimitry Andric- Vector Permute: xxperm xxpermr
4820b57cec5SDimitry Andric  . I have checked "PPCxxswapd" in PPCInstrVSX.td, but they are different
4830b57cec5SDimitry Andric  . Use intrinsic
4840b57cec5SDimitry Andric    (set v16i8:$XT, (int_ppc_vsx_xxperm v16i8:$XA, v16i8:$XB))
4850b57cec5SDimitry Andric    (set v16i8:$XT, (int_ppc_vsx_xxpermr v16i8:$XA, v16i8:$XB))
4860b57cec5SDimitry Andric
4870b57cec5SDimitry Andric- Vector Splat Immediate Byte: xxspltib
4880b57cec5SDimitry Andric  . Similar to XXSPLTW:
4890b57cec5SDimitry Andric      def XXSPLTW : XX2Form_2<60, 164,
4900b57cec5SDimitry Andric                           (outs vsrc:$XT), (ins vsrc:$XB, u2imm:$UIM),
4910b57cec5SDimitry Andric                           "xxspltw $XT, $XB, $UIM", IIC_VecPerm, []>;
4920b57cec5SDimitry Andric
4930b57cec5SDimitry Andric  . No SDAG, intrinsic, builtin are required?
4940b57cec5SDimitry Andric
4950b57cec5SDimitry Andric- Load/Store Vector: lxv stxv
4960b57cec5SDimitry Andric  . Has likely SDAG match:
4970b57cec5SDimitry Andric    (set v?:$XT, (load ix16addr:$src))
4980b57cec5SDimitry Andric    (set v?:$XT, (store ix16addr:$dst))
4990b57cec5SDimitry Andric
5000b57cec5SDimitry Andric  . Need define ix16addr in PPCInstrInfo.td
5010b57cec5SDimitry Andric    ix16addr: 16-byte aligned, see "def memrix16" in PPCInstrInfo.td
5020b57cec5SDimitry Andric
5030b57cec5SDimitry Andric- Load/Store Vector Indexed: lxvx stxvx
5040b57cec5SDimitry Andric  . Has likely SDAG match:
5050b57cec5SDimitry Andric    (set v?:$XT, (load xoaddr:$src))
5060b57cec5SDimitry Andric    (set v?:$XT, (store xoaddr:$dst))
5070b57cec5SDimitry Andric
5080b57cec5SDimitry Andric- Load/Store DWord: lxsd stxsd
5090b57cec5SDimitry Andric  . Similar to lxsdx/stxsdx:
5100b57cec5SDimitry Andric    def LXSDX : XX1Form<31, 588,
5110b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins memrr:$src),
5120b57cec5SDimitry Andric                        "lxsdx $XT, $src", IIC_LdStLFD,
5130b57cec5SDimitry Andric                        [(set f64:$XT, (load xoaddr:$src))]>;
5140b57cec5SDimitry Andric
5150b57cec5SDimitry Andric  . (set f64:$XT, (load iaddrX4:$src))
5160b57cec5SDimitry Andric    (set f64:$XT, (store iaddrX4:$dst))
5170b57cec5SDimitry Andric
5180b57cec5SDimitry Andric- Load/Store SP, with conversion from/to DP: lxssp stxssp
5190b57cec5SDimitry Andric  . Similar to lxsspx/stxsspx:
5200b57cec5SDimitry Andric    def LXSSPX : XX1Form<31, 524, (outs vssrc:$XT), (ins memrr:$src),
5210b57cec5SDimitry Andric                         "lxsspx $XT, $src", IIC_LdStLFD,
5220b57cec5SDimitry Andric                         [(set f32:$XT, (load xoaddr:$src))]>;
5230b57cec5SDimitry Andric
5240b57cec5SDimitry Andric  . (set f32:$XT, (load iaddrX4:$src))
5250b57cec5SDimitry Andric    (set f32:$XT, (store iaddrX4:$dst))
5260b57cec5SDimitry Andric
5270b57cec5SDimitry Andric- Load as Integer Byte/Halfword & Zero Indexed: lxsibzx lxsihzx
5280b57cec5SDimitry Andric  . Similar to lxsiwzx:
5290b57cec5SDimitry Andric    def LXSIWZX : XX1Form<31, 12, (outs vsfrc:$XT), (ins memrr:$src),
5300b57cec5SDimitry Andric                          "lxsiwzx $XT, $src", IIC_LdStLFD,
5310b57cec5SDimitry Andric                          [(set f64:$XT, (PPClfiwzx xoaddr:$src))]>;
5320b57cec5SDimitry Andric
5330b57cec5SDimitry Andric  . (set f64:$XT, (PPClfiwzx xoaddr:$src))
5340b57cec5SDimitry Andric
5350b57cec5SDimitry Andric- Store as Integer Byte/Halfword Indexed: stxsibx stxsihx
5360b57cec5SDimitry Andric  . Similar to stxsiwx:
5370b57cec5SDimitry Andric    def STXSIWX : XX1Form<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst),
5380b57cec5SDimitry Andric                          "stxsiwx $XT, $dst", IIC_LdStSTFD,
5390b57cec5SDimitry Andric                          [(PPCstfiwx f64:$XT, xoaddr:$dst)]>;
5400b57cec5SDimitry Andric
5410b57cec5SDimitry Andric  . (PPCstfiwx f64:$XT, xoaddr:$dst)
5420b57cec5SDimitry Andric
5430b57cec5SDimitry Andric- Load Vector Halfword*8/Byte*16 Indexed: lxvh8x lxvb16x
5440b57cec5SDimitry Andric  . Similar to lxvd2x/lxvw4x:
5450b57cec5SDimitry Andric    def LXVD2X : XX1Form<31, 844,
5460b57cec5SDimitry Andric                         (outs vsrc:$XT), (ins memrr:$src),
5470b57cec5SDimitry Andric                         "lxvd2x $XT, $src", IIC_LdStLFD,
5480b57cec5SDimitry Andric                         [(set v2f64:$XT, (int_ppc_vsx_lxvd2x xoaddr:$src))]>;
5490b57cec5SDimitry Andric
5500b57cec5SDimitry Andric  . (set v8i16:$XT, (int_ppc_vsx_lxvh8x xoaddr:$src))
5510b57cec5SDimitry Andric    (set v16i8:$XT, (int_ppc_vsx_lxvb16x xoaddr:$src))
5520b57cec5SDimitry Andric
5530b57cec5SDimitry Andric- Store Vector Halfword*8/Byte*16 Indexed: stxvh8x stxvb16x
5540b57cec5SDimitry Andric  . Similar to stxvd2x/stxvw4x:
5550b57cec5SDimitry Andric    def STXVD2X : XX1Form<31, 972,
5560b57cec5SDimitry Andric                         (outs), (ins vsrc:$XT, memrr:$dst),
5570b57cec5SDimitry Andric                         "stxvd2x $XT, $dst", IIC_LdStSTFD,
5580b57cec5SDimitry Andric                         [(store v2f64:$XT, xoaddr:$dst)]>;
5590b57cec5SDimitry Andric
5600b57cec5SDimitry Andric  . (store v8i16:$XT, xoaddr:$dst)
5610b57cec5SDimitry Andric    (store v16i8:$XT, xoaddr:$dst)
5620b57cec5SDimitry Andric
5630b57cec5SDimitry Andric- Load/Store Vector (Left-justified) with Length: lxvl lxvll stxvl stxvll
5640b57cec5SDimitry Andric  . Likely needs an intrinsic
5650b57cec5SDimitry Andric  . (set v?:$XT, (int_ppc_vsx_lxvl xoaddr:$src))
5660b57cec5SDimitry Andric    (set v?:$XT, (int_ppc_vsx_lxvll xoaddr:$src))
5670b57cec5SDimitry Andric
5680b57cec5SDimitry Andric  . (int_ppc_vsx_stxvl xoaddr:$dst))
5690b57cec5SDimitry Andric    (int_ppc_vsx_stxvll xoaddr:$dst))
5700b57cec5SDimitry Andric
5710b57cec5SDimitry Andric- Load Vector Word & Splat Indexed: lxvwsx
5720b57cec5SDimitry Andric  . Likely needs an intrinsic
5730b57cec5SDimitry Andric  . (set v?:$XT, (int_ppc_vsx_lxvwsx xoaddr:$src))
5740b57cec5SDimitry Andric
5750b57cec5SDimitry AndricAtomic operations (l[dw]at, st[dw]at):
5760b57cec5SDimitry Andric- Provide custom lowering for common atomic operations to use these
5770b57cec5SDimitry Andric  instructions with the correct Function Code
5780b57cec5SDimitry Andric- Ensure the operands are in the correct register (i.e. RT+1, RT+2)
5790b57cec5SDimitry Andric- Provide builtins since not all FC's necessarily have an existing LLVM
5800b57cec5SDimitry Andric  atomic operation
5810b57cec5SDimitry Andric
5820b57cec5SDimitry AndricMove to CR from XER Extended (mcrxrx):
5830b57cec5SDimitry Andric- Is there a use for this in LLVM?
5840b57cec5SDimitry Andric
5850b57cec5SDimitry AndricFixed Point Facility:
5860b57cec5SDimitry Andric
5870b57cec5SDimitry Andric- Copy-Paste Facility: copy copy_first cp_abort paste paste. paste_last
5880b57cec5SDimitry Andric  . Use instrinstics:
5890b57cec5SDimitry Andric    (int_ppc_copy_first i32:$rA, i32:$rB)
5900b57cec5SDimitry Andric    (int_ppc_copy i32:$rA, i32:$rB)
5910b57cec5SDimitry Andric
5920b57cec5SDimitry Andric    (int_ppc_paste i32:$rA, i32:$rB)
5930b57cec5SDimitry Andric    (int_ppc_paste_last i32:$rA, i32:$rB)
5940b57cec5SDimitry Andric
5950b57cec5SDimitry Andric    (int_cp_abort)
5960b57cec5SDimitry Andric
5970b57cec5SDimitry Andric- Message Synchronize: msgsync
5980b57cec5SDimitry Andric- SLB*: slbieg slbsync
5990b57cec5SDimitry Andric- stop
6000b57cec5SDimitry Andric  . No instrinstics
601