1*06f32e7eSjoerg//===- README_P9.txt - Notes for improving Power9 code gen ----------------===//
2*06f32e7eSjoerg
3*06f32e7eSjoergTODO: Instructions Need Implement Instrinstics or Map to LLVM IR
4*06f32e7eSjoerg
5*06f32e7eSjoergAltivec:
6*06f32e7eSjoerg- Vector Compare Not Equal (Zero):
7*06f32e7eSjoerg  vcmpneb(.) vcmpneh(.) vcmpnew(.)
8*06f32e7eSjoerg  vcmpnezb(.) vcmpnezh(.) vcmpnezw(.)
9*06f32e7eSjoerg  . Same as other VCMP*, use VCMP/VCMPo form (support intrinsic)
10*06f32e7eSjoerg
11*06f32e7eSjoerg- Vector Extract Unsigned: vextractub vextractuh vextractuw vextractd
12*06f32e7eSjoerg  . Don't use llvm extractelement because they have different semantics
13*06f32e7eSjoerg  . Use instrinstics:
14*06f32e7eSjoerg    (set v2i64:$vD, (int_ppc_altivec_vextractub v16i8:$vA, imm:$UIMM))
15*06f32e7eSjoerg    (set v2i64:$vD, (int_ppc_altivec_vextractuh v8i16:$vA, imm:$UIMM))
16*06f32e7eSjoerg    (set v2i64:$vD, (int_ppc_altivec_vextractuw v4i32:$vA, imm:$UIMM))
17*06f32e7eSjoerg    (set v2i64:$vD, (int_ppc_altivec_vextractd  v2i64:$vA, imm:$UIMM))
18*06f32e7eSjoerg
19*06f32e7eSjoerg- Vector Extract Unsigned Byte Left/Right-Indexed:
20*06f32e7eSjoerg  vextublx vextubrx vextuhlx vextuhrx vextuwlx vextuwrx
21*06f32e7eSjoerg  . Use instrinstics:
22*06f32e7eSjoerg    // Left-Indexed
23*06f32e7eSjoerg    (set i64:$rD, (int_ppc_altivec_vextublx i64:$rA, v16i8:$vB))
24*06f32e7eSjoerg    (set i64:$rD, (int_ppc_altivec_vextuhlx i64:$rA, v8i16:$vB))
25*06f32e7eSjoerg    (set i64:$rD, (int_ppc_altivec_vextuwlx i64:$rA, v4i32:$vB))
26*06f32e7eSjoerg
27*06f32e7eSjoerg    // Right-Indexed
28*06f32e7eSjoerg    (set i64:$rD, (int_ppc_altivec_vextubrx i64:$rA, v16i8:$vB))
29*06f32e7eSjoerg    (set i64:$rD, (int_ppc_altivec_vextuhrx i64:$rA, v8i16:$vB))
30*06f32e7eSjoerg    (set i64:$rD, (int_ppc_altivec_vextuwrx i64:$rA, v4i32:$vB))
31*06f32e7eSjoerg
32*06f32e7eSjoerg- Vector Insert Element Instructions: vinsertb vinsertd vinserth vinsertw
33*06f32e7eSjoerg    (set v16i8:$vD, (int_ppc_altivec_vinsertb v16i8:$vA, imm:$UIMM))
34*06f32e7eSjoerg    (set v8i16:$vD, (int_ppc_altivec_vinsertd v8i16:$vA, imm:$UIMM))
35*06f32e7eSjoerg    (set v4i32:$vD, (int_ppc_altivec_vinserth v4i32:$vA, imm:$UIMM))
36*06f32e7eSjoerg    (set v2i64:$vD, (int_ppc_altivec_vinsertw v2i64:$vA, imm:$UIMM))
37*06f32e7eSjoerg
38*06f32e7eSjoerg- Vector Count Leading/Trailing Zero LSB. Result is placed into GPR[rD]:
39*06f32e7eSjoerg  vclzlsbb vctzlsbb
40*06f32e7eSjoerg  . Use intrinsic:
41*06f32e7eSjoerg    (set i64:$rD, (int_ppc_altivec_vclzlsbb v16i8:$vB))
42*06f32e7eSjoerg    (set i64:$rD, (int_ppc_altivec_vctzlsbb v16i8:$vB))
43*06f32e7eSjoerg
44*06f32e7eSjoerg- Vector Count Trailing Zeros: vctzb vctzh vctzw vctzd
45*06f32e7eSjoerg  . Map to llvm cttz
46*06f32e7eSjoerg    (set v16i8:$vD, (cttz v16i8:$vB))     // vctzb
47*06f32e7eSjoerg    (set v8i16:$vD, (cttz v8i16:$vB))     // vctzh
48*06f32e7eSjoerg    (set v4i32:$vD, (cttz v4i32:$vB))     // vctzw
49*06f32e7eSjoerg    (set v2i64:$vD, (cttz v2i64:$vB))     // vctzd
50*06f32e7eSjoerg
51*06f32e7eSjoerg- Vector Extend Sign: vextsb2w vextsh2w vextsb2d vextsh2d vextsw2d
52*06f32e7eSjoerg  . vextsb2w:
53*06f32e7eSjoerg    (set v4i32:$vD, (sext v4i8:$vB))
54*06f32e7eSjoerg
55*06f32e7eSjoerg    // PowerISA_V3.0:
56*06f32e7eSjoerg    do i = 0 to 3
57*06f32e7eSjoerg       VR[VRT].word[i] ← EXTS32(VR[VRB].word[i].byte[3])
58*06f32e7eSjoerg    end
59*06f32e7eSjoerg
60*06f32e7eSjoerg  . vextsh2w:
61*06f32e7eSjoerg    (set v4i32:$vD, (sext v4i16:$vB))
62*06f32e7eSjoerg
63*06f32e7eSjoerg    // PowerISA_V3.0:
64*06f32e7eSjoerg    do i = 0 to 3
65*06f32e7eSjoerg       VR[VRT].word[i] ← EXTS32(VR[VRB].word[i].hword[1])
66*06f32e7eSjoerg    end
67*06f32e7eSjoerg
68*06f32e7eSjoerg  . vextsb2d
69*06f32e7eSjoerg    (set v2i64:$vD, (sext v2i8:$vB))
70*06f32e7eSjoerg
71*06f32e7eSjoerg    // PowerISA_V3.0:
72*06f32e7eSjoerg    do i = 0 to 1
73*06f32e7eSjoerg       VR[VRT].dword[i] ← EXTS64(VR[VRB].dword[i].byte[7])
74*06f32e7eSjoerg    end
75*06f32e7eSjoerg
76*06f32e7eSjoerg  . vextsh2d
77*06f32e7eSjoerg    (set v2i64:$vD, (sext v2i16:$vB))
78*06f32e7eSjoerg
79*06f32e7eSjoerg    // PowerISA_V3.0:
80*06f32e7eSjoerg    do i = 0 to 1
81*06f32e7eSjoerg       VR[VRT].dword[i] ← EXTS64(VR[VRB].dword[i].hword[3])
82*06f32e7eSjoerg    end
83*06f32e7eSjoerg
84*06f32e7eSjoerg  . vextsw2d
85*06f32e7eSjoerg    (set v2i64:$vD, (sext v2i32:$vB))
86*06f32e7eSjoerg
87*06f32e7eSjoerg    // PowerISA_V3.0:
88*06f32e7eSjoerg    do i = 0 to 1
89*06f32e7eSjoerg       VR[VRT].dword[i] ← EXTS64(VR[VRB].dword[i].word[1])
90*06f32e7eSjoerg    end
91*06f32e7eSjoerg
92*06f32e7eSjoerg- Vector Integer Negate: vnegw vnegd
93*06f32e7eSjoerg  . Map to llvm ineg
94*06f32e7eSjoerg    (set v4i32:$rT, (ineg v4i32:$rA))       // vnegw
95*06f32e7eSjoerg    (set v2i64:$rT, (ineg v2i64:$rA))       // vnegd
96*06f32e7eSjoerg
97*06f32e7eSjoerg- Vector Parity Byte: vprtybw vprtybd vprtybq
98*06f32e7eSjoerg  . Use intrinsic:
99*06f32e7eSjoerg    (set v4i32:$rD, (int_ppc_altivec_vprtybw v4i32:$vB))
100*06f32e7eSjoerg    (set v2i64:$rD, (int_ppc_altivec_vprtybd v2i64:$vB))
101*06f32e7eSjoerg    (set v1i128:$rD, (int_ppc_altivec_vprtybq v1i128:$vB))
102*06f32e7eSjoerg
103*06f32e7eSjoerg- Vector (Bit) Permute (Right-indexed):
104*06f32e7eSjoerg  . vbpermd: Same as "vbpermq", use VX1_Int_Ty2:
105*06f32e7eSjoerg    VX1_Int_Ty2<1484, "vbpermd", int_ppc_altivec_vbpermd, v2i64, v2i64>;
106*06f32e7eSjoerg
107*06f32e7eSjoerg  . vpermr: use VA1a_Int_Ty3
108*06f32e7eSjoerg    VA1a_Int_Ty3<59, "vpermr", int_ppc_altivec_vpermr, v16i8, v16i8, v16i8>;
109*06f32e7eSjoerg
110*06f32e7eSjoerg- Vector Rotate Left Mask/Mask-Insert: vrlwnm vrlwmi vrldnm vrldmi
111*06f32e7eSjoerg  . Use intrinsic:
112*06f32e7eSjoerg    VX1_Int_Ty<389, "vrlwnm", int_ppc_altivec_vrlwnm, v4i32>;
113*06f32e7eSjoerg    VX1_Int_Ty<133, "vrlwmi", int_ppc_altivec_vrlwmi, v4i32>;
114*06f32e7eSjoerg    VX1_Int_Ty<453, "vrldnm", int_ppc_altivec_vrldnm, v2i64>;
115*06f32e7eSjoerg    VX1_Int_Ty<197, "vrldmi", int_ppc_altivec_vrldmi, v2i64>;
116*06f32e7eSjoerg
117*06f32e7eSjoerg- Vector Shift Left/Right: vslv vsrv
118*06f32e7eSjoerg  . Use intrinsic, don't map to llvm shl and lshr, because they have different
119*06f32e7eSjoerg    semantics, e.g. vslv:
120*06f32e7eSjoerg
121*06f32e7eSjoerg      do i = 0 to 15
122*06f32e7eSjoerg         sh ← VR[VRB].byte[i].bit[5:7]
123*06f32e7eSjoerg         VR[VRT].byte[i] ← src.byte[i:i+1].bit[sh:sh+7]
124*06f32e7eSjoerg      end
125*06f32e7eSjoerg
126*06f32e7eSjoerg    VR[VRT].byte[i] is composed of 2 bytes from src.byte[i:i+1]
127*06f32e7eSjoerg
128*06f32e7eSjoerg  . VX1_Int_Ty<1860, "vslv", int_ppc_altivec_vslv, v16i8>;
129*06f32e7eSjoerg    VX1_Int_Ty<1796, "vsrv", int_ppc_altivec_vsrv, v16i8>;
130*06f32e7eSjoerg
131*06f32e7eSjoerg- Vector Multiply-by-10 (& Write Carry) Unsigned Quadword:
132*06f32e7eSjoerg  vmul10uq vmul10cuq
133*06f32e7eSjoerg  . Use intrinsic:
134*06f32e7eSjoerg    VX1_Int_Ty<513, "vmul10uq",   int_ppc_altivec_vmul10uq,  v1i128>;
135*06f32e7eSjoerg    VX1_Int_Ty<  1, "vmul10cuq",  int_ppc_altivec_vmul10cuq, v1i128>;
136*06f32e7eSjoerg
137*06f32e7eSjoerg- Vector Multiply-by-10 Extended (& Write Carry) Unsigned Quadword:
138*06f32e7eSjoerg  vmul10euq vmul10ecuq
139*06f32e7eSjoerg  . Use intrinsic:
140*06f32e7eSjoerg    VX1_Int_Ty<577, "vmul10euq",  int_ppc_altivec_vmul10euq, v1i128>;
141*06f32e7eSjoerg    VX1_Int_Ty< 65, "vmul10ecuq", int_ppc_altivec_vmul10ecuq, v1i128>;
142*06f32e7eSjoerg
143*06f32e7eSjoerg- Decimal Convert From/to National/Zoned/Signed-QWord:
144*06f32e7eSjoerg  bcdcfn. bcdcfz. bcdctn. bcdctz. bcdcfsq. bcdctsq.
145*06f32e7eSjoerg  . Use instrinstics:
146*06f32e7eSjoerg    (set v1i128:$vD, (int_ppc_altivec_bcdcfno  v1i128:$vB, i1:$PS))
147*06f32e7eSjoerg    (set v1i128:$vD, (int_ppc_altivec_bcdcfzo  v1i128:$vB, i1:$PS))
148*06f32e7eSjoerg    (set v1i128:$vD, (int_ppc_altivec_bcdctno  v1i128:$vB))
149*06f32e7eSjoerg    (set v1i128:$vD, (int_ppc_altivec_bcdctzo  v1i128:$vB, i1:$PS))
150*06f32e7eSjoerg    (set v1i128:$vD, (int_ppc_altivec_bcdcfsqo v1i128:$vB, i1:$PS))
151*06f32e7eSjoerg    (set v1i128:$vD, (int_ppc_altivec_bcdctsqo v1i128:$vB))
152*06f32e7eSjoerg
153*06f32e7eSjoerg- Decimal Copy-Sign/Set-Sign: bcdcpsgn. bcdsetsgn.
154*06f32e7eSjoerg  . Use instrinstics:
155*06f32e7eSjoerg    (set v1i128:$vD, (int_ppc_altivec_bcdcpsgno v1i128:$vA, v1i128:$vB))
156*06f32e7eSjoerg    (set v1i128:$vD, (int_ppc_altivec_bcdsetsgno v1i128:$vB, i1:$PS))
157*06f32e7eSjoerg
158*06f32e7eSjoerg- Decimal Shift/Unsigned-Shift/Shift-and-Round: bcds. bcdus. bcdsr.
159*06f32e7eSjoerg  . Use instrinstics:
160*06f32e7eSjoerg    (set v1i128:$vD, (int_ppc_altivec_bcdso  v1i128:$vA, v1i128:$vB, i1:$PS))
161*06f32e7eSjoerg    (set v1i128:$vD, (int_ppc_altivec_bcduso v1i128:$vA, v1i128:$vB))
162*06f32e7eSjoerg    (set v1i128:$vD, (int_ppc_altivec_bcdsro v1i128:$vA, v1i128:$vB, i1:$PS))
163*06f32e7eSjoerg
164*06f32e7eSjoerg  . Note! Their VA is accessed only 1 byte, i.e. VA.byte[7]
165*06f32e7eSjoerg
166*06f32e7eSjoerg- Decimal (Unsigned) Truncate: bcdtrunc. bcdutrunc.
167*06f32e7eSjoerg  . Use instrinstics:
168*06f32e7eSjoerg    (set v1i128:$vD, (int_ppc_altivec_bcdso  v1i128:$vA, v1i128:$vB, i1:$PS))
169*06f32e7eSjoerg    (set v1i128:$vD, (int_ppc_altivec_bcduso v1i128:$vA, v1i128:$vB))
170*06f32e7eSjoerg
171*06f32e7eSjoerg  . Note! Their VA is accessed only 2 byte, i.e. VA.hword[3] (VA.bit[48:63])
172*06f32e7eSjoerg
173*06f32e7eSjoergVSX:
174*06f32e7eSjoerg- QP Copy Sign: xscpsgnqp
175*06f32e7eSjoerg  . Similar to xscpsgndp
176*06f32e7eSjoerg  . (set f128:$vT, (fcopysign f128:$vB, f128:$vA)
177*06f32e7eSjoerg
178*06f32e7eSjoerg- QP Absolute/Negative-Absolute/Negate: xsabsqp xsnabsqp xsnegqp
179*06f32e7eSjoerg  . Similar to xsabsdp/xsnabsdp/xsnegdp
180*06f32e7eSjoerg  . (set f128:$vT, (fabs f128:$vB))             // xsabsqp
181*06f32e7eSjoerg    (set f128:$vT, (fneg (fabs f128:$vB)))      // xsnabsqp
182*06f32e7eSjoerg    (set f128:$vT, (fneg f128:$vB))             // xsnegqp
183*06f32e7eSjoerg
184*06f32e7eSjoerg- QP Add/Divide/Multiply/Subtract/Square-Root:
185*06f32e7eSjoerg  xsaddqp xsdivqp xsmulqp xssubqp xssqrtqp
186*06f32e7eSjoerg  . Similar to xsadddp
187*06f32e7eSjoerg  . isCommutable = 1
188*06f32e7eSjoerg    (set f128:$vT, (fadd f128:$vA, f128:$vB))   // xsaddqp
189*06f32e7eSjoerg    (set f128:$vT, (fmul f128:$vA, f128:$vB))   // xsmulqp
190*06f32e7eSjoerg
191*06f32e7eSjoerg  . isCommutable = 0
192*06f32e7eSjoerg    (set f128:$vT, (fdiv f128:$vA, f128:$vB))   // xsdivqp
193*06f32e7eSjoerg    (set f128:$vT, (fsub f128:$vA, f128:$vB))   // xssubqp
194*06f32e7eSjoerg    (set f128:$vT, (fsqrt f128:$vB)))           // xssqrtqp
195*06f32e7eSjoerg
196*06f32e7eSjoerg- Round to Odd of QP Add/Divide/Multiply/Subtract/Square-Root:
197*06f32e7eSjoerg  xsaddqpo xsdivqpo xsmulqpo xssubqpo xssqrtqpo
198*06f32e7eSjoerg  . Similar to xsrsqrtedp??
199*06f32e7eSjoerg      def XSRSQRTEDP : XX2Form<60, 74,
200*06f32e7eSjoerg                               (outs vsfrc:$XT), (ins vsfrc:$XB),
201*06f32e7eSjoerg                               "xsrsqrtedp $XT, $XB", IIC_VecFP,
202*06f32e7eSjoerg                               [(set f64:$XT, (PPCfrsqrte f64:$XB))]>;
203*06f32e7eSjoerg
204*06f32e7eSjoerg  . Define DAG Node in PPCInstrInfo.td:
205*06f32e7eSjoerg    def PPCfaddrto: SDNode<"PPCISD::FADDRTO", SDTFPBinOp, []>;
206*06f32e7eSjoerg    def PPCfdivrto: SDNode<"PPCISD::FDIVRTO", SDTFPBinOp, []>;
207*06f32e7eSjoerg    def PPCfmulrto: SDNode<"PPCISD::FMULRTO", SDTFPBinOp, []>;
208*06f32e7eSjoerg    def PPCfsubrto: SDNode<"PPCISD::FSUBRTO", SDTFPBinOp, []>;
209*06f32e7eSjoerg    def PPCfsqrtrto: SDNode<"PPCISD::FSQRTRTO", SDTFPUnaryOp, []>;
210*06f32e7eSjoerg
211*06f32e7eSjoerg    DAG patterns of each instruction (PPCInstrVSX.td):
212*06f32e7eSjoerg    . isCommutable = 1
213*06f32e7eSjoerg      (set f128:$vT, (PPCfaddrto f128:$vA, f128:$vB))   // xsaddqpo
214*06f32e7eSjoerg      (set f128:$vT, (PPCfmulrto f128:$vA, f128:$vB))   // xsmulqpo
215*06f32e7eSjoerg
216*06f32e7eSjoerg    . isCommutable = 0
217*06f32e7eSjoerg      (set f128:$vT, (PPCfdivrto f128:$vA, f128:$vB))   // xsdivqpo
218*06f32e7eSjoerg      (set f128:$vT, (PPCfsubrto f128:$vA, f128:$vB))   // xssubqpo
219*06f32e7eSjoerg      (set f128:$vT, (PPCfsqrtrto f128:$vB))            // xssqrtqpo
220*06f32e7eSjoerg
221*06f32e7eSjoerg- QP (Negative) Multiply-{Add/Subtract}: xsmaddqp xsmsubqp xsnmaddqp xsnmsubqp
222*06f32e7eSjoerg  . Ref: xsmaddadp/xsmsubadp/xsnmaddadp/xsnmsubadp
223*06f32e7eSjoerg
224*06f32e7eSjoerg  . isCommutable = 1
225*06f32e7eSjoerg    // xsmaddqp
226*06f32e7eSjoerg    [(set f128:$vT, (fma f128:$vA, f128:$vB, f128:$vTi))]>,
227*06f32e7eSjoerg    RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">,
228*06f32e7eSjoerg    AltVSXFMARel;
229*06f32e7eSjoerg
230*06f32e7eSjoerg    // xsmsubqp
231*06f32e7eSjoerg    [(set f128:$vT, (fma f128:$vA, f128:$vB, (fneg f128:$vTi)))]>,
232*06f32e7eSjoerg    RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">,
233*06f32e7eSjoerg    AltVSXFMARel;
234*06f32e7eSjoerg
235*06f32e7eSjoerg    // xsnmaddqp
236*06f32e7eSjoerg    [(set f128:$vT, (fneg (fma f128:$vA, f128:$vB, f128:$vTi)))]>,
237*06f32e7eSjoerg    RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">,
238*06f32e7eSjoerg    AltVSXFMARel;
239*06f32e7eSjoerg
240*06f32e7eSjoerg    // xsnmsubqp
241*06f32e7eSjoerg    [(set f128:$vT, (fneg (fma f128:$vA, f128:$vB, (fneg f128:$vTi))))]>,
242*06f32e7eSjoerg    RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">,
243*06f32e7eSjoerg    AltVSXFMARel;
244*06f32e7eSjoerg
245*06f32e7eSjoerg- Round to Odd of QP (Negative) Multiply-{Add/Subtract}:
246*06f32e7eSjoerg  xsmaddqpo xsmsubqpo xsnmaddqpo xsnmsubqpo
247*06f32e7eSjoerg  . Similar to xsrsqrtedp??
248*06f32e7eSjoerg
249*06f32e7eSjoerg  . Define DAG Node in PPCInstrInfo.td:
250*06f32e7eSjoerg    def PPCfmarto: SDNode<"PPCISD::FMARTO", SDTFPTernaryOp, []>;
251*06f32e7eSjoerg
252*06f32e7eSjoerg    It looks like we only need to define "PPCfmarto" for these instructions,
253*06f32e7eSjoerg    because according to PowerISA_V3.0, these instructions perform RTO on
254*06f32e7eSjoerg    fma's result:
255*06f32e7eSjoerg        xsmaddqp(o)
256*06f32e7eSjoerg        v      ← bfp_MULTIPLY_ADD(src1, src3, src2)
257*06f32e7eSjoerg        rnd    ← bfp_ROUND_TO_BFP128(RO, FPSCR.RN, v)
258*06f32e7eSjoerg        result ← bfp_CONVERT_TO_BFP128(rnd)
259*06f32e7eSjoerg
260*06f32e7eSjoerg        xsmsubqp(o)
261*06f32e7eSjoerg        v      ← bfp_MULTIPLY_ADD(src1, src3, bfp_NEGATE(src2))
262*06f32e7eSjoerg        rnd    ← bfp_ROUND_TO_BFP128(RO, FPSCR.RN, v)
263*06f32e7eSjoerg        result ← bfp_CONVERT_TO_BFP128(rnd)
264*06f32e7eSjoerg
265*06f32e7eSjoerg        xsnmaddqp(o)
266*06f32e7eSjoerg        v      ← bfp_MULTIPLY_ADD(src1,src3,src2)
267*06f32e7eSjoerg        rnd    ← bfp_NEGATE(bfp_ROUND_TO_BFP128(RO, FPSCR.RN, v))
268*06f32e7eSjoerg        result ← bfp_CONVERT_TO_BFP128(rnd)
269*06f32e7eSjoerg
270*06f32e7eSjoerg        xsnmsubqp(o)
271*06f32e7eSjoerg        v      ← bfp_MULTIPLY_ADD(src1, src3, bfp_NEGATE(src2))
272*06f32e7eSjoerg        rnd    ← bfp_NEGATE(bfp_ROUND_TO_BFP128(RO, FPSCR.RN, v))
273*06f32e7eSjoerg        result ← bfp_CONVERT_TO_BFP128(rnd)
274*06f32e7eSjoerg
275*06f32e7eSjoerg    DAG patterns of each instruction (PPCInstrVSX.td):
276*06f32e7eSjoerg    . isCommutable = 1
277*06f32e7eSjoerg      // xsmaddqpo
278*06f32e7eSjoerg      [(set f128:$vT, (PPCfmarto f128:$vA, f128:$vB, f128:$vTi))]>,
279*06f32e7eSjoerg      RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">,
280*06f32e7eSjoerg      AltVSXFMARel;
281*06f32e7eSjoerg
282*06f32e7eSjoerg      // xsmsubqpo
283*06f32e7eSjoerg      [(set f128:$vT, (PPCfmarto f128:$vA, f128:$vB, (fneg f128:$vTi)))]>,
284*06f32e7eSjoerg      RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">,
285*06f32e7eSjoerg      AltVSXFMARel;
286*06f32e7eSjoerg
287*06f32e7eSjoerg      // xsnmaddqpo
288*06f32e7eSjoerg      [(set f128:$vT, (fneg (PPCfmarto f128:$vA, f128:$vB, f128:$vTi)))]>,
289*06f32e7eSjoerg      RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">,
290*06f32e7eSjoerg      AltVSXFMARel;
291*06f32e7eSjoerg
292*06f32e7eSjoerg      // xsnmsubqpo
293*06f32e7eSjoerg      [(set f128:$vT, (fneg (PPCfmarto f128:$vA, f128:$vB, (fneg f128:$vTi))))]>,
294*06f32e7eSjoerg      RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">,
295*06f32e7eSjoerg      AltVSXFMARel;
296*06f32e7eSjoerg
297*06f32e7eSjoerg- QP Compare Ordered/Unordered: xscmpoqp xscmpuqp
298*06f32e7eSjoerg  . ref: XSCMPUDP
299*06f32e7eSjoerg      def XSCMPUDP : XX3Form_1<60, 35,
300*06f32e7eSjoerg                               (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
301*06f32e7eSjoerg                               "xscmpudp $crD, $XA, $XB", IIC_FPCompare, []>;
302*06f32e7eSjoerg
303*06f32e7eSjoerg  . No SDAG, intrinsic, builtin are required??
304*06f32e7eSjoerg    Or llvm fcmp order/unorder compare??
305*06f32e7eSjoerg
306*06f32e7eSjoerg- DP/QP Compare Exponents: xscmpexpdp xscmpexpqp
307*06f32e7eSjoerg  . No SDAG, intrinsic, builtin are required?
308*06f32e7eSjoerg
309*06f32e7eSjoerg- DP Compare ==, >=, >, !=: xscmpeqdp xscmpgedp xscmpgtdp xscmpnedp
310*06f32e7eSjoerg  . I checked existing instruction "XSCMPUDP". They are different in target
311*06f32e7eSjoerg    register. "XSCMPUDP" write to CR field, xscmp*dp write to VSX register
312*06f32e7eSjoerg
313*06f32e7eSjoerg  . Use instrinsic:
314*06f32e7eSjoerg    (set i128:$XT, (int_ppc_vsx_xscmpeqdp f64:$XA, f64:$XB))
315*06f32e7eSjoerg    (set i128:$XT, (int_ppc_vsx_xscmpgedp f64:$XA, f64:$XB))
316*06f32e7eSjoerg    (set i128:$XT, (int_ppc_vsx_xscmpgtdp f64:$XA, f64:$XB))
317*06f32e7eSjoerg    (set i128:$XT, (int_ppc_vsx_xscmpnedp f64:$XA, f64:$XB))
318*06f32e7eSjoerg
319*06f32e7eSjoerg- Vector Compare Not Equal: xvcmpnedp xvcmpnedp. xvcmpnesp xvcmpnesp.
320*06f32e7eSjoerg  . Similar to xvcmpeqdp:
321*06f32e7eSjoerg      defm XVCMPEQDP : XX3Form_Rcr<60, 99,
322*06f32e7eSjoerg                                 "xvcmpeqdp", "$XT, $XA, $XB", IIC_VecFPCompare,
323*06f32e7eSjoerg                                 int_ppc_vsx_xvcmpeqdp, v2i64, v2f64>;
324*06f32e7eSjoerg
325*06f32e7eSjoerg  . So we should use "XX3Form_Rcr" to implement instrinsic
326*06f32e7eSjoerg
327*06f32e7eSjoerg- Convert DP -> QP: xscvdpqp
328*06f32e7eSjoerg  . Similar to XSCVDPSP:
329*06f32e7eSjoerg      def XSCVDPSP : XX2Form<60, 265,
330*06f32e7eSjoerg                          (outs vsfrc:$XT), (ins vsfrc:$XB),
331*06f32e7eSjoerg                          "xscvdpsp $XT, $XB", IIC_VecFP, []>;
332*06f32e7eSjoerg  . So, No SDAG, intrinsic, builtin are required??
333*06f32e7eSjoerg
334*06f32e7eSjoerg- Round & Convert QP -> DP (dword[1] is set to zero): xscvqpdp xscvqpdpo
335*06f32e7eSjoerg  . Similar to XSCVDPSP
336*06f32e7eSjoerg  . No SDAG, intrinsic, builtin are required??
337*06f32e7eSjoerg
338*06f32e7eSjoerg- Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero):
339*06f32e7eSjoerg  xscvqpsdz xscvqpswz xscvqpudz xscvqpuwz
340*06f32e7eSjoerg  . According to PowerISA_V3.0, these are similar to "XSCVDPSXDS", "XSCVDPSXWS",
341*06f32e7eSjoerg    "XSCVDPUXDS", "XSCVDPUXWS"
342*06f32e7eSjoerg
343*06f32e7eSjoerg  . DAG patterns:
344*06f32e7eSjoerg    (set f128:$XT, (PPCfctidz f128:$XB))    // xscvqpsdz
345*06f32e7eSjoerg    (set f128:$XT, (PPCfctiwz f128:$XB))    // xscvqpswz
346*06f32e7eSjoerg    (set f128:$XT, (PPCfctiduz f128:$XB))   // xscvqpudz
347*06f32e7eSjoerg    (set f128:$XT, (PPCfctiwuz f128:$XB))   // xscvqpuwz
348*06f32e7eSjoerg
349*06f32e7eSjoerg- Convert (Un)Signed DWord -> QP: xscvsdqp xscvudqp
350*06f32e7eSjoerg  . Similar to XSCVSXDSP
351*06f32e7eSjoerg  . (set f128:$XT, (PPCfcfids f64:$XB))     // xscvsdqp
352*06f32e7eSjoerg    (set f128:$XT, (PPCfcfidus f64:$XB))    // xscvudqp
353*06f32e7eSjoerg
354*06f32e7eSjoerg- (Round &) Convert DP <-> HP: xscvdphp xscvhpdp
355*06f32e7eSjoerg  . Similar to XSCVDPSP
356*06f32e7eSjoerg  . No SDAG, intrinsic, builtin are required??
357*06f32e7eSjoerg
358*06f32e7eSjoerg- Vector HP -> SP: xvcvhpsp xvcvsphp
359*06f32e7eSjoerg  . Similar to XVCVDPSP:
360*06f32e7eSjoerg      def XVCVDPSP : XX2Form<60, 393,
361*06f32e7eSjoerg                          (outs vsrc:$XT), (ins vsrc:$XB),
362*06f32e7eSjoerg                          "xvcvdpsp $XT, $XB", IIC_VecFP, []>;
363*06f32e7eSjoerg  . No SDAG, intrinsic, builtin are required??
364*06f32e7eSjoerg
365*06f32e7eSjoerg- Round to Quad-Precision Integer: xsrqpi xsrqpix
366*06f32e7eSjoerg  . These are combination of "XSRDPI", "XSRDPIC", "XSRDPIM", .., because you
367*06f32e7eSjoerg    need to assign rounding mode in instruction
368*06f32e7eSjoerg  . Provide builtin?
369*06f32e7eSjoerg    (set f128:$vT, (int_ppc_vsx_xsrqpi f128:$vB))
370*06f32e7eSjoerg    (set f128:$vT, (int_ppc_vsx_xsrqpix f128:$vB))
371*06f32e7eSjoerg
372*06f32e7eSjoerg- Round Quad-Precision to Double-Extended Precision (fp80): xsrqpxp
373*06f32e7eSjoerg  . Provide builtin?
374*06f32e7eSjoerg    (set f128:$vT, (int_ppc_vsx_xsrqpxp f128:$vB))
375*06f32e7eSjoerg
376*06f32e7eSjoergFixed Point Facility:
377*06f32e7eSjoerg
378*06f32e7eSjoerg- Exploit cmprb and cmpeqb (perhaps for something like
379*06f32e7eSjoerg  isalpha/isdigit/isupper/islower and isspace respectivelly). This can
380*06f32e7eSjoerg  perhaps be done through a builtin.
381*06f32e7eSjoerg
382*06f32e7eSjoerg- Provide testing for cnttz[dw]
383*06f32e7eSjoerg- Insert Exponent DP/QP: xsiexpdp xsiexpqp
384*06f32e7eSjoerg  . Use intrinsic?
385*06f32e7eSjoerg  . xsiexpdp:
386*06f32e7eSjoerg    // Note: rA and rB are the unsigned integer value.
387*06f32e7eSjoerg    (set f128:$XT, (int_ppc_vsx_xsiexpdp i64:$rA, i64:$rB))
388*06f32e7eSjoerg
389*06f32e7eSjoerg  . xsiexpqp:
390*06f32e7eSjoerg    (set f128:$vT, (int_ppc_vsx_xsiexpqp f128:$vA, f64:$vB))
391*06f32e7eSjoerg
392*06f32e7eSjoerg- Extract Exponent/Significand DP/QP: xsxexpdp xsxsigdp xsxexpqp xsxsigqp
393*06f32e7eSjoerg  . Use intrinsic?
394*06f32e7eSjoerg  . (set i64:$rT, (int_ppc_vsx_xsxexpdp f64$XB))    // xsxexpdp
395*06f32e7eSjoerg    (set i64:$rT, (int_ppc_vsx_xsxsigdp f64$XB))    // xsxsigdp
396*06f32e7eSjoerg    (set f128:$vT, (int_ppc_vsx_xsxexpqp f128$vB))  // xsxexpqp
397*06f32e7eSjoerg    (set f128:$vT, (int_ppc_vsx_xsxsigqp f128$vB))  // xsxsigqp
398*06f32e7eSjoerg
399*06f32e7eSjoerg- Vector Insert Word: xxinsertw
400*06f32e7eSjoerg  - Useful for inserting f32/i32 elements into vectors (the element to be
401*06f32e7eSjoerg    inserted needs to be prepared)
402*06f32e7eSjoerg  . Note: llvm has insertelem in "Vector Operations"
403*06f32e7eSjoerg    ; yields <n x <ty>>
404*06f32e7eSjoerg    <result> = insertelement <n x <ty>> <val>, <ty> <elt>, <ty2> <idx>
405*06f32e7eSjoerg
406*06f32e7eSjoerg    But how to map to it??
407*06f32e7eSjoerg    [(set v1f128:$XT, (insertelement v1f128:$XTi, f128:$XB, i4:$UIMM))]>,
408*06f32e7eSjoerg    RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
409*06f32e7eSjoerg
410*06f32e7eSjoerg  . Or use intrinsic?
411*06f32e7eSjoerg    (set v1f128:$XT, (int_ppc_vsx_xxinsertw v1f128:$XTi, f128:$XB, i4:$UIMM))
412*06f32e7eSjoerg
413*06f32e7eSjoerg- Vector Extract Unsigned Word: xxextractuw
414*06f32e7eSjoerg  - Not useful for extraction of f32 from v4f32 (the current pattern is better -
415*06f32e7eSjoerg    shift->convert)
416*06f32e7eSjoerg  - It is useful for (uint_to_fp (vector_extract v4i32, N))
417*06f32e7eSjoerg  - Unfortunately, it can't be used for (sint_to_fp (vector_extract v4i32, N))
418*06f32e7eSjoerg  . Note: llvm has extractelement in "Vector Operations"
419*06f32e7eSjoerg    ; yields <ty>
420*06f32e7eSjoerg    <result> = extractelement <n x <ty>> <val>, <ty2> <idx>
421*06f32e7eSjoerg
422*06f32e7eSjoerg    How to map to it??
423*06f32e7eSjoerg    [(set f128:$XT, (extractelement v1f128:$XB, i4:$UIMM))]
424*06f32e7eSjoerg
425*06f32e7eSjoerg  . Or use intrinsic?
426*06f32e7eSjoerg    (set f128:$XT, (int_ppc_vsx_xxextractuw v1f128:$XB, i4:$UIMM))
427*06f32e7eSjoerg
428*06f32e7eSjoerg- Vector Insert Exponent DP/SP: xviexpdp xviexpsp
429*06f32e7eSjoerg  . Use intrinsic
430*06f32e7eSjoerg    (set v2f64:$XT, (int_ppc_vsx_xviexpdp v2f64:$XA, v2f64:$XB))
431*06f32e7eSjoerg    (set v4f32:$XT, (int_ppc_vsx_xviexpsp v4f32:$XA, v4f32:$XB))
432*06f32e7eSjoerg
433*06f32e7eSjoerg- Vector Extract Exponent/Significand DP/SP: xvxexpdp xvxexpsp xvxsigdp xvxsigsp
434*06f32e7eSjoerg  . Use intrinsic
435*06f32e7eSjoerg    (set v2f64:$XT, (int_ppc_vsx_xvxexpdp v2f64:$XB))
436*06f32e7eSjoerg    (set v4f32:$XT, (int_ppc_vsx_xvxexpsp v4f32:$XB))
437*06f32e7eSjoerg    (set v2f64:$XT, (int_ppc_vsx_xvxsigdp v2f64:$XB))
438*06f32e7eSjoerg    (set v4f32:$XT, (int_ppc_vsx_xvxsigsp v4f32:$XB))
439*06f32e7eSjoerg
440*06f32e7eSjoerg- Test Data Class SP/DP/QP: xststdcsp xststdcdp xststdcqp
441*06f32e7eSjoerg  . No SDAG, intrinsic, builtin are required?
442*06f32e7eSjoerg    Because it seems that we have no way to map BF field?
443*06f32e7eSjoerg
444*06f32e7eSjoerg    Instruction Form: [PO T XO B XO BX TX]
445*06f32e7eSjoerg    Asm: xststd* BF,XB,DCMX
446*06f32e7eSjoerg
447*06f32e7eSjoerg    BF is an index to CR register field.
448*06f32e7eSjoerg
449*06f32e7eSjoerg- Vector Test Data Class SP/DP: xvtstdcsp xvtstdcdp
450*06f32e7eSjoerg  . Use intrinsic
451*06f32e7eSjoerg    (set v4f32:$XT, (int_ppc_vsx_xvtstdcsp v4f32:$XB, i7:$DCMX))
452*06f32e7eSjoerg    (set v2f64:$XT, (int_ppc_vsx_xvtstdcdp v2f64:$XB, i7:$DCMX))
453*06f32e7eSjoerg
454*06f32e7eSjoerg- Maximum/Minimum Type-C/Type-J DP: xsmaxcdp xsmaxjdp xsmincdp xsminjdp
455*06f32e7eSjoerg  . PowerISA_V3.0:
456*06f32e7eSjoerg    "xsmaxcdp can be used to implement the C/C++/Java conditional operation
457*06f32e7eSjoerg     (x>y)?x:y for single-precision and double-precision arguments."
458*06f32e7eSjoerg
459*06f32e7eSjoerg    Note! c type and j type have different behavior when:
460*06f32e7eSjoerg    1. Either input is NaN
461*06f32e7eSjoerg    2. Both input are +-Infinity, +-Zero
462*06f32e7eSjoerg
463*06f32e7eSjoerg  . dtype map to llvm fmaxnum/fminnum
464*06f32e7eSjoerg    jtype use intrinsic
465*06f32e7eSjoerg
466*06f32e7eSjoerg  . xsmaxcdp xsmincdp
467*06f32e7eSjoerg    (set f64:$XT, (fmaxnum f64:$XA, f64:$XB))
468*06f32e7eSjoerg    (set f64:$XT, (fminnum f64:$XA, f64:$XB))
469*06f32e7eSjoerg
470*06f32e7eSjoerg  . xsmaxjdp xsminjdp
471*06f32e7eSjoerg    (set f64:$XT, (int_ppc_vsx_xsmaxjdp f64:$XA, f64:$XB))
472*06f32e7eSjoerg    (set f64:$XT, (int_ppc_vsx_xsminjdp f64:$XA, f64:$XB))
473*06f32e7eSjoerg
474*06f32e7eSjoerg- Vector Byte-Reverse H/W/D/Q Word: xxbrh xxbrw xxbrd xxbrq
475*06f32e7eSjoerg  . Use intrinsic
476*06f32e7eSjoerg    (set v8i16:$XT, (int_ppc_vsx_xxbrh v8i16:$XB))
477*06f32e7eSjoerg    (set v4i32:$XT, (int_ppc_vsx_xxbrw v4i32:$XB))
478*06f32e7eSjoerg    (set v2i64:$XT, (int_ppc_vsx_xxbrd v2i64:$XB))
479*06f32e7eSjoerg    (set v1i128:$XT, (int_ppc_vsx_xxbrq v1i128:$XB))
480*06f32e7eSjoerg
481*06f32e7eSjoerg- Vector Permute: xxperm xxpermr
482*06f32e7eSjoerg  . I have checked "PPCxxswapd" in PPCInstrVSX.td, but they are different
483*06f32e7eSjoerg  . Use intrinsic
484*06f32e7eSjoerg    (set v16i8:$XT, (int_ppc_vsx_xxperm v16i8:$XA, v16i8:$XB))
485*06f32e7eSjoerg    (set v16i8:$XT, (int_ppc_vsx_xxpermr v16i8:$XA, v16i8:$XB))
486*06f32e7eSjoerg
487*06f32e7eSjoerg- Vector Splat Immediate Byte: xxspltib
488*06f32e7eSjoerg  . Similar to XXSPLTW:
489*06f32e7eSjoerg      def XXSPLTW : XX2Form_2<60, 164,
490*06f32e7eSjoerg                           (outs vsrc:$XT), (ins vsrc:$XB, u2imm:$UIM),
491*06f32e7eSjoerg                           "xxspltw $XT, $XB, $UIM", IIC_VecPerm, []>;
492*06f32e7eSjoerg
493*06f32e7eSjoerg  . No SDAG, intrinsic, builtin are required?
494*06f32e7eSjoerg
495*06f32e7eSjoerg- Load/Store Vector: lxv stxv
496*06f32e7eSjoerg  . Has likely SDAG match:
497*06f32e7eSjoerg    (set v?:$XT, (load ix16addr:$src))
498*06f32e7eSjoerg    (set v?:$XT, (store ix16addr:$dst))
499*06f32e7eSjoerg
500*06f32e7eSjoerg  . Need define ix16addr in PPCInstrInfo.td
501*06f32e7eSjoerg    ix16addr: 16-byte aligned, see "def memrix16" in PPCInstrInfo.td
502*06f32e7eSjoerg
503*06f32e7eSjoerg- Load/Store Vector Indexed: lxvx stxvx
504*06f32e7eSjoerg  . Has likely SDAG match:
505*06f32e7eSjoerg    (set v?:$XT, (load xoaddr:$src))
506*06f32e7eSjoerg    (set v?:$XT, (store xoaddr:$dst))
507*06f32e7eSjoerg
508*06f32e7eSjoerg- Load/Store DWord: lxsd stxsd
509*06f32e7eSjoerg  . Similar to lxsdx/stxsdx:
510*06f32e7eSjoerg    def LXSDX : XX1Form<31, 588,
511*06f32e7eSjoerg                        (outs vsfrc:$XT), (ins memrr:$src),
512*06f32e7eSjoerg                        "lxsdx $XT, $src", IIC_LdStLFD,
513*06f32e7eSjoerg                        [(set f64:$XT, (load xoaddr:$src))]>;
514*06f32e7eSjoerg
515*06f32e7eSjoerg  . (set f64:$XT, (load iaddrX4:$src))
516*06f32e7eSjoerg    (set f64:$XT, (store iaddrX4:$dst))
517*06f32e7eSjoerg
518*06f32e7eSjoerg- Load/Store SP, with conversion from/to DP: lxssp stxssp
519*06f32e7eSjoerg  . Similar to lxsspx/stxsspx:
520*06f32e7eSjoerg    def LXSSPX : XX1Form<31, 524, (outs vssrc:$XT), (ins memrr:$src),
521*06f32e7eSjoerg                         "lxsspx $XT, $src", IIC_LdStLFD,
522*06f32e7eSjoerg                         [(set f32:$XT, (load xoaddr:$src))]>;
523*06f32e7eSjoerg
524*06f32e7eSjoerg  . (set f32:$XT, (load iaddrX4:$src))
525*06f32e7eSjoerg    (set f32:$XT, (store iaddrX4:$dst))
526*06f32e7eSjoerg
527*06f32e7eSjoerg- Load as Integer Byte/Halfword & Zero Indexed: lxsibzx lxsihzx
528*06f32e7eSjoerg  . Similar to lxsiwzx:
529*06f32e7eSjoerg    def LXSIWZX : XX1Form<31, 12, (outs vsfrc:$XT), (ins memrr:$src),
530*06f32e7eSjoerg                          "lxsiwzx $XT, $src", IIC_LdStLFD,
531*06f32e7eSjoerg                          [(set f64:$XT, (PPClfiwzx xoaddr:$src))]>;
532*06f32e7eSjoerg
533*06f32e7eSjoerg  . (set f64:$XT, (PPClfiwzx xoaddr:$src))
534*06f32e7eSjoerg
535*06f32e7eSjoerg- Store as Integer Byte/Halfword Indexed: stxsibx stxsihx
536*06f32e7eSjoerg  . Similar to stxsiwx:
537*06f32e7eSjoerg    def STXSIWX : XX1Form<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst),
538*06f32e7eSjoerg                          "stxsiwx $XT, $dst", IIC_LdStSTFD,
539*06f32e7eSjoerg                          [(PPCstfiwx f64:$XT, xoaddr:$dst)]>;
540*06f32e7eSjoerg
541*06f32e7eSjoerg  . (PPCstfiwx f64:$XT, xoaddr:$dst)
542*06f32e7eSjoerg
543*06f32e7eSjoerg- Load Vector Halfword*8/Byte*16 Indexed: lxvh8x lxvb16x
544*06f32e7eSjoerg  . Similar to lxvd2x/lxvw4x:
545*06f32e7eSjoerg    def LXVD2X : XX1Form<31, 844,
546*06f32e7eSjoerg                         (outs vsrc:$XT), (ins memrr:$src),
547*06f32e7eSjoerg                         "lxvd2x $XT, $src", IIC_LdStLFD,
548*06f32e7eSjoerg                         [(set v2f64:$XT, (int_ppc_vsx_lxvd2x xoaddr:$src))]>;
549*06f32e7eSjoerg
550*06f32e7eSjoerg  . (set v8i16:$XT, (int_ppc_vsx_lxvh8x xoaddr:$src))
551*06f32e7eSjoerg    (set v16i8:$XT, (int_ppc_vsx_lxvb16x xoaddr:$src))
552*06f32e7eSjoerg
553*06f32e7eSjoerg- Store Vector Halfword*8/Byte*16 Indexed: stxvh8x stxvb16x
554*06f32e7eSjoerg  . Similar to stxvd2x/stxvw4x:
555*06f32e7eSjoerg    def STXVD2X : XX1Form<31, 972,
556*06f32e7eSjoerg                         (outs), (ins vsrc:$XT, memrr:$dst),
557*06f32e7eSjoerg                         "stxvd2x $XT, $dst", IIC_LdStSTFD,
558*06f32e7eSjoerg                         [(store v2f64:$XT, xoaddr:$dst)]>;
559*06f32e7eSjoerg
560*06f32e7eSjoerg  . (store v8i16:$XT, xoaddr:$dst)
561*06f32e7eSjoerg    (store v16i8:$XT, xoaddr:$dst)
562*06f32e7eSjoerg
563*06f32e7eSjoerg- Load/Store Vector (Left-justified) with Length: lxvl lxvll stxvl stxvll
564*06f32e7eSjoerg  . Likely needs an intrinsic
565*06f32e7eSjoerg  . (set v?:$XT, (int_ppc_vsx_lxvl xoaddr:$src))
566*06f32e7eSjoerg    (set v?:$XT, (int_ppc_vsx_lxvll xoaddr:$src))
567*06f32e7eSjoerg
568*06f32e7eSjoerg  . (int_ppc_vsx_stxvl xoaddr:$dst))
569*06f32e7eSjoerg    (int_ppc_vsx_stxvll xoaddr:$dst))
570*06f32e7eSjoerg
571*06f32e7eSjoerg- Load Vector Word & Splat Indexed: lxvwsx
572*06f32e7eSjoerg  . Likely needs an intrinsic
573*06f32e7eSjoerg  . (set v?:$XT, (int_ppc_vsx_lxvwsx xoaddr:$src))
574*06f32e7eSjoerg
575*06f32e7eSjoergAtomic operations (l[dw]at, st[dw]at):
576*06f32e7eSjoerg- Provide custom lowering for common atomic operations to use these
577*06f32e7eSjoerg  instructions with the correct Function Code
578*06f32e7eSjoerg- Ensure the operands are in the correct register (i.e. RT+1, RT+2)
579*06f32e7eSjoerg- Provide builtins since not all FC's necessarily have an existing LLVM
580*06f32e7eSjoerg  atomic operation
581*06f32e7eSjoerg
582*06f32e7eSjoergLoad Doubleword Monitored (ldmx):
583*06f32e7eSjoerg- Investigate whether there are any uses for this. It seems to be related to
584*06f32e7eSjoerg  Garbage Collection so it isn't likely to be all that useful for most
585*06f32e7eSjoerg  languages we deal with.
586*06f32e7eSjoerg
587*06f32e7eSjoergMove to CR from XER Extended (mcrxrx):
588*06f32e7eSjoerg- Is there a use for this in LLVM?
589*06f32e7eSjoerg
590*06f32e7eSjoergFixed Point Facility:
591*06f32e7eSjoerg
592*06f32e7eSjoerg- Copy-Paste Facility: copy copy_first cp_abort paste paste. paste_last
593*06f32e7eSjoerg  . Use instrinstics:
594*06f32e7eSjoerg    (int_ppc_copy_first i32:$rA, i32:$rB)
595*06f32e7eSjoerg    (int_ppc_copy i32:$rA, i32:$rB)
596*06f32e7eSjoerg
597*06f32e7eSjoerg    (int_ppc_paste i32:$rA, i32:$rB)
598*06f32e7eSjoerg    (int_ppc_paste_last i32:$rA, i32:$rB)
599*06f32e7eSjoerg
600*06f32e7eSjoerg    (int_cp_abort)
601*06f32e7eSjoerg
602*06f32e7eSjoerg- Message Synchronize: msgsync
603*06f32e7eSjoerg- SLB*: slbieg slbsync
604*06f32e7eSjoerg- stop
605*06f32e7eSjoerg  . No instrinstics
606