xref: /freebsd/contrib/llvm-project/llvm/lib/Target/SystemZ/SystemZInstrVector.td (revision 700637cbb5e582861067a11aaca4d053546871d2)
1//==- SystemZInstrVector.td - SystemZ Vector instructions ------*- tblgen-*-==//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9//===----------------------------------------------------------------------===//
10// Move instructions
11//===----------------------------------------------------------------------===//
12
13let Predicates = [FeatureVector] in {
14  // Register move.
15  let isMoveReg = 1 in {
16    def VLR : UnaryVRRa<"vlr", 0xE756, null_frag, v128any, v128any>;
17    def VLR32 : UnaryAliasVRR<null_frag, v32sb, v32sb>;
18    def VLR64 : UnaryAliasVRR<null_frag, v64db, v64db>;
19  }
20
21  // Load GR from VR element.
22  def VLGV  : BinaryVRScGeneric<"vlgv", 0xE721>;
23  def VLGVB : BinaryVRSc<"vlgvb", 0xE721, null_frag, v128b, 0>;
24  def VLGVH : BinaryVRSc<"vlgvh", 0xE721, null_frag, v128h, 1>;
25  def VLGVF : BinaryVRSc<"vlgvf", 0xE721, null_frag, v128f, 2>;
26  def VLGVG : BinaryVRSc<"vlgvg", 0xE721, z_vector_extract, v128g, 3>;
27
28  // Load VR element from GR.
29  def VLVG  : TernaryVRSbGeneric<"vlvg", 0xE722>;
30  def VLVGB : TernaryVRSb<"vlvgb", 0xE722, z_vector_insert,
31                          v128b, v128b, GR32, 0>;
32  def VLVGH : TernaryVRSb<"vlvgh", 0xE722, z_vector_insert,
33                          v128h, v128h, GR32, 1>;
34  def VLVGF : TernaryVRSb<"vlvgf", 0xE722, z_vector_insert,
35                          v128f, v128f, GR32, 2>;
36  def VLVGG : TernaryVRSb<"vlvgg", 0xE722, z_vector_insert,
37                          v128g, v128g, GR64, 3>;
38
39  // Load VR from GRs disjoint.
40  def VLVGP : BinaryVRRf<"vlvgp", 0xE762, z_join_dwords, v128g>;
41  def VLVGP32 : BinaryAliasVRRf<GR32>;
42}
43
44// Extractions always assign to the full GR64, even if the element would
45// fit in the lower 32 bits.  Sub-i64 extracts therefore need to take a
46// subreg of the result.
47class VectorExtractSubreg<ValueType type, Instruction insn>
48  : Pat<(i32 (z_vector_extract (type VR128:$vec), shift12only:$index)),
49        (EXTRACT_SUBREG (insn VR128:$vec, shift12only:$index), subreg_l32)>;
50
51def : VectorExtractSubreg<v16i8, VLGVB>;
52def : VectorExtractSubreg<v8i16, VLGVH>;
53def : VectorExtractSubreg<v4i32, VLGVF>;
54
55//===----------------------------------------------------------------------===//
56// Immediate instructions
57//===----------------------------------------------------------------------===//
58
59let Predicates = [FeatureVector] in {
60  let isAsCheapAsAMove = 1, isMoveImm = 1, isReMaterializable = 1 in {
61
62    // Generate byte mask.
63    def VZERO : InherentVRIa<"vzero", 0xE744, 0>;
64    def VONE  : InherentVRIa<"vone", 0xE744, 0xffff>;
65    def VGBM  : UnaryVRIa<"vgbm", 0xE744, z_byte_mask, v128b, imm32zx16_timm>;
66
67    // Generate mask.
68    def VGM  : BinaryVRIbGeneric<"vgm", 0xE746>;
69    def VGMB : BinaryVRIb<"vgmb", 0xE746, z_rotate_mask, v128b, 0>;
70    def VGMH : BinaryVRIb<"vgmh", 0xE746, z_rotate_mask, v128h, 1>;
71    def VGMF : BinaryVRIb<"vgmf", 0xE746, z_rotate_mask, v128f, 2>;
72    def VGMG : BinaryVRIb<"vgmg", 0xE746, z_rotate_mask, v128g, 3>;
73
74    // Replicate immediate.
75    def VREPI  : UnaryVRIaGeneric<"vrepi", 0xE745, imm32sx16>;
76    def VREPIB : UnaryVRIa<"vrepib", 0xE745, z_replicate, v128b, imm32sx16_timm, 0>;
77    def VREPIH : UnaryVRIa<"vrepih", 0xE745, z_replicate, v128h, imm32sx16_timm, 1>;
78    def VREPIF : UnaryVRIa<"vrepif", 0xE745, z_replicate, v128f, imm32sx16_timm, 2>;
79    def VREPIG : UnaryVRIa<"vrepig", 0xE745, z_replicate, v128g, imm32sx16_timm, 3>;
80  }
81
82  // Load element immediate.
83  //
84  // We want these instructions to be used ahead of VLVG* where possible.
85  // However, VLVG* takes a variable BD-format index whereas VLEI takes
86  // a plain immediate index.  This means that VLVG* has an extra "base"
87  // register operand and is 3 units more complex.  Bumping the complexity
88  // of the VLEI* instructions by 4 means that they are strictly better
89  // than VLVG* in cases where both forms match.
90  let AddedComplexity = 4 in {
91    def VLEIB : TernaryVRIa<"vleib", 0xE740, z_vector_insert,
92                            v128b, v128b, imm32sx16trunc, imm32zx4>;
93    def VLEIH : TernaryVRIa<"vleih", 0xE741, z_vector_insert,
94                            v128h, v128h, imm32sx16trunc, imm32zx3>;
95    def VLEIF : TernaryVRIa<"vleif", 0xE743, z_vector_insert,
96                            v128f, v128f, imm32sx16, imm32zx2>;
97    def VLEIG : TernaryVRIa<"vleig", 0xE742, z_vector_insert,
98                            v128g, v128g, imm64sx16, imm32zx1>;
99  }
100}
101
102//===----------------------------------------------------------------------===//
103// Loads
104//===----------------------------------------------------------------------===//
105
106let Predicates = [FeatureVector] in {
107  // Load.
108  let SimpleBDXLoad = 1 in
109      defm VL : UnaryVRXAlign<"vl", 0xE706>;
110
111  // Load to block boundary.  The number of loaded bytes is only known
112  // at run time.  The instruction is really polymorphic, but v128b matches
113  // the return type of the associated intrinsic.
114  def VLBB : BinaryVRX<"vlbb", 0xE707, int_s390_vlbb, v128b, 0>;
115
116  // Load count to block boundary.
117  let Defs = [CC] in
118    def LCBB : InstRXE<0xE727, (outs GR32:$R1),
119                               (ins (bdxaddr12only $B2, $D2, $X2):$XBD2, imm32zx4:$M3),
120                       "lcbb\t$R1, $XBD2, $M3",
121                       [(set GR32:$R1, (int_s390_lcbb bdxaddr12only:$XBD2,
122                                                      imm32zx4_timm:$M3))]>;
123
124  // Load with length.  The number of loaded bytes is only known at run time.
125  def VLL : BinaryVRSb<"vll", 0xE737, int_s390_vll, 0>;
126
127  // Load multiple.
128  defm VLM : LoadMultipleVRSaAlign<"vlm", 0xE736>;
129
130  // Load and replicate
131  def VLREP  : UnaryVRXGeneric<"vlrep", 0xE705>;
132  def VLREPB : UnaryVRX<"vlrepb", 0xE705, z_replicate_loadi8,  v128b, 1, 0>;
133  def VLREPH : UnaryVRX<"vlreph", 0xE705, z_replicate_loadi16, v128h, 2, 1>;
134  def VLREPF : UnaryVRX<"vlrepf", 0xE705, z_replicate_loadi32, v128f, 4, 2>;
135  def VLREPG : UnaryVRX<"vlrepg", 0xE705, z_replicate_loadi64, v128g, 8, 3>;
136  def : Pat<(v4f32 (z_replicate_loadf32 bdxaddr12only:$addr)),
137            (VLREPF bdxaddr12only:$addr)>;
138  def : Pat<(v2f64 (z_replicate_loadf64 bdxaddr12only:$addr)),
139            (VLREPG bdxaddr12only:$addr)>;
140
141  // Use VLREP to load subvectors.  These patterns use "12pair" because
142  // LEY and LDY offer full 20-bit displacement fields.  It's often better
143  // to use those instructions rather than force a 20-bit displacement
144  // into a GPR temporary.
145  let mayLoad = 1, SimpleBDXLoad = 1, canFoldAsLoad = 1 in {
146    def VL16 : UnaryAliasVRX<z_load, v16hb, bdxaddr12pair>;
147    def VL32 : UnaryAliasVRX<z_load, v32sb, bdxaddr12pair>;
148    def VL64 : UnaryAliasVRX<z_load, v64db, bdxaddr12pair>;
149  }
150
151  // Load logical element and zero.
152  def VLLEZ  : UnaryVRXGeneric<"vllez", 0xE704>;
153  def VLLEZB : UnaryVRX<"vllezb", 0xE704, z_vllezi8,  v128b, 1, 0>;
154  def VLLEZH : UnaryVRX<"vllezh", 0xE704, z_vllezi16, v128h, 2, 1>;
155  def VLLEZF : UnaryVRX<"vllezf", 0xE704, z_vllezi32, v128f, 4, 2>;
156  def VLLEZG : UnaryVRX<"vllezg", 0xE704, z_vllezi64, v128g, 8, 3>;
157  def : Pat<(z_vllezf32 bdxaddr12only:$addr),
158            (VLLEZF bdxaddr12only:$addr)>;
159  def : Pat<(z_vllezf64 bdxaddr12only:$addr),
160            (VLLEZG bdxaddr12only:$addr)>;
161  let Predicates = [FeatureVectorEnhancements1] in {
162    def VLLEZLF : UnaryVRX<"vllezlf", 0xE704, z_vllezli32, v128f, 4, 6>;
163    def : Pat<(z_vllezlf32 bdxaddr12only:$addr),
164              (VLLEZLF bdxaddr12only:$addr)>;
165  }
166
167  // Load element.
168  def VLEB : TernaryVRX<"vleb", 0xE700, z_vlei8,  v128b, v128b, 1, imm32zx4>;
169  def VLEH : TernaryVRX<"vleh", 0xE701, z_vlei16, v128h, v128h, 2, imm32zx3>;
170  def VLEF : TernaryVRX<"vlef", 0xE703, z_vlei32, v128f, v128f, 4, imm32zx2>;
171  def VLEG : TernaryVRX<"vleg", 0xE702, z_vlei64, v128g, v128g, 8, imm32zx1>;
172  def : Pat<(z_vlef32 (v4f32 VR128:$val), bdxaddr12only:$addr, imm32zx2:$index),
173            (VLEF VR128:$val, bdxaddr12only:$addr, imm32zx2:$index)>;
174  def : Pat<(z_vlef64 (v2f64 VR128:$val), bdxaddr12only:$addr, imm32zx1:$index),
175            (VLEG VR128:$val, bdxaddr12only:$addr, imm32zx1:$index)>;
176
177  // Gather element.
178  def VGEF : TernaryVRV<"vgef", 0xE713, 4, imm32zx2>;
179  def VGEG : TernaryVRV<"vgeg", 0xE712, 8, imm32zx1>;
180}
181
182let Predicates = [FeatureVectorPackedDecimal] in {
183  // Load rightmost with length.  The number of loaded bytes is only known
184  // at run time.  Note that while the instruction will accept immediate
185  // lengths larger that 15 at runtime, those will always result in a trap,
186  // so we never emit them here.
187  def VLRL : BinaryVSI<"vlrl", 0xE635, null_frag, 0>;
188  def VLRLR : BinaryVRSd<"vlrlr", 0xE637, int_s390_vlrl, 0>;
189  def : Pat<(int_s390_vlrl imm32zx4:$len, bdaddr12only:$addr),
190            (VLRL bdaddr12only:$addr, imm32zx4:$len)>;
191}
192
193// Use replicating loads if we're inserting a single element into an
194// undefined vector.  This avoids a false dependency on the previous
195// register contents.
196multiclass ReplicatePeephole<Instruction vlrep, ValueType vectype,
197                             SDPatternOperator load, ValueType scalartype> {
198  def : Pat<(vectype (z_vector_insert
199                      (undef), (scalartype (load bdxaddr12only:$addr)), 0)),
200            (vlrep bdxaddr12only:$addr)>;
201  def : Pat<(vectype (scalar_to_vector
202                      (scalartype (load bdxaddr12only:$addr)))),
203            (vlrep bdxaddr12only:$addr)>;
204}
205defm : ReplicatePeephole<VLREPB, v16i8, z_anyextloadi8, i32>;
206defm : ReplicatePeephole<VLREPH, v8i16, z_anyextloadi16, i32>;
207defm : ReplicatePeephole<VLREPF, v4i32, z_load, i32>;
208defm : ReplicatePeephole<VLREPG, v2i64, z_load, i64>;
209defm : ReplicatePeephole<VLREPF, v4f32, z_load, f32>;
210defm : ReplicatePeephole<VLREPG, v2f64, z_load, f64>;
211
212//===----------------------------------------------------------------------===//
213// Stores
214//===----------------------------------------------------------------------===//
215
216let Predicates = [FeatureVector] in {
217  // Store.
218  let SimpleBDXStore = 1 in
219      defm VST : StoreVRXAlign<"vst", 0xE70E>;
220
221  // Store with length.  The number of stored bytes is only known at run time.
222  def VSTL : StoreLengthVRSb<"vstl", 0xE73F, int_s390_vstl, 0>;
223
224  // Store multiple.
225  defm VSTM : StoreMultipleVRSaAlign<"vstm", 0xE73E>;
226
227  // Store element.
228  def VSTEB : StoreBinaryVRX<"vsteb", 0xE708, z_vstei8,  v128b, 1, imm32zx4>;
229  def VSTEH : StoreBinaryVRX<"vsteh", 0xE709, z_vstei16, v128h, 2, imm32zx3>;
230  def VSTEF : StoreBinaryVRX<"vstef", 0xE70B, z_vstei32, v128f, 4, imm32zx2>;
231  def VSTEG : StoreBinaryVRX<"vsteg", 0xE70A, z_vstei64, v128g, 8, imm32zx1>;
232  def : Pat<(z_vstef32 (v4f32 VR128:$val), bdxaddr12only:$addr,
233                       imm32zx2:$index),
234            (VSTEF VR128:$val, bdxaddr12only:$addr, imm32zx2:$index)>;
235  def : Pat<(z_vstef64 (v2f64 VR128:$val), bdxaddr12only:$addr,
236                       imm32zx1:$index),
237            (VSTEG VR128:$val, bdxaddr12only:$addr, imm32zx1:$index)>;
238
239  // Use VSTE to store subvectors.  These patterns use "12pair" because
240  // STEY and STDY offer full 20-bit displacement fields.  It's often better
241  // to use those instructions rather than force a 20-bit displacement
242  // into a GPR temporary.
243  let mayStore = 1, SimpleBDXStore = 1 in {
244    def VST16 : StoreAliasVRX<store, v16hb, bdxaddr12pair>;
245    def VST32 : StoreAliasVRX<store, v32sb, bdxaddr12pair>;
246    def VST64 : StoreAliasVRX<store, v64db, bdxaddr12pair>;
247  }
248
249  // Scatter element.
250  def VSCEF : StoreBinaryVRV<"vscef", 0xE71B, 4, imm32zx2>;
251  def VSCEG : StoreBinaryVRV<"vsceg", 0xE71A, 8, imm32zx1>;
252}
253
254let Predicates = [FeatureVectorPackedDecimal] in {
255  // Store rightmost with length.  The number of stored bytes is only known
256  // at run time.  Note that while the instruction will accept immediate
257  // lengths larger that 15 at runtime, those will always result in a trap,
258  // so we never emit them here.
259  def VSTRL : StoreLengthVSI<"vstrl", 0xE63D, null_frag, 0>;
260  def VSTRLR : StoreLengthVRSd<"vstrlr", 0xE63F, int_s390_vstrl, 0>;
261  def : Pat<(int_s390_vstrl VR128:$val, imm32zx4:$len, bdaddr12only:$addr),
262            (VSTRL VR128:$val, bdaddr12only:$addr, imm32zx4:$len)>;
263}
264
265//===----------------------------------------------------------------------===//
266// Byte swaps
267//===----------------------------------------------------------------------===//
268
269let Predicates = [FeatureVectorEnhancements2] in {
270  // Load byte-reversed elements.
271  def VLBR  : UnaryVRXGeneric<"vlbr", 0xE606>;
272  def VLBRH : UnaryVRX<"vlbrh", 0xE606, z_loadbswap, v128h, 16, 1>;
273  def VLBRF : UnaryVRX<"vlbrf", 0xE606, z_loadbswap, v128f, 16, 2>;
274  def VLBRG : UnaryVRX<"vlbrg", 0xE606, z_loadbswap, v128g, 16, 3>;
275  def VLBRQ : UnaryVRX<"vlbrq", 0xE606, z_loadbswap, v128q, 16, 4>;
276
277  // Load elements reversed.
278  def VLER  : UnaryVRXGeneric<"vler", 0xE607>;
279  def VLERH : UnaryVRX<"vlerh", 0xE607, z_loadeswap, v128h, 16, 1>;
280  def VLERF : UnaryVRX<"vlerf", 0xE607, z_loadeswap, v128f, 16, 2>;
281  def VLERG : UnaryVRX<"vlerg", 0xE607, z_loadeswap, v128g, 16, 3>;
282  def : Pat<(v4f32 (z_loadeswap bdxaddr12only:$addr)),
283            (VLERF bdxaddr12only:$addr)>;
284  def : Pat<(v2f64 (z_loadeswap bdxaddr12only:$addr)),
285            (VLERG bdxaddr12only:$addr)>;
286  def : Pat<(v16i8 (z_loadeswap bdxaddr12only:$addr)),
287            (VLBRQ bdxaddr12only:$addr)>;
288
289  // Load byte-reversed element.
290  def VLEBRH : TernaryVRX<"vlebrh", 0xE601, z_vlebri16, v128h, v128h, 2, imm32zx3>;
291  def VLEBRF : TernaryVRX<"vlebrf", 0xE603, z_vlebri32, v128f, v128f, 4, imm32zx2>;
292  def VLEBRG : TernaryVRX<"vlebrg", 0xE602, z_vlebri64, v128g, v128g, 8, imm32zx1>;
293
294  // Load byte-reversed element and zero.
295  def VLLEBRZ  : UnaryVRXGeneric<"vllebrz", 0xE604>;
296  def VLLEBRZH : UnaryVRX<"vllebrzh", 0xE604, z_vllebrzi16, v128h, 2, 1>;
297  def VLLEBRZF : UnaryVRX<"vllebrzf", 0xE604, z_vllebrzi32, v128f, 4, 2>;
298  def VLLEBRZG : UnaryVRX<"vllebrzg", 0xE604, z_vllebrzi64, v128g, 8, 3>;
299  def VLLEBRZE : UnaryVRX<"vllebrze", 0xE604, z_vllebrzli32, v128f, 4, 6>;
300  def : InstAlias<"lerv\t$V1, $XBD2",
301                  (VLLEBRZE VR128:$V1, bdxaddr12only:$XBD2), 0>;
302  def : InstAlias<"ldrv\t$V1, $XBD2",
303                  (VLLEBRZG VR128:$V1, bdxaddr12only:$XBD2), 0>;
304
305  // Load byte-reversed element and replicate.
306  def VLBRREP  : UnaryVRXGeneric<"vlbrrep", 0xE605>;
307  def VLBRREPH : UnaryVRX<"vlbrreph", 0xE605, z_replicate_loadbswapi16, v128h, 2, 1>;
308  def VLBRREPF : UnaryVRX<"vlbrrepf", 0xE605, z_replicate_loadbswapi32, v128f, 4, 2>;
309  def VLBRREPG : UnaryVRX<"vlbrrepg", 0xE605, z_replicate_loadbswapi64, v128g, 8, 3>;
310
311  // Store byte-reversed elements.
312  def VSTBR  : StoreVRXGeneric<"vstbr", 0xE60E>;
313  def VSTBRH : StoreVRX<"vstbrh", 0xE60E, z_storebswap, v128h, 16, 1>;
314  def VSTBRF : StoreVRX<"vstbrf", 0xE60E, z_storebswap, v128f, 16, 2>;
315  def VSTBRG : StoreVRX<"vstbrg", 0xE60E, z_storebswap, v128g, 16, 3>;
316  def VSTBRQ : StoreVRX<"vstbrq", 0xE60E, z_storebswap, v128q, 16, 4>;
317
318  // Store elements reversed.
319  def VSTER  : StoreVRXGeneric<"vster", 0xE60F>;
320  def VSTERH : StoreVRX<"vsterh", 0xE60F, z_storeeswap, v128h, 16, 1>;
321  def VSTERF : StoreVRX<"vsterf", 0xE60F, z_storeeswap, v128f, 16, 2>;
322  def VSTERG : StoreVRX<"vsterg", 0xE60F, z_storeeswap, v128g, 16, 3>;
323  def : Pat<(z_storeeswap (v4f32 VR128:$val), bdxaddr12only:$addr),
324            (VSTERF VR128:$val, bdxaddr12only:$addr)>;
325  def : Pat<(z_storeeswap (v2f64 VR128:$val), bdxaddr12only:$addr),
326            (VSTERG VR128:$val, bdxaddr12only:$addr)>;
327  def : Pat<(z_storeeswap (v16i8 VR128:$val), bdxaddr12only:$addr),
328            (VSTBRQ VR128:$val, bdxaddr12only:$addr)>;
329
330  // Store byte-reversed element.
331  def VSTEBRH : StoreBinaryVRX<"vstebrh", 0xE609, z_vstebri16, v128h, 2, imm32zx3>;
332  def VSTEBRF : StoreBinaryVRX<"vstebrf", 0xE60B, z_vstebri32, v128f, 4, imm32zx2>;
333  def VSTEBRG : StoreBinaryVRX<"vstebrg", 0xE60A, z_vstebri64, v128g, 8, imm32zx1>;
334  def : InstAlias<"sterv\t$V1, $XBD2",
335                  (VSTEBRF VR128:$V1, bdxaddr12only:$XBD2, 0), 0>;
336  def : InstAlias<"stdrv\t$V1, $XBD2",
337                  (VSTEBRG VR128:$V1, bdxaddr12only:$XBD2, 0), 0>;
338}
339
340//===----------------------------------------------------------------------===//
341// Selects and permutes
342//===----------------------------------------------------------------------===//
343
344let Predicates = [FeatureVector] in {
345  // Merge high.
346  def VMRH:   BinaryVRRcGeneric<"vmrh", 0xE761>;
347  def VMRHB : BinaryVRRc<"vmrhb", 0xE761, z_merge_high, v128b, v128b, 0>;
348  def VMRHH : BinaryVRRc<"vmrhh", 0xE761, z_merge_high, v128h, v128h, 1>;
349  def VMRHF : BinaryVRRc<"vmrhf", 0xE761, z_merge_high, v128f, v128f, 2>;
350  def VMRHG : BinaryVRRc<"vmrhg", 0xE761, z_merge_high, v128g, v128g, 3>;
351  def : BinaryRRWithType<VMRHF, VR128, z_merge_high, v4f32>;
352  def : BinaryRRWithType<VMRHG, VR128, z_merge_high, v2f64>;
353
354  // Merge low.
355  def VMRL:   BinaryVRRcGeneric<"vmrl", 0xE760>;
356  def VMRLB : BinaryVRRc<"vmrlb", 0xE760, z_merge_low, v128b, v128b, 0>;
357  def VMRLH : BinaryVRRc<"vmrlh", 0xE760, z_merge_low, v128h, v128h, 1>;
358  def VMRLF : BinaryVRRc<"vmrlf", 0xE760, z_merge_low, v128f, v128f, 2>;
359  def VMRLG : BinaryVRRc<"vmrlg", 0xE760, z_merge_low, v128g, v128g, 3>;
360  def : BinaryRRWithType<VMRLF, VR128, z_merge_low, v4f32>;
361  def : BinaryRRWithType<VMRLG, VR128, z_merge_low, v2f64>;
362
363  // Permute.
364  def VPERM : TernaryVRRe<"vperm", 0xE78C, z_permute, v128b, v128b>;
365
366  // Permute doubleword immediate.
367  def VPDI : TernaryVRRc<"vpdi", 0xE784, z_permute_dwords, v128g, v128g>;
368
369  // Bit Permute.
370  let Predicates = [FeatureVectorEnhancements1] in
371    def VBPERM : BinaryVRRc<"vbperm", 0xE785, int_s390_vbperm, v128g, v128b>;
372
373  // Replicate.
374  def VREP:   BinaryVRIcGeneric<"vrep", 0xE74D>;
375  def VREPB : BinaryVRIc<"vrepb", 0xE74D, z_splat, v128b, v128b, 0>;
376  def VREPH : BinaryVRIc<"vreph", 0xE74D, z_splat, v128h, v128h, 1>;
377  def VREPF : BinaryVRIc<"vrepf", 0xE74D, z_splat, v128f, v128f, 2>;
378  def VREPG : BinaryVRIc<"vrepg", 0xE74D, z_splat, v128g, v128g, 3>;
379  def : Pat<(v4f32 (z_splat VR128:$vec, imm32zx16_timm:$index)),
380            (VREPF VR128:$vec, imm32zx16:$index)>;
381  def : Pat<(v2f64 (z_splat VR128:$vec, imm32zx16_timm:$index)),
382            (VREPG VR128:$vec, imm32zx16:$index)>;
383
384  // Select.
385  def VSEL : TernaryVRRe<"vsel", 0xE78D, null_frag, v128any, v128any>;
386
387  // Blend.
388  let Predicates = [FeatureVectorEnhancements3] in {
389    def VBLEND  : TernaryVRRdGeneric<"vblend", 0xE789>;
390    def VBLENDB : TernaryVRRd<"vblendb", 0xE789, null_frag, v128b, v128b, 0>;
391    def VBLENDH : TernaryVRRd<"vblendh", 0xE789, null_frag, v128h, v128h, 1>;
392    def VBLENDF : TernaryVRRd<"vblendf", 0xE789, null_frag, v128f, v128f, 2>;
393    def VBLENDG : TernaryVRRd<"vblendg", 0xE789, null_frag, v128g, v128g, 3>;
394    def VBLENDQ : TernaryVRRd<"vblendq", 0xE789, null_frag, v128q, v128q, 4>;
395  }
396}
397
398//===----------------------------------------------------------------------===//
399// Widening and narrowing
400//===----------------------------------------------------------------------===//
401
402let Predicates = [FeatureVector] in {
403  // Pack
404  def VPK  : BinaryVRRcGeneric<"vpk", 0xE794>;
405  def VPKH : BinaryVRRc<"vpkh", 0xE794, z_pack, v128b, v128h, 1>;
406  def VPKF : BinaryVRRc<"vpkf", 0xE794, z_pack, v128h, v128f, 2>;
407  def VPKG : BinaryVRRc<"vpkg", 0xE794, z_pack, v128f, v128g, 3>;
408
409  // Pack saturate.
410  def  VPKS  : BinaryVRRbSPairGeneric<"vpks", 0xE797>;
411  defm VPKSH : BinaryVRRbSPair<"vpksh", 0xE797, int_s390_vpksh, z_packs_cc,
412                               v128b, v128h, 1>;
413  defm VPKSF : BinaryVRRbSPair<"vpksf", 0xE797, int_s390_vpksf, z_packs_cc,
414                               v128h, v128f, 2>;
415  defm VPKSG : BinaryVRRbSPair<"vpksg", 0xE797, int_s390_vpksg, z_packs_cc,
416                               v128f, v128g, 3>;
417
418  // Pack saturate logical.
419  def  VPKLS  : BinaryVRRbSPairGeneric<"vpkls", 0xE795>;
420  defm VPKLSH : BinaryVRRbSPair<"vpklsh", 0xE795, int_s390_vpklsh, z_packls_cc,
421                                v128b, v128h, 1>;
422  defm VPKLSF : BinaryVRRbSPair<"vpklsf", 0xE795, int_s390_vpklsf, z_packls_cc,
423                                v128h, v128f, 2>;
424  defm VPKLSG : BinaryVRRbSPair<"vpklsg", 0xE795, int_s390_vpklsg, z_packls_cc,
425                                v128f, v128g, 3>;
426
427  // Sign-extend to doubleword.
428  def VSEG  : UnaryVRRaGeneric<"vseg", 0xE75F>;
429  def VSEGB : UnaryVRRa<"vsegb", 0xE75F, z_vsei8,  v128g, v128g, 0>;
430  def VSEGH : UnaryVRRa<"vsegh", 0xE75F, z_vsei16, v128g, v128g, 1>;
431  def VSEGF : UnaryVRRa<"vsegf", 0xE75F, z_vsei32, v128g, v128g, 2>;
432  def : Pat<(z_vsei8_by_parts  (v16i8 VR128:$src)), (VSEGB VR128:$src)>;
433  def : Pat<(z_vsei16_by_parts (v8i16 VR128:$src)), (VSEGH VR128:$src)>;
434  def : Pat<(z_vsei32_by_parts (v4i32 VR128:$src)), (VSEGF VR128:$src)>;
435
436  // Generate element masks.
437  let Predicates = [FeatureVectorEnhancements3] in {
438    def VGEM  : UnaryVRRaGeneric<"vgem", 0xE754>;
439    def VGEMB : UnaryVRRa<"vgemb", 0xE754, int_s390_vgemb, v128b, v128h, 0>;
440    def VGEMH : UnaryVRRa<"vgemh", 0xE754, int_s390_vgemh, v128h, v128b, 1>;
441    def VGEMF : UnaryVRRa<"vgemf", 0xE754, int_s390_vgemf, v128f, v128b, 2>;
442    def VGEMG : UnaryVRRa<"vgemg", 0xE754, int_s390_vgemg, v128g, v128b, 3>;
443    def VGEMQ : UnaryVRRa<"vgemq", 0xE754, int_s390_vgemq, v128q, v128b, 4>;
444  }
445
446  // Unpack high.
447  def VUPH  : UnaryVRRaGeneric<"vuph", 0xE7D7>;
448  def VUPHB : UnaryVRRa<"vuphb", 0xE7D7, z_unpack_high, v128h, v128b, 0>;
449  def VUPHH : UnaryVRRa<"vuphh", 0xE7D7, z_unpack_high, v128f, v128h, 1>;
450  def VUPHF : UnaryVRRa<"vuphf", 0xE7D7, z_unpack_high, v128g, v128f, 2>;
451  let Predicates = [FeatureVectorEnhancements3] in
452    def VUPHG : UnaryVRRa<"vuphg", 0xE7D7, z_unpack_high, v128q, v128g, 3>;
453
454  // Unpack logical high.
455  def VUPLH  : UnaryVRRaGeneric<"vuplh", 0xE7D5>;
456  def VUPLHB : UnaryVRRa<"vuplhb", 0xE7D5, z_unpackl_high, v128h, v128b, 0>;
457  def VUPLHH : UnaryVRRa<"vuplhh", 0xE7D5, z_unpackl_high, v128f, v128h, 1>;
458  def VUPLHF : UnaryVRRa<"vuplhf", 0xE7D5, z_unpackl_high, v128g, v128f, 2>;
459  let Predicates = [FeatureVectorEnhancements3] in
460    def VUPLHG : UnaryVRRa<"vuplhg", 0xE7D5, z_unpackl_high, v128q, v128g, 3>;
461
462  // Unpack low.
463  def VUPL   : UnaryVRRaGeneric<"vupl", 0xE7D6>;
464  def VUPLB  : UnaryVRRa<"vuplb",  0xE7D6, z_unpack_low, v128h, v128b, 0>;
465  def VUPLHW : UnaryVRRa<"vuplhw", 0xE7D6, z_unpack_low, v128f, v128h, 1>;
466  def VUPLF  : UnaryVRRa<"vuplf",  0xE7D6, z_unpack_low, v128g, v128f, 2>;
467  let Predicates = [FeatureVectorEnhancements3] in
468    def VUPLG  : UnaryVRRa<"vuplg",  0xE7D6, z_unpack_low, v128q, v128g, 3>;
469
470  // Unpack logical low.
471  def VUPLL  : UnaryVRRaGeneric<"vupll", 0xE7D4>;
472  def VUPLLB : UnaryVRRa<"vupllb", 0xE7D4, z_unpackl_low, v128h, v128b, 0>;
473  def VUPLLH : UnaryVRRa<"vupllh", 0xE7D4, z_unpackl_low, v128f, v128h, 1>;
474  def VUPLLF : UnaryVRRa<"vupllf", 0xE7D4, z_unpackl_low, v128g, v128f, 2>;
475  let Predicates = [FeatureVectorEnhancements3] in
476    def VUPLLG : UnaryVRRa<"vupllg", 0xE7D4, z_unpackl_low, v128q, v128g, 3>;
477}
478
479//===----------------------------------------------------------------------===//
480// Instantiating generic operations for specific types.
481//===----------------------------------------------------------------------===//
482
483multiclass GenericVectorOps<ValueType type, ValueType inttype> {
484  let Predicates = [FeatureVector] in {
485    def : Pat<(type (load bdxaddr12only:$addr)),
486              (VL bdxaddr12only:$addr)>;
487    def : Pat<(store (type VR128:$src), bdxaddr12only:$addr),
488              (VST VR128:$src, bdxaddr12only:$addr)>;
489    def : Pat<(type (vselect (inttype VR128:$x), VR128:$y, VR128:$z)),
490              (VSEL VR128:$y, VR128:$z, VR128:$x)>;
491    def : Pat<(type (vselect (inttype (z_vnot VR128:$x)), VR128:$y, VR128:$z)),
492              (VSEL VR128:$z, VR128:$y, VR128:$x)>;
493  }
494}
495
496defm : GenericVectorOps<v16i8, v16i8>;
497defm : GenericVectorOps<v8i16, v8i16>;
498defm : GenericVectorOps<v4i32, v4i32>;
499defm : GenericVectorOps<v2i64, v2i64>;
500defm : GenericVectorOps<v4f32, v4i32>;
501defm : GenericVectorOps<v2f64, v2i64>;
502
503multiclass BlendVectorOps<ValueType type, ValueType inttype,
504                          Instruction blend> {
505  let Predicates = [FeatureVectorEnhancements3] in {
506    def : Pat<(type (vselect (inttype (z_vicmpl_zero VR128:$x)),
507                             VR128:$y, VR128:$z)),
508              (blend VR128:$y, VR128:$z, VR128:$x)>;
509    def : Pat<(type (vselect (inttype (z_vnot (z_vicmpl_zero VR128:$x))),
510                             VR128:$y, VR128:$z)),
511              (blend VR128:$z, VR128:$y, VR128:$x)>;
512  }
513}
514
515defm : BlendVectorOps<v16i8, v16i8, VBLENDB>;
516defm : BlendVectorOps<v8i16, v8i16, VBLENDH>;
517defm : BlendVectorOps<v4i32, v4i32, VBLENDF>;
518defm : BlendVectorOps<v2i64, v2i64, VBLENDG>;
519defm : BlendVectorOps<v4f32, v4i32, VBLENDF>;
520defm : BlendVectorOps<v2f64, v2i64, VBLENDG>;
521
522let Predicates = [FeatureVectorEnhancements3] in {
523    def : Pat<(i128 (or (and VR128:$y, (z_vicmph 0, VR128:$x)),
524                        (and VR128:$z, (not (z_vicmph 0, VR128:$x))))),
525              (VBLENDQ VR128:$y, VR128:$z, VR128:$x)>;
526}
527
528//===----------------------------------------------------------------------===//
529// Integer arithmetic
530//===----------------------------------------------------------------------===//
531
532let Predicates = [FeatureVector] in {
533  let isCommutable = 1 in {
534    // Add.
535    def VA  : BinaryVRRcGeneric<"va", 0xE7F3>;
536    def VAB : BinaryVRRc<"vab", 0xE7F3, add, v128b, v128b, 0>;
537    def VAH : BinaryVRRc<"vah", 0xE7F3, add, v128h, v128h, 1>;
538    def VAF : BinaryVRRc<"vaf", 0xE7F3, add, v128f, v128f, 2>;
539    def VAG : BinaryVRRc<"vag", 0xE7F3, add, v128g, v128g, 3>;
540    def VAQ : BinaryVRRc<"vaq", 0xE7F3, add, v128q, v128q, 4>;
541  }
542
543  let isCommutable = 1 in {
544    // Add compute carry.
545    def VACC  : BinaryVRRcGeneric<"vacc", 0xE7F1>;
546    def VACCB : BinaryVRRc<"vaccb", 0xE7F1, z_vacc, v128b, v128b, 0>;
547    def VACCH : BinaryVRRc<"vacch", 0xE7F1, z_vacc, v128h, v128h, 1>;
548    def VACCF : BinaryVRRc<"vaccf", 0xE7F1, z_vacc, v128f, v128f, 2>;
549    def VACCG : BinaryVRRc<"vaccg", 0xE7F1, z_vacc, v128g, v128g, 3>;
550    def VACCQ : BinaryVRRc<"vaccq", 0xE7F1, z_vacc, v128q, v128q, 4>;
551
552    // Add with carry.
553    def VAC  : TernaryVRRdGeneric<"vac", 0xE7BB>;
554    def VACQ : TernaryVRRd<"vacq", 0xE7BB, z_vac, v128q, v128q, 4>;
555
556    // Add with carry compute carry.
557    def VACCC  : TernaryVRRdGeneric<"vaccc", 0xE7B9>;
558    def VACCCQ : TernaryVRRd<"vacccq", 0xE7B9, z_vaccc, v128q, v128q, 4>;
559  }
560
561  // And.
562  let isCommutable = 1 in
563    def VN : BinaryVRRc<"vn", 0xE768, null_frag, v128any, v128any>;
564
565  // And with complement.
566  def VNC : BinaryVRRc<"vnc", 0xE769, null_frag, v128any, v128any>;
567
568  let isCommutable = 1 in {
569    // Average.
570    def VAVG  : BinaryVRRcGeneric<"vavg", 0xE7F2>;
571    def VAVGB : BinaryVRRc<"vavgb", 0xE7F2, int_s390_vavgb, v128b, v128b, 0>;
572    def VAVGH : BinaryVRRc<"vavgh", 0xE7F2, int_s390_vavgh, v128h, v128h, 1>;
573    def VAVGF : BinaryVRRc<"vavgf", 0xE7F2, int_s390_vavgf, v128f, v128f, 2>;
574    def VAVGG : BinaryVRRc<"vavgg", 0xE7F2, int_s390_vavgg, v128g, v128g, 3>;
575    let Predicates = [FeatureVectorEnhancements3] in
576      def VAVGQ : BinaryVRRc<"vavgq", 0xE7F2, int_s390_vavgq, v128q, v128q, 4>;
577
578    // Average logical.
579    def VAVGL  : BinaryVRRcGeneric<"vavgl", 0xE7F0>;
580    def VAVGLB : BinaryVRRc<"vavglb", 0xE7F0, int_s390_vavglb, v128b, v128b, 0>;
581    def VAVGLH : BinaryVRRc<"vavglh", 0xE7F0, int_s390_vavglh, v128h, v128h, 1>;
582    def VAVGLF : BinaryVRRc<"vavglf", 0xE7F0, int_s390_vavglf, v128f, v128f, 2>;
583    def VAVGLG : BinaryVRRc<"vavglg", 0xE7F0, int_s390_vavglg, v128g, v128g, 3>;
584    let Predicates = [FeatureVectorEnhancements3] in
585      def VAVGLQ : BinaryVRRc<"vavglq", 0xE7F0, int_s390_vavglq, v128q, v128q, 4>;
586  }
587
588  // Checksum.
589  def VCKSM : BinaryVRRc<"vcksm", 0xE766, int_s390_vcksm, v128f, v128f>;
590
591  // Count leading zeros.
592  def VCLZ  : UnaryVRRaGeneric<"vclz", 0xE753>;
593  def VCLZB : UnaryVRRa<"vclzb", 0xE753, ctlz, v128b, v128b, 0>;
594  def VCLZH : UnaryVRRa<"vclzh", 0xE753, ctlz, v128h, v128h, 1>;
595  def VCLZF : UnaryVRRa<"vclzf", 0xE753, ctlz, v128f, v128f, 2>;
596  def VCLZG : UnaryVRRa<"vclzg", 0xE753, ctlz, v128g, v128g, 3>;
597  let Predicates = [FeatureVectorEnhancements3] in
598    def VCLZQ : UnaryVRRa<"vclzq", 0xE753, ctlz, v128q, v128q, 4>;
599
600  // Count trailing zeros.
601  def VCTZ  : UnaryVRRaGeneric<"vctz", 0xE752>;
602  def VCTZB : UnaryVRRa<"vctzb", 0xE752, cttz, v128b, v128b, 0>;
603  def VCTZH : UnaryVRRa<"vctzh", 0xE752, cttz, v128h, v128h, 1>;
604  def VCTZF : UnaryVRRa<"vctzf", 0xE752, cttz, v128f, v128f, 2>;
605  def VCTZG : UnaryVRRa<"vctzg", 0xE752, cttz, v128g, v128g, 3>;
606  let Predicates = [FeatureVectorEnhancements3] in
607    def VCTZQ : UnaryVRRa<"vctzq", 0xE752, cttz, v128q, v128q, 4>;
608
609  // Divide.
610  let Predicates = [FeatureVectorEnhancements3] in {
611    let hasSideEffects = 1 in {
612      def VD  : TernaryVRRcIntGeneric<"vd", 0xE7B2>;
613      def VDF : TernaryVRRcInt<"vdf", 0xE7B2, null_frag, v128f, v128f, 2>;
614      def VDG : TernaryVRRcInt<"vdg", 0xE7B2, null_frag, v128g, v128g, 3>;
615      def VDQ : TernaryVRRcInt<"vdq", 0xE7B2, null_frag, v128q, v128q, 4>;
616    }
617    def : Pat<(v4i32 (sdiv VR128:$x, VR128:$y)), (VDF VR128:$x, VR128:$y, 0)>;
618    def : Pat<(v2i64 (sdiv VR128:$x, VR128:$y)), (VDG VR128:$x, VR128:$y, 0)>;
619    def : Pat<(i128 (sdiv VR128:$x, VR128:$y)), (VDQ VR128:$x, VR128:$y, 0)>;
620  }
621
622  // Divide logical.
623  let Predicates = [FeatureVectorEnhancements3] in {
624    let hasSideEffects = 1 in {
625      def VDL  : TernaryVRRcIntGeneric<"vdl", 0xE7B0>;
626      def VDLF : TernaryVRRcInt<"vdlf", 0xE7B0, null_frag, v128f, v128f, 2>;
627      def VDLG : TernaryVRRcInt<"vdlg", 0xE7B0, null_frag, v128g, v128g, 3>;
628      def VDLQ : TernaryVRRcInt<"vdlq", 0xE7B0, null_frag, v128q, v128q, 4>;
629    }
630    def : Pat<(v4i32 (udiv VR128:$x, VR128:$y)), (VDLF VR128:$x, VR128:$y, 0)>;
631    def : Pat<(v2i64 (udiv VR128:$x, VR128:$y)), (VDLG VR128:$x, VR128:$y, 0)>;
632    def : Pat<(i128 (udiv VR128:$x, VR128:$y)), (VDLQ VR128:$x, VR128:$y, 0)>;
633  }
634
635  // Evaluate.
636  let Predicates = [FeatureVectorEnhancements3] in
637    def VEVAL : QuaternaryVRIk<"veval", 0xE788, int_s390_veval, v128b>;
638
639  let isCommutable = 1 in {
640    // Not exclusive or.
641    let Predicates = [FeatureVectorEnhancements1] in
642      def VNX : BinaryVRRc<"vnx", 0xE76C, null_frag, v128any, v128any>;
643
644    // Exclusive or.
645    def VX : BinaryVRRc<"vx", 0xE76D, null_frag, v128any, v128any>;
646  }
647
648  // Galois field multiply sum.
649  def VGFM  : BinaryVRRcGeneric<"vgfm", 0xE7B4>;
650  def VGFMB : BinaryVRRc<"vgfmb", 0xE7B4, int_s390_vgfmb, v128h, v128b, 0>;
651  def VGFMH : BinaryVRRc<"vgfmh", 0xE7B4, int_s390_vgfmh, v128f, v128h, 1>;
652  def VGFMF : BinaryVRRc<"vgfmf", 0xE7B4, int_s390_vgfmf, v128g, v128f, 2>;
653  def VGFMG : BinaryVRRc<"vgfmg", 0xE7B4, int_s390_vgfmg, v128q, v128g, 3>;
654
655  // Galois field multiply sum and accumulate.
656  def VGFMA  : TernaryVRRdGeneric<"vgfma", 0xE7BC>;
657  def VGFMAB : TernaryVRRd<"vgfmab", 0xE7BC, int_s390_vgfmab, v128h, v128b, 0>;
658  def VGFMAH : TernaryVRRd<"vgfmah", 0xE7BC, int_s390_vgfmah, v128f, v128h, 1>;
659  def VGFMAF : TernaryVRRd<"vgfmaf", 0xE7BC, int_s390_vgfmaf, v128g, v128f, 2>;
660  def VGFMAG : TernaryVRRd<"vgfmag", 0xE7BC, int_s390_vgfmag, v128q, v128g, 3>;
661
662  // Load complement.
663  def VLC  : UnaryVRRaGeneric<"vlc", 0xE7DE>;
664  def VLCB : UnaryVRRa<"vlcb", 0xE7DE, z_vneg, v128b, v128b, 0>;
665  def VLCH : UnaryVRRa<"vlch", 0xE7DE, z_vneg, v128h, v128h, 1>;
666  def VLCF : UnaryVRRa<"vlcf", 0xE7DE, z_vneg, v128f, v128f, 2>;
667  def VLCG : UnaryVRRa<"vlcg", 0xE7DE, z_vneg, v128g, v128g, 3>;
668  let Predicates = [FeatureVectorEnhancements3] in
669    def VLCQ : UnaryVRRa<"vlcq", 0xE7DE, ineg, v128q, v128q, 4>;
670
671  // Load positive.
672  def VLP  : UnaryVRRaGeneric<"vlp", 0xE7DF>;
673  def VLPB : UnaryVRRa<"vlpb", 0xE7DF, abs, v128b, v128b, 0>;
674  def VLPH : UnaryVRRa<"vlph", 0xE7DF, abs, v128h, v128h, 1>;
675  def VLPF : UnaryVRRa<"vlpf", 0xE7DF, abs, v128f, v128f, 2>;
676  def VLPG : UnaryVRRa<"vlpg", 0xE7DF, abs, v128g, v128g, 3>;
677  let Predicates = [FeatureVectorEnhancements3] in
678    def VLPQ : UnaryVRRa<"vlpq", 0xE7DF, abs, v128q, v128q, 4>;
679
680  let isCommutable = 1 in {
681    // Maximum.
682    def VMX  : BinaryVRRcGeneric<"vmx", 0xE7FF>;
683    def VMXB : BinaryVRRc<"vmxb", 0xE7FF, null_frag, v128b, v128b, 0>;
684    def VMXH : BinaryVRRc<"vmxh", 0xE7FF, null_frag, v128h, v128h, 1>;
685    def VMXF : BinaryVRRc<"vmxf", 0xE7FF, null_frag, v128f, v128f, 2>;
686    def VMXG : BinaryVRRc<"vmxg", 0xE7FF, null_frag, v128g, v128g, 3>;
687    let Predicates = [FeatureVectorEnhancements3] in
688      def VMXQ : BinaryVRRc<"vmxq", 0xE7FF, null_frag, v128q, v128q, 4>;
689
690    // Maximum logical.
691    def VMXL  : BinaryVRRcGeneric<"vmxl", 0xE7FD>;
692    def VMXLB : BinaryVRRc<"vmxlb", 0xE7FD, null_frag, v128b, v128b, 0>;
693    def VMXLH : BinaryVRRc<"vmxlh", 0xE7FD, null_frag, v128h, v128h, 1>;
694    def VMXLF : BinaryVRRc<"vmxlf", 0xE7FD, null_frag, v128f, v128f, 2>;
695    def VMXLG : BinaryVRRc<"vmxlg", 0xE7FD, null_frag, v128g, v128g, 3>;
696    let Predicates = [FeatureVectorEnhancements3] in
697      def VMXLQ : BinaryVRRc<"vmxlq", 0xE7FD, null_frag, v128q, v128q, 4>;
698  }
699
700  let isCommutable = 1 in {
701    // Minimum.
702    def VMN  : BinaryVRRcGeneric<"vmn", 0xE7FE>;
703    def VMNB : BinaryVRRc<"vmnb", 0xE7FE, null_frag, v128b, v128b, 0>;
704    def VMNH : BinaryVRRc<"vmnh", 0xE7FE, null_frag, v128h, v128h, 1>;
705    def VMNF : BinaryVRRc<"vmnf", 0xE7FE, null_frag, v128f, v128f, 2>;
706    def VMNG : BinaryVRRc<"vmng", 0xE7FE, null_frag, v128g, v128g, 3>;
707    let Predicates = [FeatureVectorEnhancements3] in
708      def VMNQ : BinaryVRRc<"vmnq", 0xE7FE, null_frag, v128q, v128q, 4>;
709
710    // Minimum logical.
711    def VMNL  : BinaryVRRcGeneric<"vmnl", 0xE7FC>;
712    def VMNLB : BinaryVRRc<"vmnlb", 0xE7FC, null_frag, v128b, v128b, 0>;
713    def VMNLH : BinaryVRRc<"vmnlh", 0xE7FC, null_frag, v128h, v128h, 1>;
714    def VMNLF : BinaryVRRc<"vmnlf", 0xE7FC, null_frag, v128f, v128f, 2>;
715    def VMNLG : BinaryVRRc<"vmnlg", 0xE7FC, null_frag, v128g, v128g, 3>;
716    let Predicates = [FeatureVectorEnhancements3] in
717      def VMNLQ : BinaryVRRc<"vmnlq", 0xE7FC, null_frag, v128q, v128q, 4>;
718  }
719
720  let isCommutable = 1 in {
721    // Multiply and add low.
722    def VMAL   : TernaryVRRdGeneric<"vmal", 0xE7AA>;
723    def VMALB  : TernaryVRRd<"vmalb",  0xE7AA, z_muladd<mul>, v128b, v128b, 0>;
724    def VMALHW : TernaryVRRd<"vmalhw", 0xE7AA, z_muladd<mul>, v128h, v128h, 1>;
725    def VMALF  : TernaryVRRd<"vmalf",  0xE7AA, z_muladd<mul>, v128f, v128f, 2>;
726    let Predicates = [FeatureVectorEnhancements3] in {
727      def VMALG : TernaryVRRd<"vmalg",  0xE7AA, z_muladd<mul>, v128g, v128g, 3>;
728      def VMALQ : TernaryVRRd<"vmalq",  0xE7AA, z_muladd<mul>, v128q, v128q, 4>;
729    }
730
731    // Multiply and add high.
732    def VMAH  : TernaryVRRdGeneric<"vmah", 0xE7AB>;
733    def VMAHB : TernaryVRRd<"vmahb", 0xE7AB, z_vmah, v128b, v128b, 0>;
734    def VMAHH : TernaryVRRd<"vmahh", 0xE7AB, z_vmah, v128h, v128h, 1>;
735    def VMAHF : TernaryVRRd<"vmahf", 0xE7AB, z_vmah, v128f, v128f, 2>;
736    let Predicates = [FeatureVectorEnhancements3] in {
737      def VMAHG : TernaryVRRd<"vmahg", 0xE7AB, z_vmah, v128g, v128g, 3>;
738      def VMAHQ : TernaryVRRd<"vmahq", 0xE7AB, z_vmah, v128q, v128q, 4>;
739    }
740
741    // Multiply and add logical high.
742    def VMALH  : TernaryVRRdGeneric<"vmalh", 0xE7A9>;
743    def VMALHB : TernaryVRRd<"vmalhb", 0xE7A9, z_vmalh, v128b, v128b, 0>;
744    def VMALHH : TernaryVRRd<"vmalhh", 0xE7A9, z_vmalh, v128h, v128h, 1>;
745    def VMALHF : TernaryVRRd<"vmalhf", 0xE7A9, z_vmalh, v128f, v128f, 2>;
746    let Predicates = [FeatureVectorEnhancements3] in {
747      def VMALHG : TernaryVRRd<"vmalhg", 0xE7A9, z_vmalh, v128g, v128g, 3>;
748      def VMALHQ : TernaryVRRd<"vmalhq", 0xE7A9, z_vmalh, v128q, v128q, 4>;
749    }
750
751    // Multiply and add even.
752    def VMAE  : TernaryVRRdGeneric<"vmae", 0xE7AE>;
753    def VMAEB : TernaryVRRd<"vmaeb", 0xE7AE, z_muladd<z_vme>, v128h, v128b, 0>;
754    def VMAEH : TernaryVRRd<"vmaeh", 0xE7AE, z_muladd<z_vme>, v128f, v128h, 1>;
755    def VMAEF : TernaryVRRd<"vmaef", 0xE7AE, z_muladd<z_vme>, v128g, v128f, 2>;
756    let Predicates = [FeatureVectorEnhancements3] in
757      def VMAEG : TernaryVRRd<"vmaeg", 0xE7AE, z_muladd<z_vme>, v128q, v128g, 3>;
758
759    // Multiply and add logical even.
760    def VMALE  : TernaryVRRdGeneric<"vmale", 0xE7AC>;
761    def VMALEB : TernaryVRRd<"vmaleb", 0xE7AC, z_muladd<z_vmle>, v128h, v128b, 0>;
762    def VMALEH : TernaryVRRd<"vmaleh", 0xE7AC, z_muladd<z_vmle>, v128f, v128h, 1>;
763    def VMALEF : TernaryVRRd<"vmalef", 0xE7AC, z_muladd<z_vmle>, v128g, v128f, 2>;
764    let Predicates = [FeatureVectorEnhancements3] in
765      def VMALEG : TernaryVRRd<"vmaleg", 0xE7AC, z_muladd<z_vmle>, v128q, v128g, 3>;
766
767    // Multiply and add odd.
768    def VMAO  : TernaryVRRdGeneric<"vmao", 0xE7AF>;
769    def VMAOB : TernaryVRRd<"vmaob", 0xE7AF, z_muladd<z_vmo>, v128h, v128b, 0>;
770    def VMAOH : TernaryVRRd<"vmaoh", 0xE7AF, z_muladd<z_vmo>, v128f, v128h, 1>;
771    def VMAOF : TernaryVRRd<"vmaof", 0xE7AF, z_muladd<z_vmo>, v128g, v128f, 2>;
772    let Predicates = [FeatureVectorEnhancements3] in
773      def VMAOG : TernaryVRRd<"vmaog", 0xE7AF, z_muladd<z_vmo>, v128q, v128g, 3>;
774
775    // Multiply and add logical odd.
776    def VMALO  : TernaryVRRdGeneric<"vmalo", 0xE7AD>;
777    def VMALOB : TernaryVRRd<"vmalob", 0xE7AD, z_muladd<z_vmlo>, v128h, v128b, 0>;
778    def VMALOH : TernaryVRRd<"vmaloh", 0xE7AD, z_muladd<z_vmlo>, v128f, v128h, 1>;
779    def VMALOF : TernaryVRRd<"vmalof", 0xE7AD, z_muladd<z_vmlo>, v128g, v128f, 2>;
780    let Predicates = [FeatureVectorEnhancements3] in
781      def VMALOG : TernaryVRRd<"vmalog", 0xE7AD, z_muladd<z_vmlo>, v128q, v128g, 3>;
782  }
783
784  let isCommutable = 1 in {
785    // Multiply high.
786    def VMH  : BinaryVRRcGeneric<"vmh", 0xE7A3>;
787    def VMHB : BinaryVRRc<"vmhb", 0xE7A3, mulhs, v128b, v128b, 0>;
788    def VMHH : BinaryVRRc<"vmhh", 0xE7A3, mulhs, v128h, v128h, 1>;
789    def VMHF : BinaryVRRc<"vmhf", 0xE7A3, mulhs, v128f, v128f, 2>;
790    let Predicates = [FeatureVectorEnhancements3] in {
791      def VMHG : BinaryVRRc<"vmhg", 0xE7A3, mulhs, v128g, v128g, 3>;
792      def VMHQ : BinaryVRRc<"vmhq", 0xE7A3, mulhs, v128q, v128q, 4>;
793    }
794
795    // Multiply logical high.
796    def VMLH  : BinaryVRRcGeneric<"vmlh", 0xE7A1>;
797    def VMLHB : BinaryVRRc<"vmlhb", 0xE7A1, mulhu, v128b, v128b, 0>;
798    def VMLHH : BinaryVRRc<"vmlhh", 0xE7A1, mulhu, v128h, v128h, 1>;
799    def VMLHF : BinaryVRRc<"vmlhf", 0xE7A1, mulhu, v128f, v128f, 2>;
800    let Predicates = [FeatureVectorEnhancements3] in {
801      def VMLHG : BinaryVRRc<"vmlhg", 0xE7A1, mulhu, v128g, v128g, 3>;
802      def VMLHQ : BinaryVRRc<"vmlhq", 0xE7A1, mulhu, v128q, v128q, 4>;
803    }
804
805    // Multiply low.
806    def VML   : BinaryVRRcGeneric<"vml", 0xE7A2>;
807    def VMLB  : BinaryVRRc<"vmlb",  0xE7A2, mul, v128b, v128b, 0>;
808    def VMLHW : BinaryVRRc<"vmlhw", 0xE7A2, mul, v128h, v128h, 1>;
809    def VMLF  : BinaryVRRc<"vmlf",  0xE7A2, mul, v128f, v128f, 2>;
810    let Predicates = [FeatureVectorEnhancements3] in {
811      def VMLG : BinaryVRRc<"vmlg",  0xE7A2, mul, v128g, v128g, 3>;
812      def VMLQ : BinaryVRRc<"vmlq",  0xE7A2, mul, v128q, v128q, 4>;
813    }
814
815    // Multiply even.
816    def VME  : BinaryVRRcGeneric<"vme", 0xE7A6>;
817    def VMEB : BinaryVRRc<"vmeb", 0xE7A6, z_vme, v128h, v128b, 0>;
818    def VMEH : BinaryVRRc<"vmeh", 0xE7A6, z_vme, v128f, v128h, 1>;
819    def VMEF : BinaryVRRc<"vmef", 0xE7A6, z_vme, v128g, v128f, 2>;
820    let Predicates = [FeatureVectorEnhancements3] in
821      def VMEG : BinaryVRRc<"vmeg", 0xE7A6, z_vme, v128q, v128g, 3>;
822
823    // Multiply logical even.
824    def VMLE  : BinaryVRRcGeneric<"vmle", 0xE7A4>;
825    def VMLEB : BinaryVRRc<"vmleb", 0xE7A4, z_vmle, v128h, v128b, 0>;
826    def VMLEH : BinaryVRRc<"vmleh", 0xE7A4, z_vmle, v128f, v128h, 1>;
827    def VMLEF : BinaryVRRc<"vmlef", 0xE7A4, z_vmle, v128g, v128f, 2>;
828    let Predicates = [FeatureVectorEnhancements3] in
829      def VMLEG : BinaryVRRc<"vmleg", 0xE7A4, z_vmle, v128q, v128g, 3>;
830
831    // Multiply odd.
832    def VMO  : BinaryVRRcGeneric<"vmo", 0xE7A7>;
833    def VMOB : BinaryVRRc<"vmob", 0xE7A7, z_vmo, v128h, v128b, 0>;
834    def VMOH : BinaryVRRc<"vmoh", 0xE7A7, z_vmo, v128f, v128h, 1>;
835    def VMOF : BinaryVRRc<"vmof", 0xE7A7, z_vmo, v128g, v128f, 2>;
836    let Predicates = [FeatureVectorEnhancements3] in
837      def VMOG : BinaryVRRc<"vmog", 0xE7A7, z_vmo, v128q, v128g, 3>;
838
839    // Multiply logical odd.
840    def VMLO  : BinaryVRRcGeneric<"vmlo", 0xE7A5>;
841    def VMLOB : BinaryVRRc<"vmlob", 0xE7A5, z_vmlo, v128h, v128b, 0>;
842    def VMLOH : BinaryVRRc<"vmloh", 0xE7A5, z_vmlo, v128f, v128h, 1>;
843    def VMLOF : BinaryVRRc<"vmlof", 0xE7A5, z_vmlo, v128g, v128f, 2>;
844    let Predicates = [FeatureVectorEnhancements3] in
845      def VMLOG : BinaryVRRc<"vmlog", 0xE7A5, z_vmlo, v128q, v128g, 3>;
846  }
847
848  // Multiply sum logical.
849  let Predicates = [FeatureVectorEnhancements1], isCommutable = 1 in {
850    def VMSL  : QuaternaryVRRdGeneric<"vmsl", 0xE7B8>;
851    def VMSLG : QuaternaryVRRd<"vmslg", 0xE7B8, int_s390_vmslg,
852                               v128q, v128g, v128g, v128q, 3>;
853  }
854
855  // Nand.
856  let Predicates = [FeatureVectorEnhancements1], isCommutable = 1 in
857    def VNN : BinaryVRRc<"vnn", 0xE76E, null_frag, v128any, v128any>;
858
859  // Nor.
860  let isCommutable = 1 in
861    def VNO : BinaryVRRc<"vno", 0xE76B, null_frag, v128any, v128any>;
862  def : InstAlias<"vnot\t$V1, $V2", (VNO VR128:$V1, VR128:$V2, VR128:$V2), 0>;
863
864  // Or.
865  let isCommutable = 1 in
866    def VO : BinaryVRRc<"vo", 0xE76A, null_frag, v128any, v128any>;
867
868  // Or with complement.
869  let Predicates = [FeatureVectorEnhancements1] in
870    def VOC : BinaryVRRc<"voc", 0xE76F, null_frag, v128any, v128any>;
871
872  // Population count.
873  def VPOPCT : UnaryVRRaGeneric<"vpopct", 0xE750>;
874  def : Pat<(v16i8 (z_popcnt VR128:$x)), (VPOPCT VR128:$x, 0)>;
875  let Predicates = [FeatureVectorEnhancements1] in {
876    def VPOPCTB : UnaryVRRa<"vpopctb", 0xE750, ctpop, v128b, v128b, 0>;
877    def VPOPCTH : UnaryVRRa<"vpopcth", 0xE750, ctpop, v128h, v128h, 1>;
878    def VPOPCTF : UnaryVRRa<"vpopctf", 0xE750, ctpop, v128f, v128f, 2>;
879    def VPOPCTG : UnaryVRRa<"vpopctg", 0xE750, ctpop, v128g, v128g, 3>;
880  }
881
882  // Remainder.
883  let Predicates = [FeatureVectorEnhancements3] in {
884    let hasSideEffects = 1 in {
885      def VR  : TernaryVRRcIntGeneric<"vr", 0xE7B3>;
886      def VRF : TernaryVRRcInt<"vrf", 0xE7B3, null_frag, v128f, v128f, 2>;
887      def VRG : TernaryVRRcInt<"vrg", 0xE7B3, null_frag, v128g, v128g, 3>;
888      def VRQ : TernaryVRRcInt<"vrq", 0xE7B3, null_frag, v128q, v128q, 4>;
889    }
890    def : Pat<(v4i32 (srem VR128:$x, VR128:$y)), (VRF VR128:$x, VR128:$y, 0)>;
891    def : Pat<(v2i64 (srem VR128:$x, VR128:$y)), (VRG VR128:$x, VR128:$y, 0)>;
892    def : Pat<(i128 (srem VR128:$x, VR128:$y)), (VRQ VR128:$x, VR128:$y, 0)>;
893  }
894
895  // Remainder logical.
896  let Predicates = [FeatureVectorEnhancements3] in {
897    let hasSideEffects = 1 in {
898      def VRL  : TernaryVRRcIntGeneric<"vrl", 0xE7B1>;
899      def VRLF : TernaryVRRcInt<"vrlf", 0xE7B1, null_frag, v128f, v128f, 2>;
900      def VRLG : TernaryVRRcInt<"vrlg", 0xE7B1, null_frag, v128g, v128g, 3>;
901      def VRLQ : TernaryVRRcInt<"vrlq", 0xE7B1, null_frag, v128q, v128q, 4>;
902    }
903    def : Pat<(v4i32 (urem VR128:$x, VR128:$y)), (VRLF VR128:$x, VR128:$y, 0)>;
904    def : Pat<(v2i64 (urem VR128:$x, VR128:$y)), (VRLG VR128:$x, VR128:$y, 0)>;
905    def : Pat<(i128 (urem VR128:$x, VR128:$y)), (VRLQ VR128:$x, VR128:$y, 0)>;
906  }
907
908  // Element rotate left logical (with vector shift amount).
909  def VERLLV  : BinaryVRRcGeneric<"verllv", 0xE773>;
910  def VERLLVB : BinaryVRRc<"verllvb", 0xE773, rotl, v128b, v128b, 0>;
911  def VERLLVH : BinaryVRRc<"verllvh", 0xE773, rotl, v128h, v128h, 1>;
912  def VERLLVF : BinaryVRRc<"verllvf", 0xE773, rotl, v128f, v128f, 2>;
913  def VERLLVG : BinaryVRRc<"verllvg", 0xE773, rotl, v128g, v128g, 3>;
914
915  // Element rotate left logical (with scalar shift amount).
916  def VERLL  : BinaryVRSaGeneric<"verll", 0xE733>;
917  def VERLLB : BinaryVRSa<"verllb", 0xE733, z_vrotl_by_scalar, v128b, v128b, 0>;
918  def VERLLH : BinaryVRSa<"verllh", 0xE733, z_vrotl_by_scalar, v128h, v128h, 1>;
919  def VERLLF : BinaryVRSa<"verllf", 0xE733, z_vrotl_by_scalar, v128f, v128f, 2>;
920  def VERLLG : BinaryVRSa<"verllg", 0xE733, z_vrotl_by_scalar, v128g, v128g, 3>;
921
922  // Element rotate and insert under mask.
923  def VERIM  : QuaternaryVRIdGeneric<"verim", 0xE772>;
924  def VERIMB : QuaternaryVRId<"verimb", 0xE772, int_s390_verimb, v128b, v128b, 0>;
925  def VERIMH : QuaternaryVRId<"verimh", 0xE772, int_s390_verimh, v128h, v128h, 1>;
926  def VERIMF : QuaternaryVRId<"verimf", 0xE772, int_s390_verimf, v128f, v128f, 2>;
927  def VERIMG : QuaternaryVRId<"verimg", 0xE772, int_s390_verimg, v128g, v128g, 3>;
928
929  // Element shift left (with vector shift amount).
930  def VESLV  : BinaryVRRcGeneric<"veslv", 0xE770>;
931  def VESLVB : BinaryVRRc<"veslvb", 0xE770, z_vshl, v128b, v128b, 0>;
932  def VESLVH : BinaryVRRc<"veslvh", 0xE770, z_vshl, v128h, v128h, 1>;
933  def VESLVF : BinaryVRRc<"veslvf", 0xE770, z_vshl, v128f, v128f, 2>;
934  def VESLVG : BinaryVRRc<"veslvg", 0xE770, z_vshl, v128g, v128g, 3>;
935
936  // Element shift left (with scalar shift amount).
937  def VESL  : BinaryVRSaGeneric<"vesl", 0xE730>;
938  def VESLB : BinaryVRSa<"veslb", 0xE730, z_vshl_by_scalar, v128b, v128b, 0>;
939  def VESLH : BinaryVRSa<"veslh", 0xE730, z_vshl_by_scalar, v128h, v128h, 1>;
940  def VESLF : BinaryVRSa<"veslf", 0xE730, z_vshl_by_scalar, v128f, v128f, 2>;
941  def VESLG : BinaryVRSa<"veslg", 0xE730, z_vshl_by_scalar, v128g, v128g, 3>;
942
943  // Element shift right arithmetic (with vector shift amount).
944  def VESRAV  : BinaryVRRcGeneric<"vesrav", 0xE77A>;
945  def VESRAVB : BinaryVRRc<"vesravb", 0xE77A, z_vsra, v128b, v128b, 0>;
946  def VESRAVH : BinaryVRRc<"vesravh", 0xE77A, z_vsra, v128h, v128h, 1>;
947  def VESRAVF : BinaryVRRc<"vesravf", 0xE77A, z_vsra, v128f, v128f, 2>;
948  def VESRAVG : BinaryVRRc<"vesravg", 0xE77A, z_vsra, v128g, v128g, 3>;
949
950  // Element shift right arithmetic (with scalar shift amount).
951  def VESRA  : BinaryVRSaGeneric<"vesra", 0xE73A>;
952  def VESRAB : BinaryVRSa<"vesrab", 0xE73A, z_vsra_by_scalar, v128b, v128b, 0>;
953  def VESRAH : BinaryVRSa<"vesrah", 0xE73A, z_vsra_by_scalar, v128h, v128h, 1>;
954  def VESRAF : BinaryVRSa<"vesraf", 0xE73A, z_vsra_by_scalar, v128f, v128f, 2>;
955  def VESRAG : BinaryVRSa<"vesrag", 0xE73A, z_vsra_by_scalar, v128g, v128g, 3>;
956
957  // Element shift right logical (with vector shift amount).
958  def VESRLV  : BinaryVRRcGeneric<"vesrlv", 0xE778>;
959  def VESRLVB : BinaryVRRc<"vesrlvb", 0xE778, z_vsrl, v128b, v128b, 0>;
960  def VESRLVH : BinaryVRRc<"vesrlvh", 0xE778, z_vsrl, v128h, v128h, 1>;
961  def VESRLVF : BinaryVRRc<"vesrlvf", 0xE778, z_vsrl, v128f, v128f, 2>;
962  def VESRLVG : BinaryVRRc<"vesrlvg", 0xE778, z_vsrl, v128g, v128g, 3>;
963
964  // Element shift right logical (with scalar shift amount).
965  def VESRL  : BinaryVRSaGeneric<"vesrl", 0xE738>;
966  def VESRLB : BinaryVRSa<"vesrlb", 0xE738, z_vsrl_by_scalar, v128b, v128b, 0>;
967  def VESRLH : BinaryVRSa<"vesrlh", 0xE738, z_vsrl_by_scalar, v128h, v128h, 1>;
968  def VESRLF : BinaryVRSa<"vesrlf", 0xE738, z_vsrl_by_scalar, v128f, v128f, 2>;
969  def VESRLG : BinaryVRSa<"vesrlg", 0xE738, z_vsrl_by_scalar, v128g, v128g, 3>;
970
971  // Shift left.
972  def VSL : BinaryVRRc<"vsl", 0xE774, int_s390_vsl, v128b, v128b>;
973
974  // Shift left by byte.
975  def VSLB : BinaryVRRc<"vslb", 0xE775, int_s390_vslb, v128b, v128b>;
976
977  // Shift left double by byte.
978  def VSLDB : TernaryVRId<"vsldb", 0xE777, z_shl_double, v128b, v128b, 0>;
979  def : Pat<(int_s390_vsldb VR128:$x, VR128:$y, imm32zx8_timm:$z),
980            (VSLDB VR128:$x, VR128:$y, imm32zx8:$z)>;
981
982  // Shift left double by bit.
983  let Predicates = [FeatureVectorEnhancements2] in {
984    def VSLD : TernaryVRId<"vsld", 0xE786, z_shl_double_bit, v128b, v128b, 0>;
985    def : Pat<(int_s390_vsld VR128:$x, VR128:$y, imm32zx8_timm:$z),
986              (VSLD VR128:$x, VR128:$y, imm32zx8:$z)>;
987  }
988
989  // Shift right arithmetic.
990  def VSRA : BinaryVRRc<"vsra", 0xE77E, int_s390_vsra, v128b, v128b>;
991
992  // Shift right arithmetic by byte.
993  def VSRAB : BinaryVRRc<"vsrab", 0xE77F, int_s390_vsrab, v128b, v128b>;
994
995  // Shift right logical.
996  def VSRL : BinaryVRRc<"vsrl", 0xE77C, int_s390_vsrl, v128b, v128b>;
997
998  // Shift right logical by byte.
999  def VSRLB : BinaryVRRc<"vsrlb", 0xE77D, int_s390_vsrlb, v128b, v128b>;
1000
1001  // Shift right double by bit.
1002  let Predicates = [FeatureVectorEnhancements2] in {
1003    def VSRD : TernaryVRId<"vsrd", 0xE787, z_shr_double_bit, v128b, v128b, 0>;
1004    def : Pat<(int_s390_vsrd VR128:$x, VR128:$y, imm32zx8_timm:$z),
1005              (VSRD VR128:$x, VR128:$y, imm32zx8:$z)>;
1006  }
1007
1008  // Subtract.
1009  def VS  : BinaryVRRcGeneric<"vs", 0xE7F7>;
1010  def VSB : BinaryVRRc<"vsb", 0xE7F7, sub, v128b, v128b, 0>;
1011  def VSH : BinaryVRRc<"vsh", 0xE7F7, sub, v128h, v128h, 1>;
1012  def VSF : BinaryVRRc<"vsf", 0xE7F7, sub, v128f, v128f, 2>;
1013  def VSG : BinaryVRRc<"vsg", 0xE7F7, sub, v128g, v128g, 3>;
1014  def VSQ : BinaryVRRc<"vsq", 0xE7F7, sub, v128q, v128q, 4>;
1015
1016  // Subtract compute borrow indication.
1017  def VSCBI  : BinaryVRRcGeneric<"vscbi", 0xE7F5>;
1018  def VSCBIB : BinaryVRRc<"vscbib", 0xE7F5, z_vscbi, v128b, v128b, 0>;
1019  def VSCBIH : BinaryVRRc<"vscbih", 0xE7F5, z_vscbi, v128h, v128h, 1>;
1020  def VSCBIF : BinaryVRRc<"vscbif", 0xE7F5, z_vscbi, v128f, v128f, 2>;
1021  def VSCBIG : BinaryVRRc<"vscbig", 0xE7F5, z_vscbi, v128g, v128g, 3>;
1022  def VSCBIQ : BinaryVRRc<"vscbiq", 0xE7F5, z_vscbi, v128q, v128q, 4>;
1023
1024  // Subtract with borrow indication.
1025  def VSBI  : TernaryVRRdGeneric<"vsbi", 0xE7BF>;
1026  def VSBIQ : TernaryVRRd<"vsbiq", 0xE7BF, z_vsbi, v128q, v128q, 4>;
1027
1028  // Subtract with borrow compute borrow indication.
1029  def VSBCBI  : TernaryVRRdGeneric<"vsbcbi", 0xE7BD>;
1030  def VSBCBIQ : TernaryVRRd<"vsbcbiq", 0xE7BD, z_vsbcbi, v128q, v128q, 4>;
1031
1032  // Sum across doubleword.
1033  def VSUMG  : BinaryVRRcGeneric<"vsumg", 0xE765>;
1034  def VSUMGH : BinaryVRRc<"vsumgh", 0xE765, z_vsum, v128g, v128h, 1>;
1035  def VSUMGF : BinaryVRRc<"vsumgf", 0xE765, z_vsum, v128g, v128f, 2>;
1036
1037  // Sum across quadword.
1038  def VSUMQ  : BinaryVRRcGeneric<"vsumq", 0xE767>;
1039  def VSUMQF : BinaryVRRc<"vsumqf", 0xE767, z_vsum, v128q, v128f, 2>;
1040  def VSUMQG : BinaryVRRc<"vsumqg", 0xE767, z_vsum, v128q, v128g, 3>;
1041
1042  // Sum across word.
1043  def VSUM  : BinaryVRRcGeneric<"vsum", 0xE764>;
1044  def VSUMB : BinaryVRRc<"vsumb", 0xE764, z_vsum, v128f, v128b, 0>;
1045  def VSUMH : BinaryVRRc<"vsumh", 0xE764, z_vsum, v128f, v128h, 1>;
1046}
1047
1048// Instantiate the bitwise ops for type TYPE.
1049multiclass BitwiseVectorOps<ValueType type, SDPatternOperator not_op> {
1050  let Predicates = [FeatureVector] in {
1051    def : Pat<(type (and VR128:$x, VR128:$y)), (VN VR128:$x, VR128:$y)>;
1052    def : Pat<(type (and VR128:$x, (not_op VR128:$y))),
1053              (VNC VR128:$x, VR128:$y)>;
1054    def : Pat<(type (or VR128:$x, VR128:$y)), (VO VR128:$x, VR128:$y)>;
1055    def : Pat<(type (xor VR128:$x, VR128:$y)), (VX VR128:$x, VR128:$y)>;
1056    def : Pat<(type (or (and VR128:$x, VR128:$z),
1057                        (and VR128:$y, (not_op VR128:$z)))),
1058              (VSEL VR128:$x, VR128:$y, VR128:$z)>;
1059    def : Pat<(type (not_op (or VR128:$x, VR128:$y))),
1060              (VNO VR128:$x, VR128:$y)>;
1061    def : Pat<(type (not_op VR128:$x)), (VNO VR128:$x, VR128:$x)>;
1062  }
1063  let Predicates = [FeatureVectorEnhancements1] in {
1064    def : Pat<(type (not_op (xor VR128:$x, VR128:$y))),
1065              (VNX VR128:$x, VR128:$y)>;
1066    def : Pat<(type (not_op (and VR128:$x, VR128:$y))),
1067              (VNN VR128:$x, VR128:$y)>;
1068    def : Pat<(type (or VR128:$x, (not_op VR128:$y))),
1069              (VOC VR128:$x, VR128:$y)>;
1070  }
1071  let Predicates = [FeatureVectorEnhancements3] in {
1072    def : Pat<(type (and VR128:$x, (and VR128:$y, VR128:$z))),
1073              (VEVAL VR128:$x, VR128:$y, VR128:$z, 1)>;
1074    def : Pat<(type (and (not_op VR128:$z), (and VR128:$x, VR128:$y))),
1075              (VEVAL VR128:$x, VR128:$y, VR128:$z, 2)>;
1076    def : Pat<(type (and VR128:$x, (xor VR128:$y, VR128:$z))),
1077              (VEVAL VR128:$x, VR128:$y, VR128:$z, 6)>;
1078    def : Pat<(type (and VR128:$x, (or VR128:$y, VR128:$z))),
1079              (VEVAL VR128:$x, VR128:$y, VR128:$z, 7)>;
1080    def : Pat<(type (and VR128:$x, (not_op (or VR128:$y, VR128:$z)))),
1081              (VEVAL VR128:$x, VR128:$y, VR128:$z, 8)>;
1082    def : Pat<(type (and VR128:$x, (not_op (xor VR128:$y, VR128:$z)))),
1083              (VEVAL VR128:$x, VR128:$y, VR128:$z, 9)>;
1084    def : Pat<(type (and VR128:$x, (or VR128:$y, (not_op VR128:$z)))),
1085              (VEVAL VR128:$x, VR128:$y, VR128:$z, 11)>;
1086    def : Pat<(type (and VR128:$x, (not_op (and VR128:$y, VR128:$z)))),
1087              (VEVAL VR128:$x, VR128:$y, VR128:$z, 14)>;
1088    def : Pat<(type (and (or VR128:$x, VR128:$y), (xor VR128:$z, (and VR128:$x, VR128:$y)))),
1089              (VEVAL VR128:$x, VR128:$y, VR128:$z, 22)>;
1090    def : Pat<(type (or (and VR128:$x, VR128:$y), (and VR128:$z, (or VR128:$x, VR128:$y)))),
1091              (VEVAL VR128:$x, VR128:$y, VR128:$z, 23)>;
1092    def : Pat<(type (and (xor VR128:$x, VR128:$y), (xor VR128:$x, VR128:$z))),
1093              (VEVAL VR128:$x, VR128:$y, VR128:$z, 24)>;
1094    def : Pat<(type (and (or VR128:$x, VR128:$y), (not_op (xor VR128:$y, VR128:$z)))),
1095              (VEVAL VR128:$x, VR128:$y, VR128:$z, 25)>;
1096    def : Pat<(type (and (or VR128:$x, VR128:$y), (xor VR128:$x, VR128:$z))),
1097              (VEVAL VR128:$x, VR128:$y, VR128:$z, 26)>;
1098    def : Pat<(type (and (or VR128:$x, VR128:$z), (or VR128:$y, (not_op VR128:$z)))),
1099              (VEVAL VR128:$x, VR128:$y, VR128:$z, 27)>;
1100    def : Pat<(type (xor VR128:$x, (and VR128:$y, VR128:$z))),
1101              (VEVAL VR128:$x, VR128:$y, VR128:$z, 30)>;
1102    def : Pat<(type (or VR128:$x, (and VR128:$y, VR128:$z))),
1103              (VEVAL VR128:$x, VR128:$y, VR128:$z, 31)>;
1104    def : Pat<(type (and (not_op VR128:$z), (xor VR128:$x, VR128:$y))),
1105              (VEVAL VR128:$x, VR128:$y, VR128:$z, 40)>;
1106    def : Pat<(type (and (or VR128:$x, VR128:$y), (not_op (xor VR128:$z, (and VR128:$x, VR128:$y))))),
1107              (VEVAL VR128:$x, VR128:$y, VR128:$z, 41)>;
1108    def : Pat<(type (and (not_op VR128:$z), (or VR128:$x, VR128:$y))),
1109              (VEVAL VR128:$x, VR128:$y, VR128:$z, 42)>;
1110    def : Pat<(type (or (and VR128:$x, VR128:$y), (and (not_op VR128:$z), (or VR128:$x, VR128:$y)))),
1111              (VEVAL VR128:$x, VR128:$y, VR128:$z, 43)>;
1112    def : Pat<(type (xor VR128:$y, (or VR128:$x, (and VR128:$y, VR128:$z)))),
1113              (VEVAL VR128:$x, VR128:$y, VR128:$z, 44)>;
1114    def : Pat<(type (xor VR128:$x, (and VR128:$y, (not_op VR128:$z)))),
1115              (VEVAL VR128:$x, VR128:$y, VR128:$z, 45)>;
1116    def : Pat<(type (and (or VR128:$x, VR128:$y), (not_op (and VR128:$y, VR128:$z)))),
1117              (VEVAL VR128:$x, VR128:$y, VR128:$z, 46)>;
1118    def : Pat<(type (or VR128:$x, (and VR128:$y, (not_op VR128:$z)))),
1119              (VEVAL VR128:$x, VR128:$y, VR128:$z, 47)>;
1120    def : Pat<(type (or (xor VR128:$x, VR128:$y), (and VR128:$x, VR128:$z))),
1121              (VEVAL VR128:$x, VR128:$y, VR128:$z, 61)>;
1122    def : Pat<(type (or (xor VR128:$x, VR128:$y), (and VR128:$x, (not_op VR128:$z)))),
1123              (VEVAL VR128:$x, VR128:$y, VR128:$z, 62)>;
1124    def : Pat<(type (xor (or VR128:$x, VR128:$y), (or VR128:$z, (and VR128:$x, VR128:$y)))),
1125              (VEVAL VR128:$x, VR128:$y, VR128:$z, 104)>;
1126    def : Pat<(type (xor VR128:$x, (xor VR128:$y, VR128:$z))),
1127              (VEVAL VR128:$x, VR128:$y, VR128:$z, 105)>;
1128    def : Pat<(type (xor VR128:$z, (or VR128:$x, VR128:$y))),
1129              (VEVAL VR128:$x, VR128:$y, VR128:$z, 106)>;
1130    def : Pat<(type (or (and VR128:$x, VR128:$y), (xor VR128:$z, (or VR128:$x, VR128:$y)))),
1131              (VEVAL VR128:$x, VR128:$y, VR128:$z, 107)>;
1132    def : Pat<(type (or (xor VR128:$y, VR128:$z), (and VR128:$x, (not_op VR128:$y)))),
1133              (VEVAL VR128:$x, VR128:$y, VR128:$z, 110)>;
1134    def : Pat<(type (or VR128:$x, (xor VR128:$y, VR128:$z))),
1135              (VEVAL VR128:$x, VR128:$y, VR128:$z, 111)>;
1136    def : Pat<(type (or (xor VR128:$x, VR128:$y), (xor VR128:$x, VR128:$z))),
1137              (VEVAL VR128:$x, VR128:$y, VR128:$z, 126)>;
1138    def : Pat<(type (or VR128:$x, (or VR128:$y, VR128:$z))),
1139              (VEVAL VR128:$x, VR128:$y, VR128:$z, 127)>;
1140    def : Pat<(type (not_op (or VR128:$x, (or VR128:$y, VR128:$z)))),
1141              (VEVAL VR128:$x, VR128:$y, VR128:$z, 128)>;
1142    def : Pat<(type (not_op (or (xor VR128:$x, VR128:$y), (xor VR128:$x, VR128:$z)))),
1143              (VEVAL VR128:$x, VR128:$y, VR128:$z, 129)>;
1144    def : Pat<(type (not_op (or VR128:$z, (xor VR128:$x, VR128:$y)))),
1145              (VEVAL VR128:$x, VR128:$y, VR128:$z, 130)>;
1146    def : Pat<(type (and (not_op (xor VR128:$x, VR128:$y)), (or VR128:$x, (not_op VR128:$z)))),
1147              (VEVAL VR128:$x, VR128:$y, VR128:$z, 131)>;
1148    def : Pat<(type (xor (or VR128:$y, VR128:$z), (or (not_op VR128:$x), (and VR128:$y, VR128:$z)))),
1149              (VEVAL VR128:$x, VR128:$y, VR128:$z, 134)>;
1150    def : Pat<(type (not_op (xor VR128:$x, (or VR128:$y, VR128:$z)))),
1151              (VEVAL VR128:$x, VR128:$y, VR128:$z, 135)>;
1152    def : Pat<(type (or (not_op (or VR128:$y, VR128:$z)), (and VR128:$x, (and VR128:$y, VR128:$z)))),
1153              (VEVAL VR128:$x, VR128:$y, VR128:$z, 137)>;
1154    def : Pat<(type (and (not_op VR128:$z), (or VR128:$x, (not_op VR128:$y)))),
1155              (VEVAL VR128:$x, VR128:$y, VR128:$z, 138)>;
1156    def : Pat<(type (or (and VR128:$x, VR128:$y), (not_op (or VR128:$y, VR128:$z)))),
1157              (VEVAL VR128:$x, VR128:$y, VR128:$z, 139)>;
1158    def : Pat<(type (or (not_op (or VR128:$y, VR128:$z)), (and VR128:$x, (xor VR128:$y, VR128:$z)))),
1159              (VEVAL VR128:$x, VR128:$y, VR128:$z, 142)>;
1160    def : Pat<(type (or VR128:$x, (not_op (or VR128:$y, VR128:$z)))),
1161              (VEVAL VR128:$x, VR128:$y, VR128:$z, 143)>;
1162    def : Pat<(type (not_op (xor VR128:$x, (xor VR128:$y, VR128:$z)))),
1163              (VEVAL VR128:$x, VR128:$y, VR128:$z, 150)>;
1164    def : Pat<(type (or (and VR128:$x, VR128:$y), (not_op (xor VR128:$z, (or VR128:$x, VR128:$y))))),
1165              (VEVAL VR128:$x, VR128:$y, VR128:$z, 151)>;
1166    def : Pat<(type (not_op (or (and VR128:$x, VR128:$y), (xor VR128:$y, VR128:$z)))),
1167              (VEVAL VR128:$x, VR128:$y, VR128:$z, 152)>;
1168    def : Pat<(type (xor VR128:$z, (or VR128:$x, (not_op VR128:$y)))),
1169              (VEVAL VR128:$x, VR128:$y, VR128:$z, 154)>;
1170    def : Pat<(type (or (and VR128:$x, VR128:$y), (not_op (xor VR128:$y, VR128:$z)))),
1171              (VEVAL VR128:$x, VR128:$y, VR128:$z, 155)>;
1172    def : Pat<(type (or (not_op (or VR128:$y, VR128:$z)), (xor VR128:$x, (and VR128:$y, VR128:$z)))),
1173              (VEVAL VR128:$x, VR128:$y, VR128:$z, 158)>;
1174    def : Pat<(type (or VR128:$x, (not_op (xor VR128:$y, VR128:$z)))),
1175              (VEVAL VR128:$x, VR128:$y, VR128:$z, 159)>;
1176    def : Pat<(type (not_op (or VR128:$z, (and VR128:$x, VR128:$y)))),
1177              (VEVAL VR128:$x, VR128:$y, VR128:$z, 168)>;
1178    def : Pat<(type (not_op (xor VR128:$z, (and VR128:$x, VR128:$y)))),
1179              (VEVAL VR128:$x, VR128:$y, VR128:$z, 169)>;
1180    def : Pat<(type (or (not_op VR128:$z), (and VR128:$x, VR128:$y))),
1181              (VEVAL VR128:$x, VR128:$y, VR128:$z, 171)>;
1182    def : Pat<(type (and (not_op (and VR128:$x, VR128:$y)), (or VR128:$x, (not_op VR128:$z)))),
1183              (VEVAL VR128:$x, VR128:$y, VR128:$z, 172)>;
1184    def : Pat<(type (not_op (and (xor VR128:$x, VR128:$z), (or VR128:$y, VR128:$z)))),
1185              (VEVAL VR128:$x, VR128:$y, VR128:$z, 173)>;
1186    def : Pat<(type (or (not_op VR128:$z), (and VR128:$x, (not_op VR128:$y)))),
1187              (VEVAL VR128:$x, VR128:$y, VR128:$z, 174)>;
1188    def : Pat<(type (or (xor VR128:$x, VR128:$y), (not_op (or VR128:$x, VR128:$z)))),
1189              (VEVAL VR128:$x, VR128:$y, VR128:$z, 188)>;
1190    def : Pat<(type (not_op (and (xor VR128:$x, VR128:$z), (xor VR128:$y, VR128:$z)))),
1191              (VEVAL VR128:$x, VR128:$y, VR128:$z, 189)>;
1192    def : Pat<(type (or (not_op VR128:$z), (xor VR128:$x, VR128:$y))),
1193              (VEVAL VR128:$x, VR128:$y, VR128:$z, 190)>;
1194    def : Pat<(type (or (not_op VR128:$z), (or VR128:$x, VR128:$y))),
1195              (VEVAL VR128:$x, VR128:$y, VR128:$z, 191)>;
1196    def : Pat<(type (or (not_op (or VR128:$x, VR128:$y)), (and (not_op VR128:$z), (xor VR128:$x, VR128:$y)))),
1197              (VEVAL VR128:$x, VR128:$y, VR128:$z, 232)>;
1198    def : Pat<(type (xor (not_op (and VR128:$x, VR128:$y)), (and VR128:$z, (or VR128:$x, VR128:$y)))),
1199              (VEVAL VR128:$x, VR128:$y, VR128:$z, 233)>;
1200    def : Pat<(type (not_op (and VR128:$z, (or VR128:$x, VR128:$y)))),
1201              (VEVAL VR128:$x, VR128:$y, VR128:$z, 234)>;
1202    def : Pat<(type (not_op (and VR128:$z, (xor VR128:$x, VR128:$y)))),
1203              (VEVAL VR128:$x, VR128:$y, VR128:$z, 235)>;
1204    def : Pat<(type (or VR128:$x, (not_op (and VR128:$y, VR128:$z)))),
1205              (VEVAL VR128:$x, VR128:$y, VR128:$z, 239)>;
1206    def : Pat<(type (not_op (and VR128:$x, (and VR128:$y, VR128:$z)))),
1207              (VEVAL VR128:$x, VR128:$y, VR128:$z, 254)>;
1208  }
1209}
1210
1211defm : BitwiseVectorOps<v16i8, z_vnot>;
1212defm : BitwiseVectorOps<v8i16, z_vnot>;
1213defm : BitwiseVectorOps<v4i32, z_vnot>;
1214defm : BitwiseVectorOps<v2i64, z_vnot>;
1215defm : BitwiseVectorOps<i128, not>;
1216
1217// Instantiate additional patterns for absolute-related expressions on
1218// type TYPE.  LC is the negate instruction for TYPE and LP is the absolute
1219// instruction.
1220multiclass IntegerAbsoluteVectorOps<ValueType type, Instruction lc,
1221                                    Instruction lp, int shift> {
1222  let Predicates = [FeatureVector] in {
1223    def : Pat<(type (vselect (type (z_vicmph_zero VR128:$x)),
1224                             (z_vneg VR128:$x), VR128:$x)),
1225              (lc (lp VR128:$x))>;
1226    def : Pat<(type (vselect (type (z_vnot (z_vicmph_zero VR128:$x))),
1227                             VR128:$x, (z_vneg VR128:$x))),
1228              (lc (lp VR128:$x))>;
1229    def : Pat<(type (vselect (type (z_vicmpl_zero VR128:$x)),
1230                             VR128:$x, (z_vneg VR128:$x))),
1231              (lc (lp VR128:$x))>;
1232    def : Pat<(type (vselect (type (z_vnot (z_vicmpl_zero VR128:$x))),
1233                             (z_vneg VR128:$x), VR128:$x)),
1234              (lc (lp VR128:$x))>;
1235    def : Pat<(type (or (and (z_vsra_by_scalar VR128:$x, (i32 shift)),
1236                             (z_vneg VR128:$x)),
1237                        (and (z_vnot (z_vsra_by_scalar VR128:$x, (i32 shift))),
1238                             VR128:$x))),
1239              (lp VR128:$x)>;
1240    def : Pat<(type (or (and (z_vsra_by_scalar VR128:$x, (i32 shift)),
1241                             VR128:$x),
1242                        (and (z_vnot (z_vsra_by_scalar VR128:$x, (i32 shift))),
1243                             (z_vneg VR128:$x)))),
1244              (lc (lp VR128:$x))>;
1245  }
1246}
1247
1248defm : IntegerAbsoluteVectorOps<v16i8, VLCB, VLPB, 7>;
1249defm : IntegerAbsoluteVectorOps<v8i16, VLCH, VLPH, 15>;
1250defm : IntegerAbsoluteVectorOps<v4i32, VLCF, VLPF, 31>;
1251defm : IntegerAbsoluteVectorOps<v2i64, VLCG, VLPG, 63>;
1252
1253// Instantiate minimum- and maximum-related patterns for TYPE.  CMPH is the
1254// signed or unsigned "set if greater than" comparison instruction and
1255// MIN and MAX are the associated minimum and maximum instructions.
1256multiclass IntegerMinMaxVectorOps<ValueType type, SDPatternOperator cmph,
1257                                  Instruction min, Instruction max> {
1258  let Predicates = [FeatureVector] in {
1259    def : Pat<(type (vselect (cmph VR128:$x, VR128:$y), VR128:$x, VR128:$y)),
1260              (max VR128:$x, VR128:$y)>;
1261    def : Pat<(type (vselect (cmph VR128:$x, VR128:$y), VR128:$y, VR128:$x)),
1262              (min VR128:$x, VR128:$y)>;
1263    def : Pat<(type (vselect (z_vnot (cmph VR128:$x, VR128:$y)),
1264                             VR128:$x, VR128:$y)),
1265              (min VR128:$x, VR128:$y)>;
1266    def : Pat<(type (vselect (z_vnot (cmph VR128:$x, VR128:$y)),
1267                             VR128:$y, VR128:$x)),
1268              (max VR128:$x, VR128:$y)>;
1269  }
1270}
1271
1272// Signed min/max.
1273defm : IntegerMinMaxVectorOps<v16i8, z_vicmph, VMNB, VMXB>;
1274defm : IntegerMinMaxVectorOps<v8i16, z_vicmph, VMNH, VMXH>;
1275defm : IntegerMinMaxVectorOps<v4i32, z_vicmph, VMNF, VMXF>;
1276defm : IntegerMinMaxVectorOps<v2i64, z_vicmph, VMNG, VMXG>;
1277
1278let Predicates = [FeatureVectorEnhancements3] in {
1279  def : Pat<(i128 (or (and VR128:$x, (z_vicmph VR128:$x, VR128:$y)),
1280                      (and VR128:$y, (not (z_vicmph VR128:$x, VR128:$y))))),
1281            (VMXQ VR128:$x, VR128:$y)>;
1282  def : Pat<(i128 (or (and VR128:$y, (z_vicmph VR128:$x, VR128:$y)),
1283                      (and VR128:$x, (not (z_vicmph VR128:$x, VR128:$y))))),
1284            (VMNQ VR128:$x, VR128:$y)>;
1285}
1286
1287// Unsigned min/max.
1288defm : IntegerMinMaxVectorOps<v16i8, z_vicmphl, VMNLB, VMXLB>;
1289defm : IntegerMinMaxVectorOps<v8i16, z_vicmphl, VMNLH, VMXLH>;
1290defm : IntegerMinMaxVectorOps<v4i32, z_vicmphl, VMNLF, VMXLF>;
1291defm : IntegerMinMaxVectorOps<v2i64, z_vicmphl, VMNLG, VMXLG>;
1292
1293let Predicates = [FeatureVectorEnhancements3] in {
1294  def : Pat<(i128 (or (and VR128:$x, (z_vicmphl VR128:$x, VR128:$y)),
1295                      (and VR128:$y, (not (z_vicmphl VR128:$x, VR128:$y))))),
1296            (VMXLQ VR128:$x, VR128:$y)>;
1297  def : Pat<(i128 (or (and VR128:$y, (z_vicmphl VR128:$x, VR128:$y)),
1298                      (and VR128:$x, (not (z_vicmphl VR128:$x, VR128:$y))))),
1299            (VMNLQ VR128:$x, VR128:$y)>;
1300}
1301
1302// Instantiate comparison patterns to recognize VACC/VSCBI for TYPE.
1303multiclass IntegerComputeCarryOrBorrow<ValueType type,
1304                                       Instruction vacc, Instruction vscbi> {
1305  let Predicates = [FeatureVector] in {
1306    def : Pat<(z_vzext1 (type (z_vicmphl VR128:$x, (add VR128:$x, VR128:$y)))),
1307              (vacc VR128:$x, VR128:$y)>;
1308    def : Pat<(z_vzext1 (type (z_vicmphl VR128:$y, (add VR128:$x, VR128:$y)))),
1309              (vacc VR128:$x, VR128:$y)>;
1310    def : Pat<(z_vzext1 (z_vnot (type (z_vicmphl VR128:$y, VR128:$x)))),
1311              (vscbi VR128:$x, VR128:$y)>;
1312  }
1313}
1314defm : IntegerComputeCarryOrBorrow<v16i8, VACCB, VSCBIB>;
1315defm : IntegerComputeCarryOrBorrow<v8i16, VACCH, VSCBIH>;
1316defm : IntegerComputeCarryOrBorrow<v4i32, VACCF, VSCBIF>;
1317defm : IntegerComputeCarryOrBorrow<v2i64, VACCG, VSCBIG>;
1318
1319// Instantiate full-vector shifts.
1320multiclass FullVectorShiftOps<SDPatternOperator shift,
1321                              Instruction sbit, Instruction sbyte> {
1322  let Predicates = [FeatureVector] in {
1323    def : Pat<(shift (i128 VR128:$x), imm32nobytes:$amt),
1324              (sbit VR128:$x, (VREPIB (UIMM8 imm:$amt)))>;
1325    def : Pat<(shift (i128 VR128:$x), imm32nobits:$amt),
1326              (sbyte VR128:$x, (VREPIB (UIMM8 imm:$amt)))>;
1327    def : Pat<(shift (i128 VR128:$x), imm32:$amt),
1328              (sbit (sbyte VR128:$x, (VREPIB (UIMM8 imm:$amt))),
1329                    (VREPIB (UIMM8 imm:$amt)))>;
1330    def : Pat<(shift (i128 VR128:$x), GR32:$amt),
1331              (sbit (sbyte VR128:$x, (VREPB (VLVGP32 GR32:$amt, GR32:$amt), 15)),
1332                    (VREPB (VLVGP32 GR32:$amt, GR32:$amt), 15))>;
1333  }
1334}
1335defm : FullVectorShiftOps<vshiftop<shl>, VSL, VSLB>;
1336defm : FullVectorShiftOps<vshiftop<srl>, VSRL, VSRLB>;
1337defm : FullVectorShiftOps<vshiftop<sra>, VSRA, VSRAB>;
1338
1339//===----------------------------------------------------------------------===//
1340// Integer comparison
1341//===----------------------------------------------------------------------===//
1342
1343let Predicates = [FeatureVector] in {
1344  // Element compare.
1345  let Defs = [CC] in {
1346    def VEC  : CompareVRRaGeneric<"vec", 0xE7DB>;
1347    def VECB : CompareVRRa<"vecb", 0xE7DB, null_frag, v128b, 0>;
1348    def VECH : CompareVRRa<"vech", 0xE7DB, null_frag, v128h, 1>;
1349    def VECF : CompareVRRa<"vecf", 0xE7DB, null_frag, v128f, 2>;
1350    def VECG : CompareVRRa<"vecg", 0xE7DB, null_frag, v128g, 3>;
1351    let Predicates = [FeatureVectorEnhancements3] in
1352      def VECQ : CompareVRRa<"vecq", 0xE7DB, z_scmp, v128q, 4>;
1353  }
1354
1355  // Element compare logical.
1356  let Defs = [CC] in {
1357    def VECL  : CompareVRRaGeneric<"vecl", 0xE7D9>;
1358    def VECLB : CompareVRRa<"veclb", 0xE7D9, null_frag, v128b, 0>;
1359    def VECLH : CompareVRRa<"veclh", 0xE7D9, null_frag, v128h, 1>;
1360    def VECLF : CompareVRRa<"veclf", 0xE7D9, null_frag, v128f, 2>;
1361    def VECLG : CompareVRRa<"veclg", 0xE7D9, null_frag, v128g, 3>;
1362    let Predicates = [FeatureVectorEnhancements3] in
1363      def VECLQ : CompareVRRa<"veclq", 0xE7D9, z_ucmp, v128q, 4>;
1364  }
1365
1366  // Compare equal.
1367  def  VCEQ  : BinaryVRRbSPairGeneric<"vceq", 0xE7F8>;
1368  defm VCEQB : BinaryVRRbSPair<"vceqb", 0xE7F8, z_vicmpe, z_vicmpes,
1369                               v128b, v128b, 0>;
1370  defm VCEQH : BinaryVRRbSPair<"vceqh", 0xE7F8, z_vicmpe, z_vicmpes,
1371                               v128h, v128h, 1>;
1372  defm VCEQF : BinaryVRRbSPair<"vceqf", 0xE7F8, z_vicmpe, z_vicmpes,
1373                               v128f, v128f, 2>;
1374  defm VCEQG : BinaryVRRbSPair<"vceqg", 0xE7F8, z_vicmpe, z_vicmpes,
1375                               v128g, v128g, 3>;
1376  let Predicates = [FeatureVectorEnhancements3] in
1377    defm VCEQQ : BinaryVRRbSPair<"vceqq", 0xE7F8, z_vicmpe, z_vicmpes,
1378                                 v128q, v128q, 4>;
1379
1380  // Compare high.
1381  def  VCH  : BinaryVRRbSPairGeneric<"vch", 0xE7FB>;
1382  defm VCHB : BinaryVRRbSPair<"vchb", 0xE7FB, z_vicmph, z_vicmphs,
1383                              v128b, v128b, 0>;
1384  defm VCHH : BinaryVRRbSPair<"vchh", 0xE7FB, z_vicmph, z_vicmphs,
1385                              v128h, v128h, 1>;
1386  defm VCHF : BinaryVRRbSPair<"vchf", 0xE7FB, z_vicmph, z_vicmphs,
1387                              v128f, v128f, 2>;
1388  defm VCHG : BinaryVRRbSPair<"vchg", 0xE7FB, z_vicmph, z_vicmphs,
1389                              v128g, v128g, 3>;
1390  let Predicates = [FeatureVectorEnhancements3] in
1391    defm VCHQ : BinaryVRRbSPair<"vchq", 0xE7FB, z_vicmph, z_vicmphs,
1392                                v128q, v128q, 4>;
1393
1394  // Compare high logical.
1395  def  VCHL  : BinaryVRRbSPairGeneric<"vchl", 0xE7F9>;
1396  defm VCHLB : BinaryVRRbSPair<"vchlb", 0xE7F9, z_vicmphl, z_vicmphls,
1397                               v128b, v128b, 0>;
1398  defm VCHLH : BinaryVRRbSPair<"vchlh", 0xE7F9, z_vicmphl, z_vicmphls,
1399                               v128h, v128h, 1>;
1400  defm VCHLF : BinaryVRRbSPair<"vchlf", 0xE7F9, z_vicmphl, z_vicmphls,
1401                               v128f, v128f, 2>;
1402  defm VCHLG : BinaryVRRbSPair<"vchlg", 0xE7F9, z_vicmphl, z_vicmphls,
1403                               v128g, v128g, 3>;
1404  let Predicates = [FeatureVectorEnhancements3] in
1405    defm VCHLQ : BinaryVRRbSPair<"vchlq", 0xE7F9, z_vicmphl, z_vicmphls,
1406                                 v128q, v128q, 4>;
1407
1408  // Test under mask.
1409  let Defs = [CC] in
1410    def VTM : CompareVRRa<"vtm", 0xE7D8, z_vtm, v128b, 0>;
1411}
1412
1413//===----------------------------------------------------------------------===//
1414// Floating-point arithmetic
1415//===----------------------------------------------------------------------===//
1416
1417// See comments in SystemZInstrFP.td for the suppression flags and
1418// rounding modes.
1419multiclass VectorRounding<Instruction insn, TypedReg tr> {
1420  def : FPConversion<insn, any_frint,      tr, tr, 0, 0>;
1421  def : FPConversion<insn, any_fnearbyint, tr, tr, 4, 0>;
1422  def : FPConversion<insn, any_ffloor,     tr, tr, 4, 7>;
1423  def : FPConversion<insn, any_fceil,      tr, tr, 4, 6>;
1424  def : FPConversion<insn, any_ftrunc,     tr, tr, 4, 5>;
1425  def : FPConversion<insn, any_froundeven, tr, tr, 4, 4>;
1426  def : FPConversion<insn, any_fround,     tr, tr, 4, 1>;
1427}
1428
1429let Predicates = [FeatureVector] in {
1430  // Add.
1431  let Uses = [FPC], mayRaiseFPException = 1, isCommutable = 1 in {
1432    def VFA   : BinaryVRRcFloatGeneric<"vfa", 0xE7E3>;
1433    def VFADB : BinaryVRRc<"vfadb", 0xE7E3, any_fadd, v128db, v128db, 3, 0>;
1434    def WFADB : BinaryVRRc<"wfadb", 0xE7E3, any_fadd, v64db, v64db, 3, 8, 0,
1435                           "adbr">;
1436    let Predicates = [FeatureVectorEnhancements1] in {
1437      def VFASB : BinaryVRRc<"vfasb", 0xE7E3, any_fadd, v128sb, v128sb, 2, 0>;
1438      def WFASB : BinaryVRRc<"wfasb", 0xE7E3, any_fadd, v32sb, v32sb, 2, 8, 0,
1439                             "aebr">;
1440      def WFAXB : BinaryVRRc<"wfaxb", 0xE7E3, any_fadd, v128xb, v128xb, 4, 8>;
1441    }
1442  }
1443
1444  // Convert from fixed.
1445  let Uses = [FPC], mayRaiseFPException = 1 in {
1446    def VCDG  : TernaryVRRaFloatGeneric<"vcdg", 0xE7C3>;
1447    def VCDGB : TernaryVRRa<"vcdgb", 0xE7C3, null_frag, v128db, v128g, 3, 0>;
1448    def WCDGB : TernaryVRRa<"wcdgb", 0xE7C3, null_frag, v64db, v64g, 3, 8>;
1449  }
1450  def : FPConversion<VCDGB, any_sint_to_fp, v128db, v128g, 0, 0>;
1451  let Predicates = [FeatureVectorEnhancements2] in {
1452    let Uses = [FPC], mayRaiseFPException = 1 in {
1453      let isAsmParserOnly = 1 in
1454        def VCFPS  : TernaryVRRaFloatGeneric<"vcfps", 0xE7C3>;
1455      def VCEFB : TernaryVRRa<"vcefb", 0xE7C3, null_frag, v128sb, v128g, 2, 0>;
1456      def WCEFB : TernaryVRRa<"wcefb", 0xE7C3, null_frag, v32sb, v32f, 2, 8>;
1457    }
1458    def : FPConversion<VCEFB, any_sint_to_fp, v128sb, v128f, 0, 0>;
1459  }
1460
1461  // Convert from logical.
1462  let Uses = [FPC], mayRaiseFPException = 1 in {
1463    def VCDLG  : TernaryVRRaFloatGeneric<"vcdlg", 0xE7C1>;
1464    def VCDLGB : TernaryVRRa<"vcdlgb", 0xE7C1, null_frag, v128db, v128g, 3, 0>;
1465    def WCDLGB : TernaryVRRa<"wcdlgb", 0xE7C1, null_frag, v64db, v64g, 3, 8>;
1466  }
1467  def : FPConversion<VCDLGB, any_uint_to_fp, v128db, v128g, 0, 0>;
1468  let Predicates = [FeatureVectorEnhancements2] in {
1469    let Uses = [FPC], mayRaiseFPException = 1 in {
1470      let isAsmParserOnly = 1 in
1471        def VCFPL  : TernaryVRRaFloatGeneric<"vcfpl", 0xE7C1>;
1472      def VCELFB : TernaryVRRa<"vcelfb", 0xE7C1, null_frag, v128sb, v128g, 2, 0>;
1473      def WCELFB : TernaryVRRa<"wcelfb", 0xE7C1, null_frag, v32sb, v32f, 2, 8>;
1474    }
1475    def : FPConversion<VCELFB, any_uint_to_fp, v128sb, v128f, 0, 0>;
1476  }
1477
1478  // Convert to fixed.
1479  let Uses = [FPC], mayRaiseFPException = 1 in {
1480    def VCGD  : TernaryVRRaFloatGeneric<"vcgd", 0xE7C2>;
1481    def VCGDB : TernaryVRRa<"vcgdb", 0xE7C2, null_frag, v128g, v128db, 3, 0>;
1482    def WCGDB : TernaryVRRa<"wcgdb", 0xE7C2, null_frag, v64g, v64db, 3, 8>;
1483  }
1484  // Rounding mode should agree with SystemZInstrFP.td.
1485  def : FPConversion<VCGDB, any_fp_to_sint, v128g, v128db, 0, 5>;
1486  let Predicates = [FeatureVectorEnhancements2] in {
1487    let Uses = [FPC], mayRaiseFPException = 1 in {
1488      let isAsmParserOnly = 1 in
1489        def VCSFP  : TernaryVRRaFloatGeneric<"vcsfp", 0xE7C2>;
1490      def VCFEB : TernaryVRRa<"vcfeb", 0xE7C2, null_frag, v128sb, v128g, 2, 0>;
1491      def WCFEB : TernaryVRRa<"wcfeb", 0xE7C2, null_frag, v32sb, v32f, 2, 8>;
1492    }
1493    // Rounding mode should agree with SystemZInstrFP.td.
1494    def : FPConversion<VCFEB, any_fp_to_sint, v128f, v128sb, 0, 5>;
1495  }
1496
1497  // Convert to logical.
1498  let Uses = [FPC], mayRaiseFPException = 1 in {
1499    def VCLGD  : TernaryVRRaFloatGeneric<"vclgd", 0xE7C0>;
1500    def VCLGDB : TernaryVRRa<"vclgdb", 0xE7C0, null_frag, v128g, v128db, 3, 0>;
1501    def WCLGDB : TernaryVRRa<"wclgdb", 0xE7C0, null_frag, v64g, v64db, 3, 8>;
1502  }
1503  // Rounding mode should agree with SystemZInstrFP.td.
1504  def : FPConversion<VCLGDB, any_fp_to_uint, v128g, v128db, 0, 5>;
1505  let Predicates = [FeatureVectorEnhancements2] in {
1506    let Uses = [FPC], mayRaiseFPException = 1 in {
1507      let isAsmParserOnly = 1 in
1508        def VCLFP  : TernaryVRRaFloatGeneric<"vclfp", 0xE7C0>;
1509      def VCLFEB : TernaryVRRa<"vclfeb", 0xE7C0, null_frag, v128sb, v128g, 2, 0>;
1510      def WCLFEB : TernaryVRRa<"wclfeb", 0xE7C0, null_frag, v32sb, v32f, 2, 8>;
1511    }
1512    // Rounding mode should agree with SystemZInstrFP.td.
1513    def : FPConversion<VCLFEB, any_fp_to_uint, v128f, v128sb, 0, 5>;
1514  }
1515
1516  // Divide.
1517  let Uses = [FPC], mayRaiseFPException = 1 in {
1518    def VFD   : BinaryVRRcFloatGeneric<"vfd", 0xE7E5>;
1519    def VFDDB : BinaryVRRc<"vfddb", 0xE7E5, any_fdiv, v128db, v128db, 3, 0>;
1520    def WFDDB : BinaryVRRc<"wfddb", 0xE7E5, any_fdiv, v64db, v64db, 3, 8, 0,
1521                           "ddbr">;
1522    let Predicates = [FeatureVectorEnhancements1] in {
1523      def VFDSB : BinaryVRRc<"vfdsb", 0xE7E5, any_fdiv, v128sb, v128sb, 2, 0>;
1524      def WFDSB : BinaryVRRc<"wfdsb", 0xE7E5, any_fdiv, v32sb, v32sb, 2, 8, 0,
1525                             "debr">;
1526      def WFDXB : BinaryVRRc<"wfdxb", 0xE7E5, any_fdiv, v128xb, v128xb, 4, 8>;
1527    }
1528  }
1529
1530  // Load FP integer.
1531  let Uses = [FPC], mayRaiseFPException = 1 in {
1532    def VFI   : TernaryVRRaFloatGeneric<"vfi", 0xE7C7>;
1533    def VFIDB : TernaryVRRa<"vfidb", 0xE7C7, int_s390_vfidb, v128db, v128db, 3, 0>;
1534    def WFIDB : TernaryVRRa<"wfidb", 0xE7C7, null_frag, v64db, v64db, 3, 8>;
1535  }
1536  defm : VectorRounding<VFIDB, v128db>;
1537  defm : VectorRounding<WFIDB, v64db>;
1538  let Predicates = [FeatureVectorEnhancements1] in {
1539    let Uses = [FPC], mayRaiseFPException = 1 in {
1540      def VFISB : TernaryVRRa<"vfisb", 0xE7C7, int_s390_vfisb, v128sb, v128sb, 2, 0>;
1541      def WFISB : TernaryVRRa<"wfisb", 0xE7C7, null_frag, v32sb, v32sb, 2, 8>;
1542      def WFIXB : TernaryVRRa<"wfixb", 0xE7C7, null_frag, v128xb, v128xb, 4, 8>;
1543    }
1544    defm : VectorRounding<VFISB, v128sb>;
1545    defm : VectorRounding<WFISB, v32sb>;
1546    defm : VectorRounding<WFIXB, v128xb>;
1547  }
1548
1549  // Load lengthened.
1550  let Uses = [FPC], mayRaiseFPException = 1 in {
1551    def VLDE  : UnaryVRRaFloatGeneric<"vlde", 0xE7C4>;
1552    def VLDEB : UnaryVRRa<"vldeb", 0xE7C4, z_any_vextend, v128db, v128sb, 2, 0>;
1553    def WLDEB : UnaryVRRa<"wldeb", 0xE7C4, any_fpextend, v64db, v32sb, 2, 8, 0,
1554                          "ldebr">;
1555  }
1556  let Predicates = [FeatureVectorEnhancements1] in {
1557    let Uses = [FPC], mayRaiseFPException = 1 in {
1558      let isAsmParserOnly = 1 in {
1559        def VFLL  : UnaryVRRaFloatGeneric<"vfll", 0xE7C4>;
1560        def VFLLS : UnaryVRRa<"vflls", 0xE7C4, null_frag, v128db, v128sb, 2, 0>;
1561        def WFLLS : UnaryVRRa<"wflls", 0xE7C4, null_frag, v64db, v32sb, 2, 8>;
1562      }
1563      def WFLLD : UnaryVRRa<"wflld", 0xE7C4, any_fpextend, v128xb, v64db, 3, 8>;
1564    }
1565    def : Pat<(f128 (any_fpextend (f32 VR32:$src))),
1566              (WFLLD (WLDEB VR32:$src))>;
1567  }
1568
1569  // Load rounded.
1570  let Uses = [FPC], mayRaiseFPException = 1 in {
1571    def VLED  : TernaryVRRaFloatGeneric<"vled", 0xE7C5>;
1572    def VLEDB : TernaryVRRa<"vledb", 0xE7C5, null_frag, v128sb, v128db, 3, 0>;
1573    def WLEDB : TernaryVRRa<"wledb", 0xE7C5, null_frag, v32sb, v64db, 3, 8>;
1574  }
1575  def : Pat<(v4f32 (z_any_vround (v2f64 VR128:$src))), (VLEDB VR128:$src, 0, 0)>;
1576  def : FPConversion<WLEDB, any_fpround, v32sb, v64db, 0, 0>;
1577  let Predicates = [FeatureVectorEnhancements1] in {
1578    let Uses = [FPC], mayRaiseFPException = 1 in {
1579      let isAsmParserOnly = 1 in {
1580        def VFLR  : TernaryVRRaFloatGeneric<"vflr", 0xE7C5>;
1581        def VFLRD : TernaryVRRa<"vflrd", 0xE7C5, null_frag, v128sb, v128db, 3, 0>;
1582        def WFLRD : TernaryVRRa<"wflrd", 0xE7C5, null_frag, v32sb, v64db, 3, 8>;
1583      }
1584      def WFLRX : TernaryVRRa<"wflrx", 0xE7C5, null_frag, v64db, v128xb, 4, 8>;
1585    }
1586    def : FPConversion<WFLRX, any_fpround, v64db, v128xb, 0, 0>;
1587    def : Pat<(f32 (any_fpround (f128 VR128:$src))),
1588              (WLEDB (WFLRX VR128:$src, 0, 3), 0, 0)>;
1589  }
1590
1591  // Maximum.
1592  multiclass VectorMax<Instruction insn, TypedReg tr> {
1593    def : FPMinMax<insn, any_fmaxnum, tr, 4>;
1594    def : FPMinMax<insn, any_fmaximum, tr, 1>;
1595  }
1596  let Predicates = [FeatureVectorEnhancements1] in {
1597    let Uses = [FPC], mayRaiseFPException = 1, isCommutable = 1 in {
1598      def VFMAX   : TernaryVRRcFloatGeneric<"vfmax", 0xE7EF>;
1599      def VFMAXDB : TernaryVRRcFloat<"vfmaxdb", 0xE7EF, int_s390_vfmaxdb,
1600                                     v128db, v128db, 3, 0>;
1601      def WFMAXDB : TernaryVRRcFloat<"wfmaxdb", 0xE7EF, null_frag,
1602                                     v64db, v64db, 3, 8>;
1603      def VFMAXSB : TernaryVRRcFloat<"vfmaxsb", 0xE7EF, int_s390_vfmaxsb,
1604                                     v128sb, v128sb, 2, 0>;
1605      def WFMAXSB : TernaryVRRcFloat<"wfmaxsb", 0xE7EF, null_frag,
1606                                     v32sb, v32sb, 2, 8>;
1607      def WFMAXXB : TernaryVRRcFloat<"wfmaxxb", 0xE7EF, null_frag,
1608                                     v128xb, v128xb, 4, 8>;
1609    }
1610    defm : VectorMax<VFMAXDB, v128db>;
1611    defm : VectorMax<WFMAXDB, v64db>;
1612    defm : VectorMax<VFMAXSB, v128sb>;
1613    defm : VectorMax<WFMAXSB, v32sb>;
1614    defm : VectorMax<WFMAXXB, v128xb>;
1615  }
1616
1617  // Minimum.
1618  multiclass VectorMin<Instruction insn, TypedReg tr> {
1619    def : FPMinMax<insn, any_fminnum, tr, 4>;
1620    def : FPMinMax<insn, any_fminimum, tr, 1>;
1621  }
1622  let Predicates = [FeatureVectorEnhancements1] in {
1623    let Uses = [FPC], mayRaiseFPException = 1, isCommutable = 1 in {
1624      def VFMIN   : TernaryVRRcFloatGeneric<"vfmin", 0xE7EE>;
1625      def VFMINDB : TernaryVRRcFloat<"vfmindb", 0xE7EE, int_s390_vfmindb,
1626                                     v128db, v128db, 3, 0>;
1627      def WFMINDB : TernaryVRRcFloat<"wfmindb", 0xE7EE, null_frag,
1628                                     v64db, v64db, 3, 8>;
1629      def VFMINSB : TernaryVRRcFloat<"vfminsb", 0xE7EE, int_s390_vfminsb,
1630                                     v128sb, v128sb, 2, 0>;
1631      def WFMINSB : TernaryVRRcFloat<"wfminsb", 0xE7EE, null_frag,
1632                                     v32sb, v32sb, 2, 8>;
1633      def WFMINXB : TernaryVRRcFloat<"wfminxb", 0xE7EE, null_frag,
1634                                     v128xb, v128xb, 4, 8>;
1635    }
1636    defm : VectorMin<VFMINDB, v128db>;
1637    defm : VectorMin<WFMINDB, v64db>;
1638    defm : VectorMin<VFMINSB, v128sb>;
1639    defm : VectorMin<WFMINSB, v32sb>;
1640    defm : VectorMin<WFMINXB, v128xb>;
1641  }
1642
1643  // Multiply.
1644  let Uses = [FPC], mayRaiseFPException = 1, isCommutable = 1 in {
1645    def VFM   : BinaryVRRcFloatGeneric<"vfm", 0xE7E7>;
1646    def VFMDB : BinaryVRRc<"vfmdb", 0xE7E7, any_fmul, v128db, v128db, 3, 0>;
1647    def WFMDB : BinaryVRRc<"wfmdb", 0xE7E7, any_fmul, v64db, v64db, 3, 8, 0,
1648                           "mdbr">;
1649    let Predicates = [FeatureVectorEnhancements1] in {
1650      def VFMSB : BinaryVRRc<"vfmsb", 0xE7E7, any_fmul, v128sb, v128sb, 2, 0>;
1651      def WFMSB : BinaryVRRc<"wfmsb", 0xE7E7, any_fmul, v32sb, v32sb, 2, 8, 0,
1652                             "meebr">;
1653      def WFMXB : BinaryVRRc<"wfmxb", 0xE7E7, any_fmul, v128xb, v128xb, 4, 8>;
1654    }
1655  }
1656
1657  // Multiply and add.
1658  let Uses = [FPC], mayRaiseFPException = 1, isCommutable = 1 in {
1659    def VFMA   : TernaryVRReFloatGeneric<"vfma", 0xE78F>;
1660    def VFMADB : TernaryVRRe<"vfmadb", 0xE78F, any_fma, v128db, v128db, 0, 3>;
1661    def WFMADB : TernaryVRRe<"wfmadb", 0xE78F, any_fma, v64db, v64db, 8, 3,
1662                             "madbr">;
1663    let Predicates = [FeatureVectorEnhancements1] in {
1664      def VFMASB : TernaryVRRe<"vfmasb", 0xE78F, any_fma, v128sb, v128sb, 0, 2>;
1665      def WFMASB : TernaryVRRe<"wfmasb", 0xE78F, any_fma, v32sb, v32sb, 8, 2,
1666                               "maebr">;
1667      def WFMAXB : TernaryVRRe<"wfmaxb", 0xE78F, any_fma, v128xb, v128xb, 8, 4>;
1668    }
1669  }
1670
1671  // Multiply and subtract.
1672  let Uses = [FPC], mayRaiseFPException = 1, isCommutable = 1 in {
1673    def VFMS   : TernaryVRReFloatGeneric<"vfms", 0xE78E>;
1674    def VFMSDB : TernaryVRRe<"vfmsdb", 0xE78E, any_fms, v128db, v128db, 0, 3>;
1675    def WFMSDB : TernaryVRRe<"wfmsdb", 0xE78E, any_fms, v64db, v64db, 8, 3,
1676                             "msdbr">;
1677    let Predicates = [FeatureVectorEnhancements1] in {
1678      def VFMSSB : TernaryVRRe<"vfmssb", 0xE78E, any_fms, v128sb, v128sb, 0, 2>;
1679      def WFMSSB : TernaryVRRe<"wfmssb", 0xE78E, any_fms, v32sb, v32sb, 8, 2,
1680                               "msebr">;
1681      def WFMSXB : TernaryVRRe<"wfmsxb", 0xE78E, any_fms, v128xb, v128xb, 8, 4>;
1682    }
1683  }
1684
1685  // Negative multiply and add.
1686  let Uses = [FPC], mayRaiseFPException = 1, isCommutable = 1,
1687      Predicates = [FeatureVectorEnhancements1] in {
1688    def VFNMA   : TernaryVRReFloatGeneric<"vfnma", 0xE79F>;
1689    def VFNMADB : TernaryVRRe<"vfnmadb", 0xE79F, any_fnma, v128db, v128db, 0, 3>;
1690    def WFNMADB : TernaryVRRe<"wfnmadb", 0xE79F, any_fnma, v64db, v64db, 8, 3>;
1691    def VFNMASB : TernaryVRRe<"vfnmasb", 0xE79F, any_fnma, v128sb, v128sb, 0, 2>;
1692    def WFNMASB : TernaryVRRe<"wfnmasb", 0xE79F, any_fnma, v32sb, v32sb, 8, 2>;
1693    def WFNMAXB : TernaryVRRe<"wfnmaxb", 0xE79F, any_fnma, v128xb, v128xb, 8, 4>;
1694  }
1695
1696  // Negative multiply and subtract.
1697  let Uses = [FPC], mayRaiseFPException = 1, isCommutable = 1,
1698      Predicates = [FeatureVectorEnhancements1] in {
1699    def VFNMS   : TernaryVRReFloatGeneric<"vfnms", 0xE79E>;
1700    def VFNMSDB : TernaryVRRe<"vfnmsdb", 0xE79E, any_fnms, v128db, v128db, 0, 3>;
1701    def WFNMSDB : TernaryVRRe<"wfnmsdb", 0xE79E, any_fnms, v64db, v64db, 8, 3>;
1702    def VFNMSSB : TernaryVRRe<"vfnmssb", 0xE79E, any_fnms, v128sb, v128sb, 0, 2>;
1703    def WFNMSSB : TernaryVRRe<"wfnmssb", 0xE79E, any_fnms, v32sb, v32sb, 8, 2>;
1704    def WFNMSXB : TernaryVRRe<"wfnmsxb", 0xE79E, any_fnms, v128xb, v128xb, 8, 4>;
1705  }
1706
1707  // Perform sign operation.
1708  def VFPSO   : BinaryVRRaFloatGeneric<"vfpso", 0xE7CC>;
1709  def VFPSODB : BinaryVRRa<"vfpsodb", 0xE7CC, null_frag, v128db, v128db, 3, 0>;
1710  def WFPSODB : BinaryVRRa<"wfpsodb", 0xE7CC, null_frag, v64db, v64db, 3, 8>;
1711  let Predicates = [FeatureVectorEnhancements1] in {
1712    def VFPSOSB : BinaryVRRa<"vfpsosb", 0xE7CC, null_frag, v128sb, v128sb, 2, 0>;
1713    def WFPSOSB : BinaryVRRa<"wfpsosb", 0xE7CC, null_frag, v32sb, v32sb, 2, 8>;
1714    def WFPSOXB : BinaryVRRa<"wfpsoxb", 0xE7CC, null_frag, v128xb, v128xb, 4, 8>;
1715  }
1716
1717  // Load complement.
1718  def VFLCDB : UnaryVRRa<"vflcdb", 0xE7CC, fneg, v128db, v128db, 3, 0, 0>;
1719  def WFLCDB : UnaryVRRa<"wflcdb", 0xE7CC, fneg, v64db, v64db, 3, 8, 0>;
1720  let Predicates = [FeatureVectorEnhancements1] in {
1721    def VFLCSB : UnaryVRRa<"vflcsb", 0xE7CC, fneg, v128sb, v128sb, 2, 0, 0>;
1722    def WFLCSB : UnaryVRRa<"wflcsb", 0xE7CC, fneg, v32sb, v32sb, 2, 8, 0>;
1723    def WFLCXB : UnaryVRRa<"wflcxb", 0xE7CC, fneg, v128xb, v128xb, 4, 8, 0>;
1724  }
1725
1726  // Load negative.
1727  def VFLNDB : UnaryVRRa<"vflndb", 0xE7CC, fnabs, v128db, v128db, 3, 0, 1>;
1728  def WFLNDB : UnaryVRRa<"wflndb", 0xE7CC, fnabs, v64db, v64db, 3, 8, 1>;
1729  let Predicates = [FeatureVectorEnhancements1] in {
1730    def VFLNSB : UnaryVRRa<"vflnsb", 0xE7CC, fnabs, v128sb, v128sb, 2, 0, 1>;
1731    def WFLNSB : UnaryVRRa<"wflnsb", 0xE7CC, fnabs, v32sb, v32sb, 2, 8, 1>;
1732    def WFLNXB : UnaryVRRa<"wflnxb", 0xE7CC, fnabs, v128xb, v128xb, 4, 8, 1>;
1733  }
1734
1735  // Load positive.
1736  def VFLPDB : UnaryVRRa<"vflpdb", 0xE7CC, fabs, v128db, v128db, 3, 0, 2>;
1737  def WFLPDB : UnaryVRRa<"wflpdb", 0xE7CC, fabs, v64db, v64db, 3, 8, 2>;
1738  let Predicates = [FeatureVectorEnhancements1] in {
1739    def VFLPSB : UnaryVRRa<"vflpsb", 0xE7CC, fabs, v128sb, v128sb, 2, 0, 2>;
1740    def WFLPSB : UnaryVRRa<"wflpsb", 0xE7CC, fabs, v32sb, v32sb, 2, 8, 2>;
1741    def WFLPXB : UnaryVRRa<"wflpxb", 0xE7CC, fabs, v128xb, v128xb, 4, 8, 2>;
1742  }
1743
1744  // Square root.
1745  let Uses = [FPC], mayRaiseFPException = 1 in {
1746    def VFSQ   : UnaryVRRaFloatGeneric<"vfsq", 0xE7CE>;
1747    def VFSQDB : UnaryVRRa<"vfsqdb", 0xE7CE, any_fsqrt, v128db, v128db, 3, 0>;
1748    def WFSQDB : UnaryVRRa<"wfsqdb", 0xE7CE, any_fsqrt, v64db, v64db, 3, 8, 0,
1749                           "sqdbr">;
1750    let Predicates = [FeatureVectorEnhancements1] in {
1751      def VFSQSB : UnaryVRRa<"vfsqsb", 0xE7CE, any_fsqrt, v128sb, v128sb, 2, 0>;
1752      def WFSQSB : UnaryVRRa<"wfsqsb", 0xE7CE, any_fsqrt, v32sb, v32sb, 2, 8, 0,
1753                             "sqebr">;
1754      def WFSQXB : UnaryVRRa<"wfsqxb", 0xE7CE, any_fsqrt, v128xb, v128xb, 4, 8>;
1755    }
1756  }
1757
1758  // Subtract.
1759  let Uses = [FPC], mayRaiseFPException = 1 in {
1760    def VFS   : BinaryVRRcFloatGeneric<"vfs", 0xE7E2>;
1761    def VFSDB : BinaryVRRc<"vfsdb", 0xE7E2, any_fsub, v128db, v128db, 3, 0>;
1762    def WFSDB : BinaryVRRc<"wfsdb", 0xE7E2, any_fsub, v64db, v64db, 3, 8, 0,
1763                           "sdbr">;
1764    let Predicates = [FeatureVectorEnhancements1] in {
1765      def VFSSB : BinaryVRRc<"vfssb", 0xE7E2, any_fsub, v128sb, v128sb, 2, 0>;
1766      def WFSSB : BinaryVRRc<"wfssb", 0xE7E2, any_fsub, v32sb, v32sb, 2, 8, 0,
1767                             "sebr">;
1768      def WFSXB : BinaryVRRc<"wfsxb", 0xE7E2, any_fsub, v128xb, v128xb, 4, 8>;
1769    }
1770  }
1771
1772  // Test data class immediate.
1773  let Defs = [CC] in {
1774    def VFTCI   : BinaryVRIeFloatGeneric<"vftci", 0xE74A>;
1775    def VFTCIDB : BinaryVRIe<"vftcidb", 0xE74A, z_vftci, v128g, v128db, 3, 0>;
1776    def WFTCIDB : BinaryVRIe<"wftcidb", 0xE74A, null_frag, v64g, v64db, 3, 8>;
1777    let Predicates = [FeatureVectorEnhancements1] in {
1778      def VFTCISB : BinaryVRIe<"vftcisb", 0xE74A, z_vftci, v128f, v128sb, 2, 0>;
1779      def WFTCISB : BinaryVRIe<"wftcisb", 0xE74A, null_frag, v32f, v32sb, 2, 8>;
1780      def WFTCIXB : BinaryVRIe<"wftcixb", 0xE74A, null_frag, v128q, v128xb, 4, 8>;
1781    }
1782  }
1783}
1784
1785//===----------------------------------------------------------------------===//
1786// Floating-point comparison
1787//===----------------------------------------------------------------------===//
1788
1789let Predicates = [FeatureVector] in {
1790  // Compare scalar.
1791  let Uses = [FPC], mayRaiseFPException = 1, Defs = [CC] in {
1792    def WFC   : CompareVRRaFloatGeneric<"wfc", 0xE7CB>;
1793    def WFCDB : CompareVRRa<"wfcdb", 0xE7CB, z_any_fcmp, v64db, 3, "cdbr">;
1794    let Predicates = [FeatureVectorEnhancements1] in {
1795      def WFCSB : CompareVRRa<"wfcsb", 0xE7CB, z_any_fcmp, v32sb, 2, "cebr">;
1796      def WFCXB : CompareVRRa<"wfcxb", 0xE7CB, z_any_fcmp, v128xb, 4>;
1797    }
1798  }
1799
1800  // Compare and signal scalar.
1801  let Uses = [FPC], mayRaiseFPException = 1, Defs = [CC] in {
1802    def WFK   : CompareVRRaFloatGeneric<"wfk", 0xE7CA>;
1803    def WFKDB : CompareVRRa<"wfkdb", 0xE7CA, z_strict_fcmps, v64db, 3, "kdbr">;
1804    let Predicates = [FeatureVectorEnhancements1] in {
1805      def WFKSB : CompareVRRa<"wfksb", 0xE7CA, z_strict_fcmps, v32sb, 2, "kebr">;
1806      def WFKXB : CompareVRRa<"wfkxb", 0xE7CA, z_strict_fcmps, v128xb, 4>;
1807    }
1808  }
1809
1810  // Compare equal.
1811  let Uses = [FPC], mayRaiseFPException = 1 in {
1812    def  VFCE   : BinaryVRRcSPairFloatGeneric<"vfce", 0xE7E8>;
1813    defm VFCEDB : BinaryVRRcSPair<"vfcedb", 0xE7E8, z_any_vfcmpe, z_vfcmpes,
1814                                  v128g, v128db, 3, 0>;
1815    defm WFCEDB : BinaryVRRcSPair<"wfcedb", 0xE7E8, null_frag, null_frag,
1816                                  v64g, v64db, 3, 8>;
1817    let Predicates = [FeatureVectorEnhancements1] in {
1818      defm VFCESB : BinaryVRRcSPair<"vfcesb", 0xE7E8, z_any_vfcmpe, z_vfcmpes,
1819                                    v128f, v128sb, 2, 0>;
1820      defm WFCESB : BinaryVRRcSPair<"wfcesb", 0xE7E8, null_frag, null_frag,
1821                                    v32f, v32sb, 2, 8>;
1822      defm WFCEXB : BinaryVRRcSPair<"wfcexb", 0xE7E8, null_frag, null_frag,
1823                                    v128q, v128xb, 4, 8>;
1824    }
1825  }
1826
1827  // Compare and signal equal.
1828  let Uses = [FPC], mayRaiseFPException = 1,
1829      Predicates = [FeatureVectorEnhancements1] in {
1830    defm VFKEDB : BinaryVRRcSPair<"vfkedb", 0xE7E8, z_strict_vfcmpes, null_frag,
1831                                  v128g, v128db, 3, 4>;
1832    defm WFKEDB : BinaryVRRcSPair<"wfkedb", 0xE7E8, null_frag, null_frag,
1833                                  v64g, v64db, 3, 12>;
1834    defm VFKESB : BinaryVRRcSPair<"vfkesb", 0xE7E8, z_strict_vfcmpes, null_frag,
1835                                  v128f, v128sb, 2, 4>;
1836    defm WFKESB : BinaryVRRcSPair<"wfkesb", 0xE7E8, null_frag, null_frag,
1837                                  v32f, v32sb, 2, 12>;
1838    defm WFKEXB : BinaryVRRcSPair<"wfkexb", 0xE7E8, null_frag, null_frag,
1839                                  v128q, v128xb, 4, 12>;
1840  }
1841
1842  // Compare high.
1843  let Uses = [FPC], mayRaiseFPException = 1 in {
1844    def  VFCH   : BinaryVRRcSPairFloatGeneric<"vfch", 0xE7EB>;
1845    defm VFCHDB : BinaryVRRcSPair<"vfchdb", 0xE7EB, z_any_vfcmph, z_vfcmphs,
1846                                  v128g, v128db, 3, 0>;
1847    defm WFCHDB : BinaryVRRcSPair<"wfchdb", 0xE7EB, null_frag, null_frag,
1848                                  v64g, v64db, 3, 8>;
1849    let Predicates = [FeatureVectorEnhancements1] in {
1850      defm VFCHSB : BinaryVRRcSPair<"vfchsb", 0xE7EB, z_any_vfcmph, z_vfcmphs,
1851                                    v128f, v128sb, 2, 0>;
1852      defm WFCHSB : BinaryVRRcSPair<"wfchsb", 0xE7EB, null_frag, null_frag,
1853                                    v32f, v32sb, 2, 8>;
1854      defm WFCHXB : BinaryVRRcSPair<"wfchxb", 0xE7EB, null_frag, null_frag,
1855                                    v128q, v128xb, 4, 8>;
1856    }
1857  }
1858
1859  // Compare and signal high.
1860  let Uses = [FPC], mayRaiseFPException = 1,
1861      Predicates = [FeatureVectorEnhancements1] in {
1862    defm VFKHDB : BinaryVRRcSPair<"vfkhdb", 0xE7EB, z_strict_vfcmphs, null_frag,
1863                                  v128g, v128db, 3, 4>;
1864    defm WFKHDB : BinaryVRRcSPair<"wfkhdb", 0xE7EB, null_frag, null_frag,
1865                                  v64g, v64db, 3, 12>;
1866    defm VFKHSB : BinaryVRRcSPair<"vfkhsb", 0xE7EB, z_strict_vfcmphs, null_frag,
1867                                  v128f, v128sb, 2, 4>;
1868    defm WFKHSB : BinaryVRRcSPair<"wfkhsb", 0xE7EB, null_frag, null_frag,
1869                                  v32f, v32sb, 2, 12>;
1870    defm WFKHXB : BinaryVRRcSPair<"wfkhxb", 0xE7EB, null_frag, null_frag,
1871                                  v128q, v128xb, 4, 12>;
1872  }
1873
1874  // Compare high or equal.
1875  let Uses = [FPC], mayRaiseFPException = 1 in {
1876    def  VFCHE   : BinaryVRRcSPairFloatGeneric<"vfche", 0xE7EA>;
1877    defm VFCHEDB : BinaryVRRcSPair<"vfchedb", 0xE7EA, z_any_vfcmphe, z_vfcmphes,
1878                                   v128g, v128db, 3, 0>;
1879    defm WFCHEDB : BinaryVRRcSPair<"wfchedb", 0xE7EA, null_frag, null_frag,
1880                                   v64g, v64db, 3, 8>;
1881    let Predicates = [FeatureVectorEnhancements1] in {
1882      defm VFCHESB : BinaryVRRcSPair<"vfchesb", 0xE7EA, z_any_vfcmphe, z_vfcmphes,
1883                                     v128f, v128sb, 2, 0>;
1884      defm WFCHESB : BinaryVRRcSPair<"wfchesb", 0xE7EA, null_frag, null_frag,
1885                                     v32f, v32sb, 2, 8>;
1886      defm WFCHEXB : BinaryVRRcSPair<"wfchexb", 0xE7EA, null_frag, null_frag,
1887                                     v128q, v128xb, 4, 8>;
1888    }
1889  }
1890
1891  // Compare and signal high or equal.
1892  let Uses = [FPC], mayRaiseFPException = 1,
1893      Predicates = [FeatureVectorEnhancements1] in {
1894    defm VFKHEDB : BinaryVRRcSPair<"vfkhedb", 0xE7EA, z_strict_vfcmphes, null_frag,
1895                                   v128g, v128db, 3, 4>;
1896    defm WFKHEDB : BinaryVRRcSPair<"wfkhedb", 0xE7EA, null_frag, null_frag,
1897                                   v64g, v64db, 3, 12>;
1898    defm VFKHESB : BinaryVRRcSPair<"vfkhesb", 0xE7EA, z_strict_vfcmphes, null_frag,
1899                                   v128f, v128sb, 2, 4>;
1900    defm WFKHESB : BinaryVRRcSPair<"wfkhesb", 0xE7EA, null_frag, null_frag,
1901                                   v32f, v32sb, 2, 12>;
1902    defm WFKHEXB : BinaryVRRcSPair<"wfkhexb", 0xE7EA, null_frag, null_frag,
1903                                   v128q, v128xb, 4, 12>;
1904  }
1905}
1906
1907//===----------------------------------------------------------------------===//
1908// Support for 128-bit integer values in vector registers
1909//===----------------------------------------------------------------------===//
1910
1911// Loads and stores.
1912let Predicates = [FeatureVector] in {
1913  def : Pat<(i128 (load bdxaddr12only:$addr)),
1914            (VL bdxaddr12only:$addr)>;
1915  def : Pat<(store (i128 VR128:$src), bdxaddr12only:$addr),
1916            (VST VR128:$src, bdxaddr12only:$addr)>;
1917}
1918
1919// Full i128 move from GPR pair.
1920let Predicates = [FeatureVector] in
1921  def : Pat<(i128 (or (zext GR64:$x), (shl (anyext GR64:$y), (i32 64)))),
1922            (VLVGP GR64:$y, GR64:$x)>;
1923
1924// Any-extensions from GPR to i128.
1925let Predicates = [FeatureVector] in {
1926  def : Pat<(i128 (anyext GR32:$x)), (VLVGP32 GR32:$x, GR32:$x)>;
1927  def : Pat<(i128 (anyext GR64:$x)), (VLVGP GR64:$x, GR64:$x)>;
1928}
1929
1930// Any-extending loads into i128.
1931let Predicates = [FeatureVector] in {
1932  def : Pat<(i128 (z_extloadi8 bdxaddr12only:$addr)),
1933            (VLREPB bdxaddr12only:$addr)>;
1934  def : Pat<(i128 (z_extloadi16 bdxaddr12only:$addr)),
1935            (VLREPH bdxaddr12only:$addr)>;
1936  def : Pat<(i128 (z_extloadi32 bdxaddr12only:$addr)),
1937            (VLREPF bdxaddr12only:$addr)>;
1938  def : Pat<(i128 (z_extloadi64 bdxaddr12only:$addr)),
1939            (VLREPG bdxaddr12only:$addr)>;
1940}
1941
1942// Truncations from i128 to GPR.
1943let Predicates = [FeatureVector] in {
1944  def : Pat<(i32 (trunc (i128 VR128:$vec))),
1945            (EXTRACT_SUBREG (VLGVF VR128:$vec, zero_reg, 3), subreg_l32)>;
1946  def : Pat<(i32 (trunc (srl (i128 VR128:$vec), (i32 32)))),
1947            (EXTRACT_SUBREG (VLGVF VR128:$vec, zero_reg, 2), subreg_l32)>;
1948  def : Pat<(i32 (trunc (srl (i128 VR128:$vec), (i32 64)))),
1949            (EXTRACT_SUBREG (VLGVF VR128:$vec, zero_reg, 1), subreg_l32)>;
1950  def : Pat<(i32 (trunc (srl (i128 VR128:$vec), (i32 96)))),
1951            (EXTRACT_SUBREG (VLGVF VR128:$vec, zero_reg, 0), subreg_l32)>;
1952  def : Pat<(i64 (trunc (i128 VR128:$vec))),
1953            (VLGVG VR128:$vec, zero_reg, 1)>;
1954  def : Pat<(i64 (trunc (srl (i128 VR128:$vec), (i32 64)))),
1955            (VLGVG VR128:$vec, zero_reg, 0)>;
1956}
1957
1958// Truncating stores from i128.
1959let Predicates = [FeatureVector] in {
1960  def : Pat<(truncstorei8 (i128 VR128:$x), bdxaddr12only:$addr),
1961            (VSTEB VR128:$x, bdxaddr12only:$addr, 15)>;
1962  def : Pat<(truncstorei16 (i128 VR128:$x), bdxaddr12only:$addr),
1963            (VSTEH VR128:$x, bdxaddr12only:$addr, 7)>;
1964  def : Pat<(truncstorei32 (i128 VR128:$x), bdxaddr12only:$addr),
1965            (VSTEF VR128:$x, bdxaddr12only:$addr, 3)>;
1966  def : Pat<(truncstorei32 (srl (i128 VR128:$x), (i32 32)), bdxaddr12only:$addr),
1967            (VSTEF VR128:$x, bdxaddr12only:$addr, 2)>;
1968  def : Pat<(truncstorei32 (srl (i128 VR128:$x), (i32 64)), bdxaddr12only:$addr),
1969            (VSTEF VR128:$x, bdxaddr12only:$addr, 1)>;
1970  def : Pat<(truncstorei32 (srl (i128 VR128:$x), (i32 96)), bdxaddr12only:$addr),
1971            (VSTEF VR128:$x, bdxaddr12only:$addr, 0)>;
1972  def : Pat<(truncstorei64 (i128 VR128:$x), bdxaddr12only:$addr),
1973            (VSTEG VR128:$x, bdxaddr12only:$addr, 1)>;
1974  def : Pat<(truncstorei64 (srl (i128 VR128:$x), (i32 64)), bdxaddr12only:$addr),
1975            (VSTEG VR128:$x, bdxaddr12only:$addr, 0)>;
1976}
1977
1978// Zero-extensions from GPR to i128.
1979let Predicates = [FeatureVector] in {
1980  def : Pat<(i128 (zext8 (anyext GR32:$x))),
1981            (VLVGB (VGBM 0), GR32:$x, zero_reg, 15)>;
1982  def : Pat<(i128 (zext16 (anyext GR32:$x))),
1983            (VLVGH (VGBM 0), GR32:$x, zero_reg, 7)>;
1984  def : Pat<(i128 (zext GR32:$x)),
1985            (VLVGF (VGBM 0), GR32:$x, zero_reg, 3)>;
1986  def : Pat<(i128 (zext GR64:$x)),
1987            (VLVGG (VGBM 0), GR64:$x, zero_reg, 1)>;
1988}
1989
1990// Zero-extending loads into i128.
1991let Predicates = [FeatureVector] in {
1992  def : Pat<(i128 (z_zextloadi8 bdxaddr12only:$addr)),
1993            (VLEB (VGBM 0), bdxaddr12only:$addr, 15)>;
1994  def : Pat<(i128 (z_zextloadi16 bdxaddr12only:$addr)),
1995            (VLEH (VGBM 0), bdxaddr12only:$addr, 7)>;
1996  def : Pat<(i128 (z_zextloadi32 bdxaddr12only:$addr)),
1997            (VLEF (VGBM 0), bdxaddr12only:$addr, 3)>;
1998  def : Pat<(i128 (z_zextloadi64 bdxaddr12only:$addr)),
1999            (VLEG (VGBM 0), bdxaddr12only:$addr, 1)>;
2000}
2001
2002// Zero-extensions from VR element to i128 on z17.
2003let Predicates = [FeatureVectorEnhancements3] in {
2004  def : Pat<(i128 (zext (i64 (z_vector_extract (v2i64 VR128:$src), 0)))),
2005            (VUPLHG VR128:$src)>;
2006  def : Pat<(i128 (zext (i64 (z_vector_extract (v2i64 VR128:$src), 1)))),
2007            (VUPLLG VR128:$src)>;
2008  def : Pat<(i128 (zext (i32 (z_vector_extract (v4i32 VR128:$src), 0)))),
2009            (VUPLHG (VUPLHF VR128:$src))>;
2010  def : Pat<(i128 (zext (i32 (z_vector_extract (v4i32 VR128:$src), 1)))),
2011            (VUPLHG (VUPLLF VR128:$src))>;
2012  def : Pat<(i128 (zext (i32 (z_vector_extract (v4i32 VR128:$src), 2)))),
2013            (VUPLLG (VUPLHF VR128:$src))>;
2014  def : Pat<(i128 (zext (i32 (z_vector_extract (v4i32 VR128:$src), 3)))),
2015            (VUPLLG (VUPLLF VR128:$src))>;
2016}
2017
2018// In-register i128 sign-extensions on z17.
2019let Predicates = [FeatureVectorEnhancements3] in {
2020  def : Pat<(i128 (sext_inreg VR128:$x, i8)), (VUPLG (VSEGB VR128:$x))>;
2021  def : Pat<(i128 (sext_inreg VR128:$x, i16)), (VUPLG (VSEGH VR128:$x))>;
2022  def : Pat<(i128 (sext_inreg VR128:$x, i32)), (VUPLG (VSEGF VR128:$x))>;
2023  def : Pat<(i128 (sext_inreg VR128:$x, i64)), (VUPLG VR128:$x)>;
2024}
2025
2026// In-register i128 sign-extensions.
2027let Predicates = [FeatureVector] in {
2028  def : Pat<(i128 (sext_inreg VR128:$x, i8)),
2029            (VSRAB (VREPB VR128:$x, 15), (VREPIB 120))>;
2030  def : Pat<(i128 (sext_inreg VR128:$x, i16)),
2031            (VSRAB (VREPH VR128:$x, 7), (VREPIB 112))>;
2032  def : Pat<(i128 (sext_inreg VR128:$x, i32)),
2033            (VSRAB (VREPF VR128:$x, 3), (VREPIB 96))>;
2034  def : Pat<(i128 (sext_inreg VR128:$x, i64)),
2035            (VSRAB (VREPG VR128:$x, 1), (VREPIB 64))>;
2036}
2037
2038// Sign-extensions from GPR to i128 on z17.
2039let Predicates = [FeatureVectorEnhancements3] in {
2040  def : Pat<(i128 (sext_inreg (anyext GR32:$x), i8)),
2041            (VUPLG (VLVGP (LGBR (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$x, subreg_l32)),
2042                          (LGBR (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$x, subreg_l32))))>;
2043  def : Pat<(i128 (sext_inreg (anyext GR32:$x), i16)),
2044            (VUPLG (VLVGP (LGHR (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$x, subreg_l32)),
2045                          (LGHR (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$x, subreg_l32))))>;
2046  def : Pat<(i128 (sext GR32:$x)),
2047            (VUPLG (VLVGP (LGFR GR32:$x), (LGFR GR32:$x)))>;
2048  def : Pat<(i128 (sext GR64:$x)),
2049            (VUPLG (VLVGP GR64:$x, GR64:$x))>;
2050}
2051
2052// Sign-extensions from GPR to i128.
2053let Predicates = [FeatureVector] in {
2054  def : Pat<(i128 (sext_inreg (anyext GR32:$x), i8)),
2055            (VLVGP (SRAG (LGBR (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2056                                 GR32:$x, subreg_l32)), zero_reg, 63),
2057                   (LGBR (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2058                            GR32:$x, subreg_l32)))>;
2059  def : Pat<(i128 (sext_inreg (anyext GR32:$x), i16)),
2060            (VLVGP (SRAG (LGHR (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2061                                  GR32:$x, subreg_l32)), zero_reg, 63),
2062                   (LGHR (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2063                            GR32:$x, subreg_l32)))>;
2064  def : Pat<(i128 (sext GR32:$x)),
2065            (VLVGP (SRAG (LGFR GR32:$x), zero_reg, 63), (LGFR GR32:$x))>;
2066  def : Pat<(i128 (sext GR64:$x)),
2067            (VLVGP (SRAG GR64:$x, zero_reg, 63), GR64:$x)>;
2068}
2069
2070// Sign-extending loads into i128.
2071let Predicates = [FeatureVector] in {
2072  def : Pat<(i128 (z_sextloadi8 bdxaddr12only:$addr)),
2073            (VSRAB (VLREPB bdxaddr12only:$addr), (VREPIB 120))>;
2074  def : Pat<(i128 (z_sextloadi16 bdxaddr12only:$addr)),
2075            (VSRAB (VLREPH bdxaddr12only:$addr), (VREPIB 112))>;
2076  def : Pat<(i128 (z_sextloadi32 bdxaddr12only:$addr)),
2077            (VSRAB (VLREPF bdxaddr12only:$addr), (VREPIB 96))>;
2078  def : Pat<(i128 (z_sextloadi64 bdxaddr12only:$addr)),
2079            (VSRAB (VLREPG bdxaddr12only:$addr), (VREPIB 64))>;
2080}
2081
2082// Sign-extensions from VR element to i128 on z17.
2083let Predicates = [FeatureVectorEnhancements3] in {
2084  def : Pat<(i128 (sext (i64 (z_vector_extract (v2i64 VR128:$src), 0)))),
2085            (VUPHG VR128:$src)>;
2086  def : Pat<(i128 (sext (i64 (z_vector_extract (v2i64 VR128:$src), 1)))),
2087            (VUPLG VR128:$src)>;
2088  def : Pat<(i128 (sext (i32 (z_vector_extract (v4i32 VR128:$src), 0)))),
2089            (VUPHG (VUPHF VR128:$src))>;
2090  def : Pat<(i128 (sext (i32 (z_vector_extract (v4i32 VR128:$src), 1)))),
2091            (VUPHG (VUPLF VR128:$src))>;
2092  def : Pat<(i128 (sext (i32 (z_vector_extract (v4i32 VR128:$src), 2)))),
2093            (VUPLG (VUPHF VR128:$src))>;
2094  def : Pat<(i128 (sext (i32 (z_vector_extract (v4i32 VR128:$src), 3)))),
2095            (VUPLG (VUPLF VR128:$src))>;
2096}
2097
2098// i128 comparison pseudo-instructions.
2099let Predicates = [FeatureVector], Defs = [CC],
2100    usesCustomInserter = 1, hasNoSchedulingInfo = 1 in {
2101  def SCmp128Hi : Pseudo<(outs), (ins VR128:$src1, VR128:$src2),
2102                         [(set CC, (z_scmp128hi (i128 VR128:$src1),
2103                                                (i128 VR128:$src2)))]>;
2104  def UCmp128Hi : Pseudo<(outs), (ins VR128:$src1, VR128:$src2),
2105                         [(set CC, (z_ucmp128hi (i128 VR128:$src1),
2106                                                (i128 VR128:$src2)))]>;
2107}
2108
2109// i128 select pseudo-instructions.
2110let Predicates = [FeatureVector] in
2111  def Select128 : SelectWrapper<i128, VR128>;
2112
2113//===----------------------------------------------------------------------===//
2114// Conversions
2115//===----------------------------------------------------------------------===//
2116
2117let Predicates = [FeatureVector] in {
2118def : Pat<(v16i8 (bitconvert (v8i16 VR128:$src))), (v16i8 VR128:$src)>;
2119def : Pat<(v16i8 (bitconvert (v4i32 VR128:$src))), (v16i8 VR128:$src)>;
2120def : Pat<(v16i8 (bitconvert (v2i64 VR128:$src))), (v16i8 VR128:$src)>;
2121def : Pat<(v16i8 (bitconvert (i128  VR128:$src))), (v16i8 VR128:$src)>;
2122def : Pat<(v16i8 (bitconvert (v4f32 VR128:$src))), (v16i8 VR128:$src)>;
2123def : Pat<(v16i8 (bitconvert (v2f64 VR128:$src))), (v16i8 VR128:$src)>;
2124def : Pat<(v16i8 (bitconvert (f128  VR128:$src))), (v16i8 VR128:$src)>;
2125
2126def : Pat<(v8i16 (bitconvert (v16i8 VR128:$src))), (v8i16 VR128:$src)>;
2127def : Pat<(v8i16 (bitconvert (v4i32 VR128:$src))), (v8i16 VR128:$src)>;
2128def : Pat<(v8i16 (bitconvert (v2i64 VR128:$src))), (v8i16 VR128:$src)>;
2129def : Pat<(v8i16 (bitconvert (i128  VR128:$src))), (v8i16 VR128:$src)>;
2130def : Pat<(v8i16 (bitconvert (v4f32 VR128:$src))), (v8i16 VR128:$src)>;
2131def : Pat<(v8i16 (bitconvert (v2f64 VR128:$src))), (v8i16 VR128:$src)>;
2132def : Pat<(v8i16 (bitconvert (f128  VR128:$src))), (v8i16 VR128:$src)>;
2133
2134def : Pat<(v4i32 (bitconvert (v16i8 VR128:$src))), (v4i32 VR128:$src)>;
2135def : Pat<(v4i32 (bitconvert (v8i16 VR128:$src))), (v4i32 VR128:$src)>;
2136def : Pat<(v4i32 (bitconvert (v2i64 VR128:$src))), (v4i32 VR128:$src)>;
2137def : Pat<(v4i32 (bitconvert (i128  VR128:$src))), (v4i32 VR128:$src)>;
2138def : Pat<(v4i32 (bitconvert (v4f32 VR128:$src))), (v4i32 VR128:$src)>;
2139def : Pat<(v4i32 (bitconvert (v2f64 VR128:$src))), (v4i32 VR128:$src)>;
2140def : Pat<(v4i32 (bitconvert (f128  VR128:$src))), (v4i32 VR128:$src)>;
2141
2142def : Pat<(v2i64 (bitconvert (v16i8 VR128:$src))), (v2i64 VR128:$src)>;
2143def : Pat<(v2i64 (bitconvert (v8i16 VR128:$src))), (v2i64 VR128:$src)>;
2144def : Pat<(v2i64 (bitconvert (v4i32 VR128:$src))), (v2i64 VR128:$src)>;
2145def : Pat<(v2i64 (bitconvert (i128  VR128:$src))), (v2i64 VR128:$src)>;
2146def : Pat<(v2i64 (bitconvert (v4f32 VR128:$src))), (v2i64 VR128:$src)>;
2147def : Pat<(v2i64 (bitconvert (v2f64 VR128:$src))), (v2i64 VR128:$src)>;
2148def : Pat<(v2i64 (bitconvert (f128  VR128:$src))), (v2i64 VR128:$src)>;
2149
2150def : Pat<(v4f32 (bitconvert (v16i8 VR128:$src))), (v4f32 VR128:$src)>;
2151def : Pat<(v4f32 (bitconvert (v8i16 VR128:$src))), (v4f32 VR128:$src)>;
2152def : Pat<(v4f32 (bitconvert (v4i32 VR128:$src))), (v4f32 VR128:$src)>;
2153def : Pat<(v4f32 (bitconvert (i128  VR128:$src))), (v4f32 VR128:$src)>;
2154def : Pat<(v4f32 (bitconvert (v2i64 VR128:$src))), (v4f32 VR128:$src)>;
2155def : Pat<(v4f32 (bitconvert (v2f64 VR128:$src))), (v4f32 VR128:$src)>;
2156def : Pat<(v4f32 (bitconvert (f128  VR128:$src))), (v4f32 VR128:$src)>;
2157
2158def : Pat<(v2f64 (bitconvert (v16i8 VR128:$src))), (v2f64 VR128:$src)>;
2159def : Pat<(v2f64 (bitconvert (v8i16 VR128:$src))), (v2f64 VR128:$src)>;
2160def : Pat<(v2f64 (bitconvert (v4i32 VR128:$src))), (v2f64 VR128:$src)>;
2161def : Pat<(v2f64 (bitconvert (i128  VR128:$src))), (v2f64 VR128:$src)>;
2162def : Pat<(v2f64 (bitconvert (v2i64 VR128:$src))), (v2f64 VR128:$src)>;
2163def : Pat<(v2f64 (bitconvert (v4f32 VR128:$src))), (v2f64 VR128:$src)>;
2164def : Pat<(v2f64 (bitconvert (f128  VR128:$src))), (v2f64 VR128:$src)>;
2165
2166def : Pat<(f128  (bitconvert (v16i8 VR128:$src))), (f128  VR128:$src)>;
2167def : Pat<(f128  (bitconvert (v8i16 VR128:$src))), (f128  VR128:$src)>;
2168def : Pat<(f128  (bitconvert (v4i32 VR128:$src))), (f128  VR128:$src)>;
2169def : Pat<(f128  (bitconvert (v2i64 VR128:$src))), (f128  VR128:$src)>;
2170def : Pat<(f128  (bitconvert (i128  VR128:$src))), (f128  VR128:$src)>;
2171def : Pat<(f128  (bitconvert (v4f32 VR128:$src))), (f128  VR128:$src)>;
2172def : Pat<(f128  (bitconvert (v2f64 VR128:$src))), (f128  VR128:$src)>;
2173
2174def : Pat<(i128  (bitconvert (v16i8 VR128:$src))), (i128  VR128:$src)>;
2175def : Pat<(i128  (bitconvert (v8i16 VR128:$src))), (i128  VR128:$src)>;
2176def : Pat<(i128  (bitconvert (v4i32 VR128:$src))), (i128  VR128:$src)>;
2177def : Pat<(i128  (bitconvert (v2i64 VR128:$src))), (i128  VR128:$src)>;
2178def : Pat<(i128  (bitconvert (v4f32 VR128:$src))), (i128  VR128:$src)>;
2179def : Pat<(i128  (bitconvert (v2f64 VR128:$src))), (i128  VR128:$src)>;
2180def : Pat<(i128  (bitconvert (f128  VR128:$src))), (i128  VR128:$src)>;
2181} // End Predicates = [FeatureVector]
2182
2183//===----------------------------------------------------------------------===//
2184// Replicating scalars
2185//===----------------------------------------------------------------------===//
2186
2187// Define patterns for replicating a scalar GR32 into a vector of type TYPE.
2188// INDEX is 8 minus the element size in bytes.
2189class VectorReplicateScalar<ValueType type, Instruction insn, bits<16> index>
2190  : Pat<(type (z_replicate GR32:$scalar)),
2191        (insn (VLVGP32 GR32:$scalar, GR32:$scalar), index)>;
2192
2193def : VectorReplicateScalar<v16i8, VREPB, 7>;
2194def : VectorReplicateScalar<v8i16, VREPH, 3>;
2195def : VectorReplicateScalar<v4i32, VREPF, 1>;
2196
2197// i64 replications are just a single instruction.
2198def : Pat<(v2i64 (z_replicate GR64:$scalar)),
2199          (VLVGP GR64:$scalar, GR64:$scalar)>;
2200
2201//===----------------------------------------------------------------------===//
2202// Floating-point insertion and extraction
2203//===----------------------------------------------------------------------===//
2204
2205// Moving 32-bit values between GPRs and FPRs can be done using VLVGF
2206// and VLGVF.
2207let Predicates = [FeatureVector] in {
2208  def LEFR : UnaryAliasVRS<VR32, GR32>;
2209  def LFER : UnaryAliasVRS<GR64, VR32>;
2210  def : Pat<(f32 (bitconvert (i32 GR32:$src))), (LEFR GR32:$src)>;
2211  def : Pat<(i32 (bitconvert (f32 VR32:$src))),
2212            (EXTRACT_SUBREG (LFER VR32:$src), subreg_l32)>;
2213  def LEFR_16 : UnaryAliasVRS<VR16, GR32>;
2214  def LFER_16 : UnaryAliasVRS<GR32, VR16>;
2215}
2216
2217// Floating-point values are stored in element 0 of the corresponding
2218// vector register.  Scalar to vector conversion is just a subreg and
2219// scalar replication can just replicate element 0 of the vector register.
2220multiclass ScalarToVectorFP<Instruction vrep, ValueType vt, RegisterOperand cls,
2221                            SubRegIndex subreg> {
2222  def : Pat<(vt (scalar_to_vector cls:$scalar)),
2223            (INSERT_SUBREG (vt (IMPLICIT_DEF)), cls:$scalar, subreg)>;
2224  def : Pat<(vt (z_replicate cls:$scalar)),
2225            (vrep (INSERT_SUBREG (vt (IMPLICIT_DEF)), cls:$scalar,
2226                                 subreg), 0)>;
2227}
2228defm : ScalarToVectorFP<VREPF, v4f32, FP32, subreg_h32>;
2229defm : ScalarToVectorFP<VREPG, v2f64, FP64, subreg_h64>;
2230
2231// Match v2f64 insertions.  The AddedComplexity counters the 3 added by
2232// TableGen for the base register operand in VLVG-based integer insertions
2233// and ensures that this version is strictly better.
2234let AddedComplexity = 4 in {
2235  def : Pat<(z_vector_insert (v2f64 VR128:$vec), FP64:$elt, 0),
2236            (VPDI (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FP64:$elt,
2237                                 subreg_h64), VR128:$vec, 1)>;
2238  def : Pat<(z_vector_insert (v2f64 VR128:$vec), FP64:$elt, 1),
2239            (VPDI VR128:$vec, (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FP64:$elt,
2240                                             subreg_h64), 0)>;
2241}
2242
2243// We extract floating-point element X by replicating (for elements other
2244// than 0) and then taking a high subreg.  The AddedComplexity counters the
2245// 3 added by TableGen for the base register operand in VLGV-based integer
2246// extractions and ensures that this version is strictly better.
2247let AddedComplexity = 4 in {
2248  def : Pat<(f32 (z_vector_extract (v4f32 VR128:$vec), 0)),
2249            (EXTRACT_SUBREG VR128:$vec, subreg_h32)>;
2250  def : Pat<(f32 (z_vector_extract (v4f32 VR128:$vec), imm32zx2:$index)),
2251            (EXTRACT_SUBREG (VREPF VR128:$vec, imm32zx2:$index), subreg_h32)>;
2252
2253  def : Pat<(f64 (z_vector_extract (v2f64 VR128:$vec), 0)),
2254            (EXTRACT_SUBREG VR128:$vec, subreg_h64)>;
2255  def : Pat<(f64 (z_vector_extract (v2f64 VR128:$vec), imm32zx1:$index)),
2256            (EXTRACT_SUBREG (VREPG VR128:$vec, imm32zx1:$index), subreg_h64)>;
2257}
2258
2259//===----------------------------------------------------------------------===//
2260// Support for 128-bit floating-point values in vector registers
2261//===----------------------------------------------------------------------===//
2262
2263let Predicates = [FeatureVectorEnhancements1] in {
2264  def : Pat<(f128 (load bdxaddr12only:$addr)),
2265            (VL bdxaddr12only:$addr)>;
2266  def : Pat<(store (f128 VR128:$src), bdxaddr12only:$addr),
2267            (VST VR128:$src, bdxaddr12only:$addr)>;
2268
2269  def : Pat<(f128 fpimm0), (VZERO)>;
2270  def : Pat<(f128 fpimmneg0), (WFLNXB (VZERO))>;
2271}
2272
2273//===----------------------------------------------------------------------===//
2274// String instructions
2275//===----------------------------------------------------------------------===//
2276
2277let Predicates = [FeatureVector] in {
2278  defm VFAE  : TernaryOptVRRbSPairGeneric<"vfae", 0xE782>;
2279  defm VFAEB : TernaryOptVRRbSPair<"vfaeb", 0xE782, int_s390_vfaeb,
2280                                   z_vfae_cc, v128b, v128b, 0>;
2281  defm VFAEH : TernaryOptVRRbSPair<"vfaeh", 0xE782, int_s390_vfaeh,
2282                                   z_vfae_cc, v128h, v128h, 1>;
2283  defm VFAEF : TernaryOptVRRbSPair<"vfaef", 0xE782, int_s390_vfaef,
2284                                   z_vfae_cc, v128f, v128f, 2>;
2285  defm VFAEZB : TernaryOptVRRbSPair<"vfaezb", 0xE782, int_s390_vfaezb,
2286                                    z_vfaez_cc, v128b, v128b, 0, 2>;
2287  defm VFAEZH : TernaryOptVRRbSPair<"vfaezh", 0xE782, int_s390_vfaezh,
2288                                    z_vfaez_cc, v128h, v128h, 1, 2>;
2289  defm VFAEZF : TernaryOptVRRbSPair<"vfaezf", 0xE782, int_s390_vfaezf,
2290                                    z_vfaez_cc, v128f, v128f, 2, 2>;
2291
2292  defm VFEE  : BinaryExtraVRRbSPairGeneric<"vfee", 0xE780>;
2293  defm VFEEB : BinaryExtraVRRbSPair<"vfeeb", 0xE780, int_s390_vfeeb,
2294                                    z_vfee_cc, v128b, v128b, 0>;
2295  defm VFEEH : BinaryExtraVRRbSPair<"vfeeh", 0xE780, int_s390_vfeeh,
2296                                    z_vfee_cc, v128h, v128h, 1>;
2297  defm VFEEF : BinaryExtraVRRbSPair<"vfeef", 0xE780, int_s390_vfeef,
2298                                    z_vfee_cc, v128f, v128f, 2>;
2299  defm VFEEZB : BinaryVRRbSPair<"vfeezb", 0xE780, int_s390_vfeezb,
2300                                z_vfeez_cc, v128b, v128b, 0, 2>;
2301  defm VFEEZH : BinaryVRRbSPair<"vfeezh", 0xE780, int_s390_vfeezh,
2302                                z_vfeez_cc, v128h, v128h, 1, 2>;
2303  defm VFEEZF : BinaryVRRbSPair<"vfeezf", 0xE780, int_s390_vfeezf,
2304                                z_vfeez_cc, v128f, v128f, 2, 2>;
2305
2306  defm VFENE  : BinaryExtraVRRbSPairGeneric<"vfene", 0xE781>;
2307  defm VFENEB : BinaryExtraVRRbSPair<"vfeneb", 0xE781, int_s390_vfeneb,
2308                                     z_vfene_cc, v128b, v128b, 0>;
2309  defm VFENEH : BinaryExtraVRRbSPair<"vfeneh", 0xE781, int_s390_vfeneh,
2310                                     z_vfene_cc, v128h, v128h, 1>;
2311  defm VFENEF : BinaryExtraVRRbSPair<"vfenef", 0xE781, int_s390_vfenef,
2312                                     z_vfene_cc, v128f, v128f, 2>;
2313  defm VFENEZB : BinaryVRRbSPair<"vfenezb", 0xE781, int_s390_vfenezb,
2314                                 z_vfenez_cc, v128b, v128b, 0, 2>;
2315  defm VFENEZH : BinaryVRRbSPair<"vfenezh", 0xE781, int_s390_vfenezh,
2316                                 z_vfenez_cc, v128h, v128h, 1, 2>;
2317  defm VFENEZF : BinaryVRRbSPair<"vfenezf", 0xE781, int_s390_vfenezf,
2318                                 z_vfenez_cc, v128f, v128f, 2, 2>;
2319
2320  defm VISTR  : UnaryExtraVRRaSPairGeneric<"vistr", 0xE75C>;
2321  defm VISTRB : UnaryExtraVRRaSPair<"vistrb", 0xE75C, int_s390_vistrb,
2322                                    z_vistr_cc, v128b, v128b, 0>;
2323  defm VISTRH : UnaryExtraVRRaSPair<"vistrh", 0xE75C, int_s390_vistrh,
2324                                    z_vistr_cc, v128h, v128h, 1>;
2325  defm VISTRF : UnaryExtraVRRaSPair<"vistrf", 0xE75C, int_s390_vistrf,
2326                                    z_vistr_cc, v128f, v128f, 2>;
2327
2328  defm VSTRC  : QuaternaryOptVRRdSPairGeneric<"vstrc", 0xE78A>;
2329  defm VSTRCB : QuaternaryOptVRRdSPair<"vstrcb", 0xE78A, int_s390_vstrcb,
2330                                       z_vstrc_cc, v128b, v128b, 0>;
2331  defm VSTRCH : QuaternaryOptVRRdSPair<"vstrch", 0xE78A, int_s390_vstrch,
2332                                       z_vstrc_cc, v128h, v128h, 1>;
2333  defm VSTRCF : QuaternaryOptVRRdSPair<"vstrcf", 0xE78A, int_s390_vstrcf,
2334                                       z_vstrc_cc, v128f, v128f, 2>;
2335  defm VSTRCZB : QuaternaryOptVRRdSPair<"vstrczb", 0xE78A, int_s390_vstrczb,
2336                                        z_vstrcz_cc, v128b, v128b, 0, 2>;
2337  defm VSTRCZH : QuaternaryOptVRRdSPair<"vstrczh", 0xE78A, int_s390_vstrczh,
2338                                        z_vstrcz_cc, v128h, v128h, 1, 2>;
2339  defm VSTRCZF : QuaternaryOptVRRdSPair<"vstrczf", 0xE78A, int_s390_vstrczf,
2340                                        z_vstrcz_cc, v128f, v128f, 2, 2>;
2341}
2342
2343let Predicates = [FeatureVectorEnhancements2] in {
2344  defm VSTRS  : TernaryExtraVRRdGeneric<"vstrs", 0xE78B>;
2345  defm VSTRSB : TernaryExtraVRRd<"vstrsb", 0xE78B,
2346                                 z_vstrs_cc, v128b, v128b, 0>;
2347  defm VSTRSH : TernaryExtraVRRd<"vstrsh", 0xE78B,
2348                                 z_vstrs_cc, v128b, v128h, 1>;
2349  defm VSTRSF : TernaryExtraVRRd<"vstrsf", 0xE78B,
2350                                 z_vstrs_cc, v128b, v128f, 2>;
2351  let Defs = [CC] in {
2352    def VSTRSZB : TernaryVRRd<"vstrszb", 0xE78B,
2353                              z_vstrsz_cc, v128b, v128b, 0, 2>;
2354    def VSTRSZH : TernaryVRRd<"vstrszh", 0xE78B,
2355                              z_vstrsz_cc, v128b, v128h, 1, 2>;
2356    def VSTRSZF : TernaryVRRd<"vstrszf", 0xE78B,
2357                              z_vstrsz_cc, v128b, v128f, 2, 2>;
2358  }
2359}
2360
2361//===----------------------------------------------------------------------===//
2362// NNP assist instructions
2363//===----------------------------------------------------------------------===//
2364
2365let Predicates = [FeatureVector, FeatureNNPAssist] in {
2366  let Uses = [FPC], mayRaiseFPException = 1 in
2367    def VCFN : UnaryVRRaFloatGeneric<"vcfn", 0xE65D>;
2368  def : Pat<(int_s390_vcfn VR128:$x, imm32zx4_timm:$m),
2369            (VCFN VR128:$x, 1, imm32zx4:$m)>;
2370
2371  let Uses = [FPC], mayRaiseFPException = 1 in
2372    def VCLFNL : UnaryVRRaFloatGeneric<"vclfnl", 0xE65E>;
2373  def : Pat<(int_s390_vclfnls VR128:$x, imm32zx4_timm:$m),
2374            (VCLFNL VR128:$x, 2, imm32zx4:$m)>;
2375
2376  let Uses = [FPC], mayRaiseFPException = 1 in
2377    def VCLFNH : UnaryVRRaFloatGeneric<"vclfnh", 0xE656>;
2378  def : Pat<(int_s390_vclfnhs VR128:$x, imm32zx4_timm:$m),
2379            (VCLFNH VR128:$x, 2, imm32zx4:$m)>;
2380
2381  let Uses = [FPC], mayRaiseFPException = 1 in
2382    def VCNF : UnaryVRRaFloatGeneric<"vcnf", 0xE655>;
2383  def : Pat<(int_s390_vcnf VR128:$x, imm32zx4_timm:$m),
2384            (VCNF VR128:$x, imm32zx4:$m, 1)>;
2385
2386  let Uses = [FPC], mayRaiseFPException = 1 in
2387    def VCRNF : BinaryVRRcFloatGeneric<"vcrnf", 0xE675>;
2388  def : Pat<(int_s390_vcrnfs VR128:$x, VR128:$y, imm32zx4_timm:$m),
2389            (VCRNF VR128:$x, VR128:$y, imm32zx4:$m, 2)>;
2390}
2391
2392//===----------------------------------------------------------------------===//
2393// Packed-decimal instructions
2394//===----------------------------------------------------------------------===//
2395
2396let Predicates = [FeatureVectorPackedDecimal] in {
2397  def VLIP : BinaryVRIh<"vlip", 0xE649>;
2398
2399  def VPKZ : BinaryVSI<"vpkz", 0xE634, null_frag, 0>;
2400  def VUPKZ : StoreLengthVSI<"vupkz", 0xE63C, null_frag, 0>;
2401
2402  let Defs = [CC] in {
2403    let Predicates = [FeatureVectorPackedDecimalEnhancement] in {
2404      def VCVBOpt : TernaryVRRi<"vcvb", 0xE650, GR32>;
2405      def VCVBGOpt : TernaryVRRi<"vcvbg", 0xE652, GR64>;
2406    }
2407    def VCVB : BinaryVRRi<"vcvb", 0xE650, GR32>;
2408    def VCVBG : BinaryVRRi<"vcvbg", 0xE652, GR64>;
2409    def VCVD : TernaryVRIi<"vcvd", 0xE658, GR32>;
2410    def VCVDG : TernaryVRIi<"vcvdg", 0xE65A, GR64>;
2411
2412    def VAP : QuaternaryVRIf<"vap", 0xE671>;
2413    def VSP : QuaternaryVRIf<"vsp", 0xE673>;
2414
2415    def VMP : QuaternaryVRIf<"vmp", 0xE678>;
2416    def VMSP : QuaternaryVRIf<"vmsp", 0xE679>;
2417
2418    def VDP : QuaternaryVRIf<"vdp", 0xE67A>;
2419    def VRP : QuaternaryVRIf<"vrp", 0xE67B>;
2420    def VSDP : QuaternaryVRIf<"vsdp", 0xE67E>;
2421
2422    def VSRP : QuaternaryVRIg<"vsrp", 0xE659>;
2423    def VPSOP : QuaternaryVRIg<"vpsop", 0xE65B>;
2424
2425    def VTP : TestVRRg<"vtp", 0xE65F>;
2426    def VCP : CompareVRRh<"vcp", 0xE677>;
2427  }
2428}
2429
2430let Predicates = [FeatureVectorPackedDecimalEnhancement2] in {
2431  def VSCHP : BinaryExtraVRRbGeneric<"vschp", 0xE674>;
2432  def VSCHSP : BinaryExtraVRRb<"vschsp", 0xE674, 2>;
2433  def VSCHDP : BinaryExtraVRRb<"vschdp", 0xE674, 3>;
2434  def VSCHXP : BinaryExtraVRRb<"vschxp", 0xE674, 4>;
2435
2436  def VSCSHP : BinaryVRRb<"vscshp", 0xE67C, null_frag, v128b, v128b>;
2437
2438  def VCSPH : TernaryVRRj<"vcsph", 0xE67D>;
2439
2440  let Defs = [CC] in
2441    def VCLZDP : BinaryVRRk<"vclzdp", 0xE651>;
2442
2443  let Defs = [CC] in
2444    def VSRPR : QuaternaryVRIf<"vsrpr", 0xE672>;
2445
2446  let Defs = [CC] in {
2447    def VPKZR : QuaternaryVRIf<"vpkzr", 0xE670>;
2448    def VUPKZH : BinaryVRRk<"vupkzh", 0xE654>;
2449    def VUPKZL : BinaryVRRk<"vupkzl", 0xE65C>;
2450  }
2451}
2452
2453let Predicates = [FeatureVectorPackedDecimalEnhancement3] in {
2454  def VCVBQ : BinaryVRRk<"vcvbq", 0xE64E>;
2455  let Defs = [CC] in
2456    def VCVDQ : TernaryVRIj<"vcvdq", 0xE64A>;
2457
2458  let Defs = [CC] in {
2459    def VTPOpt : TestExtraVRRg<"vtp", 0xE65F>;
2460    def VTZ : TestExtraVRIl<"vtz", 0xE67F>;
2461  }
2462}
2463