xref: /freebsd/contrib/llvm-project/llvm/lib/Target/SystemZ/SystemZInstrVector.td (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric//==- SystemZInstrVector.td - SystemZ Vector instructions ------*- tblgen-*-==//
20b57cec5SDimitry Andric//
30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric//
70b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
100b57cec5SDimitry Andric// Move instructions
110b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andriclet Predicates = [FeatureVector] in {
140b57cec5SDimitry Andric  // Register move.
150b57cec5SDimitry Andric  def VLR : UnaryVRRa<"vlr", 0xE756, null_frag, v128any, v128any>;
160b57cec5SDimitry Andric  def VLR32 : UnaryAliasVRR<null_frag, v32sb, v32sb>;
170b57cec5SDimitry Andric  def VLR64 : UnaryAliasVRR<null_frag, v64db, v64db>;
180b57cec5SDimitry Andric
190b57cec5SDimitry Andric  // Load GR from VR element.
200b57cec5SDimitry Andric  def VLGV  : BinaryVRScGeneric<"vlgv", 0xE721>;
210b57cec5SDimitry Andric  def VLGVB : BinaryVRSc<"vlgvb", 0xE721, null_frag, v128b, 0>;
220b57cec5SDimitry Andric  def VLGVH : BinaryVRSc<"vlgvh", 0xE721, null_frag, v128h, 1>;
230b57cec5SDimitry Andric  def VLGVF : BinaryVRSc<"vlgvf", 0xE721, null_frag, v128f, 2>;
240b57cec5SDimitry Andric  def VLGVG : BinaryVRSc<"vlgvg", 0xE721, z_vector_extract, v128g, 3>;
250b57cec5SDimitry Andric
260b57cec5SDimitry Andric  // Load VR element from GR.
270b57cec5SDimitry Andric  def VLVG  : TernaryVRSbGeneric<"vlvg", 0xE722>;
280b57cec5SDimitry Andric  def VLVGB : TernaryVRSb<"vlvgb", 0xE722, z_vector_insert,
290b57cec5SDimitry Andric                          v128b, v128b, GR32, 0>;
300b57cec5SDimitry Andric  def VLVGH : TernaryVRSb<"vlvgh", 0xE722, z_vector_insert,
310b57cec5SDimitry Andric                          v128h, v128h, GR32, 1>;
320b57cec5SDimitry Andric  def VLVGF : TernaryVRSb<"vlvgf", 0xE722, z_vector_insert,
330b57cec5SDimitry Andric                          v128f, v128f, GR32, 2>;
340b57cec5SDimitry Andric  def VLVGG : TernaryVRSb<"vlvgg", 0xE722, z_vector_insert,
350b57cec5SDimitry Andric                          v128g, v128g, GR64, 3>;
360b57cec5SDimitry Andric
370b57cec5SDimitry Andric  // Load VR from GRs disjoint.
380b57cec5SDimitry Andric  def VLVGP : BinaryVRRf<"vlvgp", 0xE762, z_join_dwords, v128g>;
390b57cec5SDimitry Andric  def VLVGP32 : BinaryAliasVRRf<GR32>;
400b57cec5SDimitry Andric}
410b57cec5SDimitry Andric
420b57cec5SDimitry Andric// Extractions always assign to the full GR64, even if the element would
430b57cec5SDimitry Andric// fit in the lower 32 bits.  Sub-i64 extracts therefore need to take a
440b57cec5SDimitry Andric// subreg of the result.
450b57cec5SDimitry Andricclass VectorExtractSubreg<ValueType type, Instruction insn>
460b57cec5SDimitry Andric  : Pat<(i32 (z_vector_extract (type VR128:$vec), shift12only:$index)),
470b57cec5SDimitry Andric        (EXTRACT_SUBREG (insn VR128:$vec, shift12only:$index), subreg_l32)>;
480b57cec5SDimitry Andric
490b57cec5SDimitry Andricdef : VectorExtractSubreg<v16i8, VLGVB>;
500b57cec5SDimitry Andricdef : VectorExtractSubreg<v8i16, VLGVH>;
510b57cec5SDimitry Andricdef : VectorExtractSubreg<v4i32, VLGVF>;
520b57cec5SDimitry Andric
530b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
540b57cec5SDimitry Andric// Immediate instructions
550b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
560b57cec5SDimitry Andric
570b57cec5SDimitry Andriclet Predicates = [FeatureVector] in {
580b57cec5SDimitry Andric  let isAsCheapAsAMove = 1, isMoveImm = 1, isReMaterializable = 1 in {
590b57cec5SDimitry Andric
600b57cec5SDimitry Andric    // Generate byte mask.
610b57cec5SDimitry Andric    def VZERO : InherentVRIa<"vzero", 0xE744, 0>;
620b57cec5SDimitry Andric    def VONE  : InherentVRIa<"vone", 0xE744, 0xffff>;
638bcb0991SDimitry Andric    def VGBM  : UnaryVRIa<"vgbm", 0xE744, z_byte_mask, v128b, imm32zx16_timm>;
640b57cec5SDimitry Andric
650b57cec5SDimitry Andric    // Generate mask.
660b57cec5SDimitry Andric    def VGM  : BinaryVRIbGeneric<"vgm", 0xE746>;
670b57cec5SDimitry Andric    def VGMB : BinaryVRIb<"vgmb", 0xE746, z_rotate_mask, v128b, 0>;
680b57cec5SDimitry Andric    def VGMH : BinaryVRIb<"vgmh", 0xE746, z_rotate_mask, v128h, 1>;
690b57cec5SDimitry Andric    def VGMF : BinaryVRIb<"vgmf", 0xE746, z_rotate_mask, v128f, 2>;
700b57cec5SDimitry Andric    def VGMG : BinaryVRIb<"vgmg", 0xE746, z_rotate_mask, v128g, 3>;
710b57cec5SDimitry Andric
720b57cec5SDimitry Andric    // Replicate immediate.
730b57cec5SDimitry Andric    def VREPI  : UnaryVRIaGeneric<"vrepi", 0xE745, imm32sx16>;
748bcb0991SDimitry Andric    def VREPIB : UnaryVRIa<"vrepib", 0xE745, z_replicate, v128b, imm32sx16_timm, 0>;
758bcb0991SDimitry Andric    def VREPIH : UnaryVRIa<"vrepih", 0xE745, z_replicate, v128h, imm32sx16_timm, 1>;
768bcb0991SDimitry Andric    def VREPIF : UnaryVRIa<"vrepif", 0xE745, z_replicate, v128f, imm32sx16_timm, 2>;
778bcb0991SDimitry Andric    def VREPIG : UnaryVRIa<"vrepig", 0xE745, z_replicate, v128g, imm32sx16_timm, 3>;
780b57cec5SDimitry Andric  }
790b57cec5SDimitry Andric
800b57cec5SDimitry Andric  // Load element immediate.
810b57cec5SDimitry Andric  //
820b57cec5SDimitry Andric  // We want these instructions to be used ahead of VLVG* where possible.
830b57cec5SDimitry Andric  // However, VLVG* takes a variable BD-format index whereas VLEI takes
840b57cec5SDimitry Andric  // a plain immediate index.  This means that VLVG* has an extra "base"
850b57cec5SDimitry Andric  // register operand and is 3 units more complex.  Bumping the complexity
860b57cec5SDimitry Andric  // of the VLEI* instructions by 4 means that they are strictly better
870b57cec5SDimitry Andric  // than VLVG* in cases where both forms match.
880b57cec5SDimitry Andric  let AddedComplexity = 4 in {
890b57cec5SDimitry Andric    def VLEIB : TernaryVRIa<"vleib", 0xE740, z_vector_insert,
900b57cec5SDimitry Andric                            v128b, v128b, imm32sx16trunc, imm32zx4>;
910b57cec5SDimitry Andric    def VLEIH : TernaryVRIa<"vleih", 0xE741, z_vector_insert,
920b57cec5SDimitry Andric                            v128h, v128h, imm32sx16trunc, imm32zx3>;
930b57cec5SDimitry Andric    def VLEIF : TernaryVRIa<"vleif", 0xE743, z_vector_insert,
940b57cec5SDimitry Andric                            v128f, v128f, imm32sx16, imm32zx2>;
950b57cec5SDimitry Andric    def VLEIG : TernaryVRIa<"vleig", 0xE742, z_vector_insert,
960b57cec5SDimitry Andric                            v128g, v128g, imm64sx16, imm32zx1>;
970b57cec5SDimitry Andric  }
980b57cec5SDimitry Andric}
990b57cec5SDimitry Andric
1000b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
1010b57cec5SDimitry Andric// Loads
1020b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
1030b57cec5SDimitry Andric
1040b57cec5SDimitry Andriclet Predicates = [FeatureVector] in {
1050b57cec5SDimitry Andric  // Load.
1060b57cec5SDimitry Andric  defm VL : UnaryVRXAlign<"vl", 0xE706>;
1070b57cec5SDimitry Andric
1080b57cec5SDimitry Andric  // Load to block boundary.  The number of loaded bytes is only known
1090b57cec5SDimitry Andric  // at run time.  The instruction is really polymorphic, but v128b matches
1100b57cec5SDimitry Andric  // the return type of the associated intrinsic.
1110b57cec5SDimitry Andric  def VLBB : BinaryVRX<"vlbb", 0xE707, int_s390_vlbb, v128b, 0>;
1120b57cec5SDimitry Andric
1130b57cec5SDimitry Andric  // Load count to block boundary.
1140b57cec5SDimitry Andric  let Defs = [CC] in
1150b57cec5SDimitry Andric    def LCBB : InstRXE<0xE727, (outs GR32:$R1),
11606c3fb27SDimitry Andric                               (ins (bdxaddr12only $B2, $D2, $X2):$XBD2, imm32zx4:$M3),
1170b57cec5SDimitry Andric                       "lcbb\t$R1, $XBD2, $M3",
1180b57cec5SDimitry Andric                       [(set GR32:$R1, (int_s390_lcbb bdxaddr12only:$XBD2,
1198bcb0991SDimitry Andric                                                      imm32zx4_timm:$M3))]>;
1200b57cec5SDimitry Andric
1210b57cec5SDimitry Andric  // Load with length.  The number of loaded bytes is only known at run time.
1220b57cec5SDimitry Andric  def VLL : BinaryVRSb<"vll", 0xE737, int_s390_vll, 0>;
1230b57cec5SDimitry Andric
1240b57cec5SDimitry Andric  // Load multiple.
1250b57cec5SDimitry Andric  defm VLM : LoadMultipleVRSaAlign<"vlm", 0xE736>;
1260b57cec5SDimitry Andric
1270b57cec5SDimitry Andric  // Load and replicate
1280b57cec5SDimitry Andric  def VLREP  : UnaryVRXGeneric<"vlrep", 0xE705>;
1290b57cec5SDimitry Andric  def VLREPB : UnaryVRX<"vlrepb", 0xE705, z_replicate_loadi8,  v128b, 1, 0>;
1300b57cec5SDimitry Andric  def VLREPH : UnaryVRX<"vlreph", 0xE705, z_replicate_loadi16, v128h, 2, 1>;
1310b57cec5SDimitry Andric  def VLREPF : UnaryVRX<"vlrepf", 0xE705, z_replicate_loadi32, v128f, 4, 2>;
1320b57cec5SDimitry Andric  def VLREPG : UnaryVRX<"vlrepg", 0xE705, z_replicate_loadi64, v128g, 8, 3>;
1330b57cec5SDimitry Andric  def : Pat<(v4f32 (z_replicate_loadf32 bdxaddr12only:$addr)),
1340b57cec5SDimitry Andric            (VLREPF bdxaddr12only:$addr)>;
1350b57cec5SDimitry Andric  def : Pat<(v2f64 (z_replicate_loadf64 bdxaddr12only:$addr)),
1360b57cec5SDimitry Andric            (VLREPG bdxaddr12only:$addr)>;
1370b57cec5SDimitry Andric
1380b57cec5SDimitry Andric  // Use VLREP to load subvectors.  These patterns use "12pair" because
1390b57cec5SDimitry Andric  // LEY and LDY offer full 20-bit displacement fields.  It's often better
1400b57cec5SDimitry Andric  // to use those instructions rather than force a 20-bit displacement
1410b57cec5SDimitry Andric  // into a GPR temporary.
142*0fca6ea1SDimitry Andric  let mayLoad = 1, canFoldAsLoad = 1 in {
143*0fca6ea1SDimitry Andric    def VL32 : UnaryAliasVRX<z_load, v32sb, bdxaddr12pair>;
144*0fca6ea1SDimitry Andric    def VL64 : UnaryAliasVRX<z_load, v64db, bdxaddr12pair>;
1450b57cec5SDimitry Andric  }
1460b57cec5SDimitry Andric
1470b57cec5SDimitry Andric  // Load logical element and zero.
1480b57cec5SDimitry Andric  def VLLEZ  : UnaryVRXGeneric<"vllez", 0xE704>;
1490b57cec5SDimitry Andric  def VLLEZB : UnaryVRX<"vllezb", 0xE704, z_vllezi8,  v128b, 1, 0>;
1500b57cec5SDimitry Andric  def VLLEZH : UnaryVRX<"vllezh", 0xE704, z_vllezi16, v128h, 2, 1>;
1510b57cec5SDimitry Andric  def VLLEZF : UnaryVRX<"vllezf", 0xE704, z_vllezi32, v128f, 4, 2>;
1520b57cec5SDimitry Andric  def VLLEZG : UnaryVRX<"vllezg", 0xE704, z_vllezi64, v128g, 8, 3>;
1530b57cec5SDimitry Andric  def : Pat<(z_vllezf32 bdxaddr12only:$addr),
1540b57cec5SDimitry Andric            (VLLEZF bdxaddr12only:$addr)>;
1550b57cec5SDimitry Andric  def : Pat<(z_vllezf64 bdxaddr12only:$addr),
1560b57cec5SDimitry Andric            (VLLEZG bdxaddr12only:$addr)>;
1570b57cec5SDimitry Andric  let Predicates = [FeatureVectorEnhancements1] in {
1580b57cec5SDimitry Andric    def VLLEZLF : UnaryVRX<"vllezlf", 0xE704, z_vllezli32, v128f, 4, 6>;
1590b57cec5SDimitry Andric    def : Pat<(z_vllezlf32 bdxaddr12only:$addr),
1600b57cec5SDimitry Andric              (VLLEZLF bdxaddr12only:$addr)>;
1610b57cec5SDimitry Andric  }
1620b57cec5SDimitry Andric
1630b57cec5SDimitry Andric  // Load element.
1640b57cec5SDimitry Andric  def VLEB : TernaryVRX<"vleb", 0xE700, z_vlei8,  v128b, v128b, 1, imm32zx4>;
1650b57cec5SDimitry Andric  def VLEH : TernaryVRX<"vleh", 0xE701, z_vlei16, v128h, v128h, 2, imm32zx3>;
1660b57cec5SDimitry Andric  def VLEF : TernaryVRX<"vlef", 0xE703, z_vlei32, v128f, v128f, 4, imm32zx2>;
1670b57cec5SDimitry Andric  def VLEG : TernaryVRX<"vleg", 0xE702, z_vlei64, v128g, v128g, 8, imm32zx1>;
1680b57cec5SDimitry Andric  def : Pat<(z_vlef32 (v4f32 VR128:$val), bdxaddr12only:$addr, imm32zx2:$index),
1690b57cec5SDimitry Andric            (VLEF VR128:$val, bdxaddr12only:$addr, imm32zx2:$index)>;
1700b57cec5SDimitry Andric  def : Pat<(z_vlef64 (v2f64 VR128:$val), bdxaddr12only:$addr, imm32zx1:$index),
1710b57cec5SDimitry Andric            (VLEG VR128:$val, bdxaddr12only:$addr, imm32zx1:$index)>;
1720b57cec5SDimitry Andric
1730b57cec5SDimitry Andric  // Gather element.
1740b57cec5SDimitry Andric  def VGEF : TernaryVRV<"vgef", 0xE713, 4, imm32zx2>;
1750b57cec5SDimitry Andric  def VGEG : TernaryVRV<"vgeg", 0xE712, 8, imm32zx1>;
1760b57cec5SDimitry Andric}
1770b57cec5SDimitry Andric
1780b57cec5SDimitry Andriclet Predicates = [FeatureVectorPackedDecimal] in {
1790b57cec5SDimitry Andric  // Load rightmost with length.  The number of loaded bytes is only known
1805ffd83dbSDimitry Andric  // at run time.  Note that while the instruction will accept immediate
1815ffd83dbSDimitry Andric  // lengths larger that 15 at runtime, those will always result in a trap,
1825ffd83dbSDimitry Andric  // so we never emit them here.
1835ffd83dbSDimitry Andric  def VLRL : BinaryVSI<"vlrl", 0xE635, null_frag, 0>;
1840b57cec5SDimitry Andric  def VLRLR : BinaryVRSd<"vlrlr", 0xE637, int_s390_vlrl, 0>;
1855ffd83dbSDimitry Andric  def : Pat<(int_s390_vlrl imm32zx4:$len, bdaddr12only:$addr),
1865ffd83dbSDimitry Andric            (VLRL bdaddr12only:$addr, imm32zx4:$len)>;
1870b57cec5SDimitry Andric}
1880b57cec5SDimitry Andric
1890b57cec5SDimitry Andric// Use replicating loads if we're inserting a single element into an
1900b57cec5SDimitry Andric// undefined vector.  This avoids a false dependency on the previous
1910b57cec5SDimitry Andric// register contents.
1920b57cec5SDimitry Andricmulticlass ReplicatePeephole<Instruction vlrep, ValueType vectype,
1930b57cec5SDimitry Andric                             SDPatternOperator load, ValueType scalartype> {
1940b57cec5SDimitry Andric  def : Pat<(vectype (z_vector_insert
1950b57cec5SDimitry Andric                      (undef), (scalartype (load bdxaddr12only:$addr)), 0)),
1960b57cec5SDimitry Andric            (vlrep bdxaddr12only:$addr)>;
1970b57cec5SDimitry Andric  def : Pat<(vectype (scalar_to_vector
1980b57cec5SDimitry Andric                      (scalartype (load bdxaddr12only:$addr)))),
1990b57cec5SDimitry Andric            (vlrep bdxaddr12only:$addr)>;
2000b57cec5SDimitry Andric}
201*0fca6ea1SDimitry Andricdefm : ReplicatePeephole<VLREPB, v16i8, z_anyextloadi8, i32>;
202*0fca6ea1SDimitry Andricdefm : ReplicatePeephole<VLREPH, v8i16, z_anyextloadi16, i32>;
203*0fca6ea1SDimitry Andricdefm : ReplicatePeephole<VLREPF, v4i32, z_load, i32>;
204*0fca6ea1SDimitry Andricdefm : ReplicatePeephole<VLREPG, v2i64, z_load, i64>;
205*0fca6ea1SDimitry Andricdefm : ReplicatePeephole<VLREPF, v4f32, z_load, f32>;
206*0fca6ea1SDimitry Andricdefm : ReplicatePeephole<VLREPG, v2f64, z_load, f64>;
2070b57cec5SDimitry Andric
2080b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
2090b57cec5SDimitry Andric// Stores
2100b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
2110b57cec5SDimitry Andric
2120b57cec5SDimitry Andriclet Predicates = [FeatureVector] in {
2130b57cec5SDimitry Andric  // Store.
2140b57cec5SDimitry Andric  defm VST : StoreVRXAlign<"vst", 0xE70E>;
2150b57cec5SDimitry Andric
2160b57cec5SDimitry Andric  // Store with length.  The number of stored bytes is only known at run time.
2170b57cec5SDimitry Andric  def VSTL : StoreLengthVRSb<"vstl", 0xE73F, int_s390_vstl, 0>;
2180b57cec5SDimitry Andric
2190b57cec5SDimitry Andric  // Store multiple.
2200b57cec5SDimitry Andric  defm VSTM : StoreMultipleVRSaAlign<"vstm", 0xE73E>;
2210b57cec5SDimitry Andric
2220b57cec5SDimitry Andric  // Store element.
2230b57cec5SDimitry Andric  def VSTEB : StoreBinaryVRX<"vsteb", 0xE708, z_vstei8,  v128b, 1, imm32zx4>;
2240b57cec5SDimitry Andric  def VSTEH : StoreBinaryVRX<"vsteh", 0xE709, z_vstei16, v128h, 2, imm32zx3>;
2250b57cec5SDimitry Andric  def VSTEF : StoreBinaryVRX<"vstef", 0xE70B, z_vstei32, v128f, 4, imm32zx2>;
2260b57cec5SDimitry Andric  def VSTEG : StoreBinaryVRX<"vsteg", 0xE70A, z_vstei64, v128g, 8, imm32zx1>;
2270b57cec5SDimitry Andric  def : Pat<(z_vstef32 (v4f32 VR128:$val), bdxaddr12only:$addr,
2280b57cec5SDimitry Andric                       imm32zx2:$index),
2290b57cec5SDimitry Andric            (VSTEF VR128:$val, bdxaddr12only:$addr, imm32zx2:$index)>;
2300b57cec5SDimitry Andric  def : Pat<(z_vstef64 (v2f64 VR128:$val), bdxaddr12only:$addr,
2310b57cec5SDimitry Andric                       imm32zx1:$index),
2320b57cec5SDimitry Andric            (VSTEG VR128:$val, bdxaddr12only:$addr, imm32zx1:$index)>;
2330b57cec5SDimitry Andric
2340b57cec5SDimitry Andric  // Use VSTE to store subvectors.  These patterns use "12pair" because
2350b57cec5SDimitry Andric  // STEY and STDY offer full 20-bit displacement fields.  It's often better
2360b57cec5SDimitry Andric  // to use those instructions rather than force a 20-bit displacement
2370b57cec5SDimitry Andric  // into a GPR temporary.
2380b57cec5SDimitry Andric  let mayStore = 1 in {
2390b57cec5SDimitry Andric    def VST32 : StoreAliasVRX<store, v32sb, bdxaddr12pair>;
2400b57cec5SDimitry Andric    def VST64 : StoreAliasVRX<store, v64db, bdxaddr12pair>;
2410b57cec5SDimitry Andric  }
2420b57cec5SDimitry Andric
2430b57cec5SDimitry Andric  // Scatter element.
2440b57cec5SDimitry Andric  def VSCEF : StoreBinaryVRV<"vscef", 0xE71B, 4, imm32zx2>;
2450b57cec5SDimitry Andric  def VSCEG : StoreBinaryVRV<"vsceg", 0xE71A, 8, imm32zx1>;
2460b57cec5SDimitry Andric}
2470b57cec5SDimitry Andric
2480b57cec5SDimitry Andriclet Predicates = [FeatureVectorPackedDecimal] in {
2490b57cec5SDimitry Andric  // Store rightmost with length.  The number of stored bytes is only known
2505ffd83dbSDimitry Andric  // at run time.  Note that while the instruction will accept immediate
2515ffd83dbSDimitry Andric  // lengths larger that 15 at runtime, those will always result in a trap,
2525ffd83dbSDimitry Andric  // so we never emit them here.
2535ffd83dbSDimitry Andric  def VSTRL : StoreLengthVSI<"vstrl", 0xE63D, null_frag, 0>;
2540b57cec5SDimitry Andric  def VSTRLR : StoreLengthVRSd<"vstrlr", 0xE63F, int_s390_vstrl, 0>;
2555ffd83dbSDimitry Andric  def : Pat<(int_s390_vstrl VR128:$val, imm32zx4:$len, bdaddr12only:$addr),
2565ffd83dbSDimitry Andric            (VSTRL VR128:$val, bdaddr12only:$addr, imm32zx4:$len)>;
2570b57cec5SDimitry Andric}
2580b57cec5SDimitry Andric
2590b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
2600b57cec5SDimitry Andric// Byte swaps
2610b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
2620b57cec5SDimitry Andric
2630b57cec5SDimitry Andriclet Predicates = [FeatureVectorEnhancements2] in {
2640b57cec5SDimitry Andric  // Load byte-reversed elements.
2650b57cec5SDimitry Andric  def VLBR  : UnaryVRXGeneric<"vlbr", 0xE606>;
2660b57cec5SDimitry Andric  def VLBRH : UnaryVRX<"vlbrh", 0xE606, z_loadbswap, v128h, 16, 1>;
2670b57cec5SDimitry Andric  def VLBRF : UnaryVRX<"vlbrf", 0xE606, z_loadbswap, v128f, 16, 2>;
2680b57cec5SDimitry Andric  def VLBRG : UnaryVRX<"vlbrg", 0xE606, z_loadbswap, v128g, 16, 3>;
2695f757f3fSDimitry Andric  def VLBRQ : UnaryVRX<"vlbrq", 0xE606, z_loadbswap, v128q, 16, 4>;
2700b57cec5SDimitry Andric
2710b57cec5SDimitry Andric  // Load elements reversed.
2720b57cec5SDimitry Andric  def VLER  : UnaryVRXGeneric<"vler", 0xE607>;
2730b57cec5SDimitry Andric  def VLERH : UnaryVRX<"vlerh", 0xE607, z_loadeswap, v128h, 16, 1>;
2740b57cec5SDimitry Andric  def VLERF : UnaryVRX<"vlerf", 0xE607, z_loadeswap, v128f, 16, 2>;
2750b57cec5SDimitry Andric  def VLERG : UnaryVRX<"vlerg", 0xE607, z_loadeswap, v128g, 16, 3>;
2760b57cec5SDimitry Andric  def : Pat<(v4f32 (z_loadeswap bdxaddr12only:$addr)),
2770b57cec5SDimitry Andric            (VLERF bdxaddr12only:$addr)>;
2780b57cec5SDimitry Andric  def : Pat<(v2f64 (z_loadeswap bdxaddr12only:$addr)),
2790b57cec5SDimitry Andric            (VLERG bdxaddr12only:$addr)>;
2800b57cec5SDimitry Andric  def : Pat<(v16i8 (z_loadeswap bdxaddr12only:$addr)),
2810b57cec5SDimitry Andric            (VLBRQ bdxaddr12only:$addr)>;
2820b57cec5SDimitry Andric
2830b57cec5SDimitry Andric  // Load byte-reversed element.
2840b57cec5SDimitry Andric  def VLEBRH : TernaryVRX<"vlebrh", 0xE601, z_vlebri16, v128h, v128h, 2, imm32zx3>;
2850b57cec5SDimitry Andric  def VLEBRF : TernaryVRX<"vlebrf", 0xE603, z_vlebri32, v128f, v128f, 4, imm32zx2>;
2860b57cec5SDimitry Andric  def VLEBRG : TernaryVRX<"vlebrg", 0xE602, z_vlebri64, v128g, v128g, 8, imm32zx1>;
2870b57cec5SDimitry Andric
2880b57cec5SDimitry Andric  // Load byte-reversed element and zero.
2890b57cec5SDimitry Andric  def VLLEBRZ  : UnaryVRXGeneric<"vllebrz", 0xE604>;
2900b57cec5SDimitry Andric  def VLLEBRZH : UnaryVRX<"vllebrzh", 0xE604, z_vllebrzi16, v128h, 2, 1>;
2910b57cec5SDimitry Andric  def VLLEBRZF : UnaryVRX<"vllebrzf", 0xE604, z_vllebrzi32, v128f, 4, 2>;
2920b57cec5SDimitry Andric  def VLLEBRZG : UnaryVRX<"vllebrzg", 0xE604, z_vllebrzi64, v128g, 8, 3>;
2930b57cec5SDimitry Andric  def VLLEBRZE : UnaryVRX<"vllebrze", 0xE604, z_vllebrzli32, v128f, 4, 6>;
2940b57cec5SDimitry Andric  def : InstAlias<"lerv\t$V1, $XBD2",
2950b57cec5SDimitry Andric                  (VLLEBRZE VR128:$V1, bdxaddr12only:$XBD2), 0>;
2960b57cec5SDimitry Andric  def : InstAlias<"ldrv\t$V1, $XBD2",
2970b57cec5SDimitry Andric                  (VLLEBRZG VR128:$V1, bdxaddr12only:$XBD2), 0>;
2980b57cec5SDimitry Andric
2990b57cec5SDimitry Andric  // Load byte-reversed element and replicate.
3000b57cec5SDimitry Andric  def VLBRREP  : UnaryVRXGeneric<"vlbrrep", 0xE605>;
3010b57cec5SDimitry Andric  def VLBRREPH : UnaryVRX<"vlbrreph", 0xE605, z_replicate_loadbswapi16, v128h, 2, 1>;
3020b57cec5SDimitry Andric  def VLBRREPF : UnaryVRX<"vlbrrepf", 0xE605, z_replicate_loadbswapi32, v128f, 4, 2>;
3030b57cec5SDimitry Andric  def VLBRREPG : UnaryVRX<"vlbrrepg", 0xE605, z_replicate_loadbswapi64, v128g, 8, 3>;
3040b57cec5SDimitry Andric
3050b57cec5SDimitry Andric  // Store byte-reversed elements.
3060b57cec5SDimitry Andric  def VSTBR  : StoreVRXGeneric<"vstbr", 0xE60E>;
3070b57cec5SDimitry Andric  def VSTBRH : StoreVRX<"vstbrh", 0xE60E, z_storebswap, v128h, 16, 1>;
3080b57cec5SDimitry Andric  def VSTBRF : StoreVRX<"vstbrf", 0xE60E, z_storebswap, v128f, 16, 2>;
3090b57cec5SDimitry Andric  def VSTBRG : StoreVRX<"vstbrg", 0xE60E, z_storebswap, v128g, 16, 3>;
3105f757f3fSDimitry Andric  def VSTBRQ : StoreVRX<"vstbrq", 0xE60E, z_storebswap, v128q, 16, 4>;
3110b57cec5SDimitry Andric
3120b57cec5SDimitry Andric  // Store elements reversed.
3130b57cec5SDimitry Andric  def VSTER  : StoreVRXGeneric<"vster", 0xE60F>;
3140b57cec5SDimitry Andric  def VSTERH : StoreVRX<"vsterh", 0xE60F, z_storeeswap, v128h, 16, 1>;
3150b57cec5SDimitry Andric  def VSTERF : StoreVRX<"vsterf", 0xE60F, z_storeeswap, v128f, 16, 2>;
3160b57cec5SDimitry Andric  def VSTERG : StoreVRX<"vsterg", 0xE60F, z_storeeswap, v128g, 16, 3>;
3170b57cec5SDimitry Andric  def : Pat<(z_storeeswap (v4f32 VR128:$val), bdxaddr12only:$addr),
3180b57cec5SDimitry Andric            (VSTERF VR128:$val, bdxaddr12only:$addr)>;
3190b57cec5SDimitry Andric  def : Pat<(z_storeeswap (v2f64 VR128:$val), bdxaddr12only:$addr),
3200b57cec5SDimitry Andric            (VSTERG VR128:$val, bdxaddr12only:$addr)>;
3210b57cec5SDimitry Andric  def : Pat<(z_storeeswap (v16i8 VR128:$val), bdxaddr12only:$addr),
3220b57cec5SDimitry Andric            (VSTBRQ VR128:$val, bdxaddr12only:$addr)>;
3230b57cec5SDimitry Andric
3240b57cec5SDimitry Andric  // Store byte-reversed element.
3250b57cec5SDimitry Andric  def VSTEBRH : StoreBinaryVRX<"vstebrh", 0xE609, z_vstebri16, v128h, 2, imm32zx3>;
3260b57cec5SDimitry Andric  def VSTEBRF : StoreBinaryVRX<"vstebrf", 0xE60B, z_vstebri32, v128f, 4, imm32zx2>;
3270b57cec5SDimitry Andric  def VSTEBRG : StoreBinaryVRX<"vstebrg", 0xE60A, z_vstebri64, v128g, 8, imm32zx1>;
3280b57cec5SDimitry Andric  def : InstAlias<"sterv\t$V1, $XBD2",
3290b57cec5SDimitry Andric                  (VSTEBRF VR128:$V1, bdxaddr12only:$XBD2, 0), 0>;
3300b57cec5SDimitry Andric  def : InstAlias<"stdrv\t$V1, $XBD2",
3310b57cec5SDimitry Andric                  (VSTEBRG VR128:$V1, bdxaddr12only:$XBD2, 0), 0>;
3320b57cec5SDimitry Andric}
3330b57cec5SDimitry Andric
3340b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
3350b57cec5SDimitry Andric// Selects and permutes
3360b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
3370b57cec5SDimitry Andric
3380b57cec5SDimitry Andriclet Predicates = [FeatureVector] in {
3390b57cec5SDimitry Andric  // Merge high.
3400b57cec5SDimitry Andric  def VMRH:   BinaryVRRcGeneric<"vmrh", 0xE761>;
3410b57cec5SDimitry Andric  def VMRHB : BinaryVRRc<"vmrhb", 0xE761, z_merge_high, v128b, v128b, 0>;
3420b57cec5SDimitry Andric  def VMRHH : BinaryVRRc<"vmrhh", 0xE761, z_merge_high, v128h, v128h, 1>;
3430b57cec5SDimitry Andric  def VMRHF : BinaryVRRc<"vmrhf", 0xE761, z_merge_high, v128f, v128f, 2>;
3440b57cec5SDimitry Andric  def VMRHG : BinaryVRRc<"vmrhg", 0xE761, z_merge_high, v128g, v128g, 3>;
3450b57cec5SDimitry Andric  def : BinaryRRWithType<VMRHF, VR128, z_merge_high, v4f32>;
3460b57cec5SDimitry Andric  def : BinaryRRWithType<VMRHG, VR128, z_merge_high, v2f64>;
3470b57cec5SDimitry Andric
3480b57cec5SDimitry Andric  // Merge low.
3490b57cec5SDimitry Andric  def VMRL:   BinaryVRRcGeneric<"vmrl", 0xE760>;
3500b57cec5SDimitry Andric  def VMRLB : BinaryVRRc<"vmrlb", 0xE760, z_merge_low, v128b, v128b, 0>;
3510b57cec5SDimitry Andric  def VMRLH : BinaryVRRc<"vmrlh", 0xE760, z_merge_low, v128h, v128h, 1>;
3520b57cec5SDimitry Andric  def VMRLF : BinaryVRRc<"vmrlf", 0xE760, z_merge_low, v128f, v128f, 2>;
3530b57cec5SDimitry Andric  def VMRLG : BinaryVRRc<"vmrlg", 0xE760, z_merge_low, v128g, v128g, 3>;
3540b57cec5SDimitry Andric  def : BinaryRRWithType<VMRLF, VR128, z_merge_low, v4f32>;
3550b57cec5SDimitry Andric  def : BinaryRRWithType<VMRLG, VR128, z_merge_low, v2f64>;
3560b57cec5SDimitry Andric
3570b57cec5SDimitry Andric  // Permute.
3580b57cec5SDimitry Andric  def VPERM : TernaryVRRe<"vperm", 0xE78C, z_permute, v128b, v128b>;
3590b57cec5SDimitry Andric
3600b57cec5SDimitry Andric  // Permute doubleword immediate.
3610b57cec5SDimitry Andric  def VPDI : TernaryVRRc<"vpdi", 0xE784, z_permute_dwords, v128g, v128g>;
3620b57cec5SDimitry Andric
3630b57cec5SDimitry Andric  // Bit Permute.
3640b57cec5SDimitry Andric  let Predicates = [FeatureVectorEnhancements1] in
3650b57cec5SDimitry Andric    def VBPERM : BinaryVRRc<"vbperm", 0xE785, int_s390_vbperm, v128g, v128b>;
3660b57cec5SDimitry Andric
3670b57cec5SDimitry Andric  // Replicate.
3680b57cec5SDimitry Andric  def VREP:   BinaryVRIcGeneric<"vrep", 0xE74D>;
3690b57cec5SDimitry Andric  def VREPB : BinaryVRIc<"vrepb", 0xE74D, z_splat, v128b, v128b, 0>;
3700b57cec5SDimitry Andric  def VREPH : BinaryVRIc<"vreph", 0xE74D, z_splat, v128h, v128h, 1>;
3710b57cec5SDimitry Andric  def VREPF : BinaryVRIc<"vrepf", 0xE74D, z_splat, v128f, v128f, 2>;
3720b57cec5SDimitry Andric  def VREPG : BinaryVRIc<"vrepg", 0xE74D, z_splat, v128g, v128g, 3>;
3738bcb0991SDimitry Andric  def : Pat<(v4f32 (z_splat VR128:$vec, imm32zx16_timm:$index)),
3740b57cec5SDimitry Andric            (VREPF VR128:$vec, imm32zx16:$index)>;
3758bcb0991SDimitry Andric  def : Pat<(v2f64 (z_splat VR128:$vec, imm32zx16_timm:$index)),
3760b57cec5SDimitry Andric            (VREPG VR128:$vec, imm32zx16:$index)>;
3770b57cec5SDimitry Andric
3780b57cec5SDimitry Andric  // Select.
3790b57cec5SDimitry Andric  def VSEL : TernaryVRRe<"vsel", 0xE78D, null_frag, v128any, v128any>;
3800b57cec5SDimitry Andric}
3810b57cec5SDimitry Andric
3820b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
3830b57cec5SDimitry Andric// Widening and narrowing
3840b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
3850b57cec5SDimitry Andric
3860b57cec5SDimitry Andriclet Predicates = [FeatureVector] in {
3870b57cec5SDimitry Andric  // Pack
3880b57cec5SDimitry Andric  def VPK  : BinaryVRRcGeneric<"vpk", 0xE794>;
3890b57cec5SDimitry Andric  def VPKH : BinaryVRRc<"vpkh", 0xE794, z_pack, v128b, v128h, 1>;
3900b57cec5SDimitry Andric  def VPKF : BinaryVRRc<"vpkf", 0xE794, z_pack, v128h, v128f, 2>;
3910b57cec5SDimitry Andric  def VPKG : BinaryVRRc<"vpkg", 0xE794, z_pack, v128f, v128g, 3>;
3920b57cec5SDimitry Andric
3930b57cec5SDimitry Andric  // Pack saturate.
3940b57cec5SDimitry Andric  def  VPKS  : BinaryVRRbSPairGeneric<"vpks", 0xE797>;
3950b57cec5SDimitry Andric  defm VPKSH : BinaryVRRbSPair<"vpksh", 0xE797, int_s390_vpksh, z_packs_cc,
3960b57cec5SDimitry Andric                               v128b, v128h, 1>;
3970b57cec5SDimitry Andric  defm VPKSF : BinaryVRRbSPair<"vpksf", 0xE797, int_s390_vpksf, z_packs_cc,
3980b57cec5SDimitry Andric                               v128h, v128f, 2>;
3990b57cec5SDimitry Andric  defm VPKSG : BinaryVRRbSPair<"vpksg", 0xE797, int_s390_vpksg, z_packs_cc,
4000b57cec5SDimitry Andric                               v128f, v128g, 3>;
4010b57cec5SDimitry Andric
4020b57cec5SDimitry Andric  // Pack saturate logical.
4030b57cec5SDimitry Andric  def  VPKLS  : BinaryVRRbSPairGeneric<"vpkls", 0xE795>;
4040b57cec5SDimitry Andric  defm VPKLSH : BinaryVRRbSPair<"vpklsh", 0xE795, int_s390_vpklsh, z_packls_cc,
4050b57cec5SDimitry Andric                                v128b, v128h, 1>;
4060b57cec5SDimitry Andric  defm VPKLSF : BinaryVRRbSPair<"vpklsf", 0xE795, int_s390_vpklsf, z_packls_cc,
4070b57cec5SDimitry Andric                                v128h, v128f, 2>;
4080b57cec5SDimitry Andric  defm VPKLSG : BinaryVRRbSPair<"vpklsg", 0xE795, int_s390_vpklsg, z_packls_cc,
4090b57cec5SDimitry Andric                                v128f, v128g, 3>;
4100b57cec5SDimitry Andric
4110b57cec5SDimitry Andric  // Sign-extend to doubleword.
4120b57cec5SDimitry Andric  def VSEG  : UnaryVRRaGeneric<"vseg", 0xE75F>;
4130b57cec5SDimitry Andric  def VSEGB : UnaryVRRa<"vsegb", 0xE75F, z_vsei8,  v128g, v128g, 0>;
4140b57cec5SDimitry Andric  def VSEGH : UnaryVRRa<"vsegh", 0xE75F, z_vsei16, v128g, v128g, 1>;
4150b57cec5SDimitry Andric  def VSEGF : UnaryVRRa<"vsegf", 0xE75F, z_vsei32, v128g, v128g, 2>;
4160b57cec5SDimitry Andric  def : Pat<(z_vsei8_by_parts  (v16i8 VR128:$src)), (VSEGB VR128:$src)>;
4170b57cec5SDimitry Andric  def : Pat<(z_vsei16_by_parts (v8i16 VR128:$src)), (VSEGH VR128:$src)>;
4180b57cec5SDimitry Andric  def : Pat<(z_vsei32_by_parts (v4i32 VR128:$src)), (VSEGF VR128:$src)>;
4190b57cec5SDimitry Andric
4200b57cec5SDimitry Andric  // Unpack high.
4210b57cec5SDimitry Andric  def VUPH  : UnaryVRRaGeneric<"vuph", 0xE7D7>;
4220b57cec5SDimitry Andric  def VUPHB : UnaryVRRa<"vuphb", 0xE7D7, z_unpack_high, v128h, v128b, 0>;
4230b57cec5SDimitry Andric  def VUPHH : UnaryVRRa<"vuphh", 0xE7D7, z_unpack_high, v128f, v128h, 1>;
4240b57cec5SDimitry Andric  def VUPHF : UnaryVRRa<"vuphf", 0xE7D7, z_unpack_high, v128g, v128f, 2>;
4250b57cec5SDimitry Andric
4260b57cec5SDimitry Andric  // Unpack logical high.
4270b57cec5SDimitry Andric  def VUPLH  : UnaryVRRaGeneric<"vuplh", 0xE7D5>;
4280b57cec5SDimitry Andric  def VUPLHB : UnaryVRRa<"vuplhb", 0xE7D5, z_unpackl_high, v128h, v128b, 0>;
4290b57cec5SDimitry Andric  def VUPLHH : UnaryVRRa<"vuplhh", 0xE7D5, z_unpackl_high, v128f, v128h, 1>;
4300b57cec5SDimitry Andric  def VUPLHF : UnaryVRRa<"vuplhf", 0xE7D5, z_unpackl_high, v128g, v128f, 2>;
4310b57cec5SDimitry Andric
4320b57cec5SDimitry Andric  // Unpack low.
4330b57cec5SDimitry Andric  def VUPL   : UnaryVRRaGeneric<"vupl", 0xE7D6>;
4340b57cec5SDimitry Andric  def VUPLB  : UnaryVRRa<"vuplb",  0xE7D6, z_unpack_low, v128h, v128b, 0>;
4350b57cec5SDimitry Andric  def VUPLHW : UnaryVRRa<"vuplhw", 0xE7D6, z_unpack_low, v128f, v128h, 1>;
4360b57cec5SDimitry Andric  def VUPLF  : UnaryVRRa<"vuplf",  0xE7D6, z_unpack_low, v128g, v128f, 2>;
4370b57cec5SDimitry Andric
4380b57cec5SDimitry Andric  // Unpack logical low.
4390b57cec5SDimitry Andric  def VUPLL  : UnaryVRRaGeneric<"vupll", 0xE7D4>;
4400b57cec5SDimitry Andric  def VUPLLB : UnaryVRRa<"vupllb", 0xE7D4, z_unpackl_low, v128h, v128b, 0>;
4410b57cec5SDimitry Andric  def VUPLLH : UnaryVRRa<"vupllh", 0xE7D4, z_unpackl_low, v128f, v128h, 1>;
4420b57cec5SDimitry Andric  def VUPLLF : UnaryVRRa<"vupllf", 0xE7D4, z_unpackl_low, v128g, v128f, 2>;
4430b57cec5SDimitry Andric}
4440b57cec5SDimitry Andric
4450b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
4460b57cec5SDimitry Andric// Instantiating generic operations for specific types.
4470b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
4480b57cec5SDimitry Andric
4490b57cec5SDimitry Andricmulticlass GenericVectorOps<ValueType type, ValueType inttype> {
4500b57cec5SDimitry Andric  let Predicates = [FeatureVector] in {
4510b57cec5SDimitry Andric    def : Pat<(type (load bdxaddr12only:$addr)),
4520b57cec5SDimitry Andric              (VL bdxaddr12only:$addr)>;
4530b57cec5SDimitry Andric    def : Pat<(store (type VR128:$src), bdxaddr12only:$addr),
4540b57cec5SDimitry Andric              (VST VR128:$src, bdxaddr12only:$addr)>;
4550b57cec5SDimitry Andric    def : Pat<(type (vselect (inttype VR128:$x), VR128:$y, VR128:$z)),
4560b57cec5SDimitry Andric              (VSEL VR128:$y, VR128:$z, VR128:$x)>;
4570b57cec5SDimitry Andric    def : Pat<(type (vselect (inttype (z_vnot VR128:$x)), VR128:$y, VR128:$z)),
4580b57cec5SDimitry Andric              (VSEL VR128:$z, VR128:$y, VR128:$x)>;
4590b57cec5SDimitry Andric  }
4600b57cec5SDimitry Andric}
4610b57cec5SDimitry Andric
4620b57cec5SDimitry Andricdefm : GenericVectorOps<v16i8, v16i8>;
4630b57cec5SDimitry Andricdefm : GenericVectorOps<v8i16, v8i16>;
4640b57cec5SDimitry Andricdefm : GenericVectorOps<v4i32, v4i32>;
4650b57cec5SDimitry Andricdefm : GenericVectorOps<v2i64, v2i64>;
4660b57cec5SDimitry Andricdefm : GenericVectorOps<v4f32, v4i32>;
4670b57cec5SDimitry Andricdefm : GenericVectorOps<v2f64, v2i64>;
4680b57cec5SDimitry Andric
4690b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
4700b57cec5SDimitry Andric// Integer arithmetic
4710b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
4720b57cec5SDimitry Andric
4730b57cec5SDimitry Andriclet Predicates = [FeatureVector] in {
4745ffd83dbSDimitry Andric  let isCommutable = 1 in {
4750b57cec5SDimitry Andric    // Add.
4760b57cec5SDimitry Andric    def VA  : BinaryVRRcGeneric<"va", 0xE7F3>;
4770b57cec5SDimitry Andric    def VAB : BinaryVRRc<"vab", 0xE7F3, add, v128b, v128b, 0>;
4780b57cec5SDimitry Andric    def VAH : BinaryVRRc<"vah", 0xE7F3, add, v128h, v128h, 1>;
4790b57cec5SDimitry Andric    def VAF : BinaryVRRc<"vaf", 0xE7F3, add, v128f, v128f, 2>;
4800b57cec5SDimitry Andric    def VAG : BinaryVRRc<"vag", 0xE7F3, add, v128g, v128g, 3>;
4815f757f3fSDimitry Andric    def VAQ : BinaryVRRc<"vaq", 0xE7F3, add, v128q, v128q, 4>;
4825ffd83dbSDimitry Andric  }
4830b57cec5SDimitry Andric
4845ffd83dbSDimitry Andric  let isCommutable = 1 in {
4850b57cec5SDimitry Andric    // Add compute carry.
4860b57cec5SDimitry Andric    def VACC  : BinaryVRRcGeneric<"vacc", 0xE7F1>;
4875f757f3fSDimitry Andric    def VACCB : BinaryVRRc<"vaccb", 0xE7F1, z_vacc, v128b, v128b, 0>;
4885f757f3fSDimitry Andric    def VACCH : BinaryVRRc<"vacch", 0xE7F1, z_vacc, v128h, v128h, 1>;
4895f757f3fSDimitry Andric    def VACCF : BinaryVRRc<"vaccf", 0xE7F1, z_vacc, v128f, v128f, 2>;
4905f757f3fSDimitry Andric    def VACCG : BinaryVRRc<"vaccg", 0xE7F1, z_vacc, v128g, v128g, 3>;
4915f757f3fSDimitry Andric    def VACCQ : BinaryVRRc<"vaccq", 0xE7F1, z_vacc, v128q, v128q, 4>;
4920b57cec5SDimitry Andric
4930b57cec5SDimitry Andric    // Add with carry.
4940b57cec5SDimitry Andric    def VAC  : TernaryVRRdGeneric<"vac", 0xE7BB>;
4955f757f3fSDimitry Andric    def VACQ : TernaryVRRd<"vacq", 0xE7BB, z_vac, v128q, v128q, 4>;
4960b57cec5SDimitry Andric
4970b57cec5SDimitry Andric    // Add with carry compute carry.
4980b57cec5SDimitry Andric    def VACCC  : TernaryVRRdGeneric<"vaccc", 0xE7B9>;
4995f757f3fSDimitry Andric    def VACCCQ : TernaryVRRd<"vacccq", 0xE7B9, z_vaccc, v128q, v128q, 4>;
5005ffd83dbSDimitry Andric  }
5010b57cec5SDimitry Andric
5020b57cec5SDimitry Andric  // And.
5035ffd83dbSDimitry Andric  let isCommutable = 1 in
5040b57cec5SDimitry Andric    def VN : BinaryVRRc<"vn", 0xE768, null_frag, v128any, v128any>;
5050b57cec5SDimitry Andric
5060b57cec5SDimitry Andric  // And with complement.
5070b57cec5SDimitry Andric  def VNC : BinaryVRRc<"vnc", 0xE769, null_frag, v128any, v128any>;
5080b57cec5SDimitry Andric
5095ffd83dbSDimitry Andric  let isCommutable = 1 in {
5100b57cec5SDimitry Andric    // Average.
5110b57cec5SDimitry Andric    def VAVG  : BinaryVRRcGeneric<"vavg", 0xE7F2>;
5120b57cec5SDimitry Andric    def VAVGB : BinaryVRRc<"vavgb", 0xE7F2, int_s390_vavgb, v128b, v128b, 0>;
5130b57cec5SDimitry Andric    def VAVGH : BinaryVRRc<"vavgh", 0xE7F2, int_s390_vavgh, v128h, v128h, 1>;
5140b57cec5SDimitry Andric    def VAVGF : BinaryVRRc<"vavgf", 0xE7F2, int_s390_vavgf, v128f, v128f, 2>;
5150b57cec5SDimitry Andric    def VAVGG : BinaryVRRc<"vavgg", 0xE7F2, int_s390_vavgg, v128g, v128g, 3>;
5160b57cec5SDimitry Andric
5170b57cec5SDimitry Andric    // Average logical.
5180b57cec5SDimitry Andric    def VAVGL  : BinaryVRRcGeneric<"vavgl", 0xE7F0>;
5190b57cec5SDimitry Andric    def VAVGLB : BinaryVRRc<"vavglb", 0xE7F0, int_s390_vavglb, v128b, v128b, 0>;
5200b57cec5SDimitry Andric    def VAVGLH : BinaryVRRc<"vavglh", 0xE7F0, int_s390_vavglh, v128h, v128h, 1>;
5210b57cec5SDimitry Andric    def VAVGLF : BinaryVRRc<"vavglf", 0xE7F0, int_s390_vavglf, v128f, v128f, 2>;
5220b57cec5SDimitry Andric    def VAVGLG : BinaryVRRc<"vavglg", 0xE7F0, int_s390_vavglg, v128g, v128g, 3>;
5235ffd83dbSDimitry Andric  }
5240b57cec5SDimitry Andric
5250b57cec5SDimitry Andric  // Checksum.
5260b57cec5SDimitry Andric  def VCKSM : BinaryVRRc<"vcksm", 0xE766, int_s390_vcksm, v128f, v128f>;
5270b57cec5SDimitry Andric
5280b57cec5SDimitry Andric  // Count leading zeros.
5290b57cec5SDimitry Andric  def VCLZ  : UnaryVRRaGeneric<"vclz", 0xE753>;
5300b57cec5SDimitry Andric  def VCLZB : UnaryVRRa<"vclzb", 0xE753, ctlz, v128b, v128b, 0>;
5310b57cec5SDimitry Andric  def VCLZH : UnaryVRRa<"vclzh", 0xE753, ctlz, v128h, v128h, 1>;
5320b57cec5SDimitry Andric  def VCLZF : UnaryVRRa<"vclzf", 0xE753, ctlz, v128f, v128f, 2>;
5330b57cec5SDimitry Andric  def VCLZG : UnaryVRRa<"vclzg", 0xE753, ctlz, v128g, v128g, 3>;
5340b57cec5SDimitry Andric
5350b57cec5SDimitry Andric  // Count trailing zeros.
5360b57cec5SDimitry Andric  def VCTZ  : UnaryVRRaGeneric<"vctz", 0xE752>;
5370b57cec5SDimitry Andric  def VCTZB : UnaryVRRa<"vctzb", 0xE752, cttz, v128b, v128b, 0>;
5380b57cec5SDimitry Andric  def VCTZH : UnaryVRRa<"vctzh", 0xE752, cttz, v128h, v128h, 1>;
5390b57cec5SDimitry Andric  def VCTZF : UnaryVRRa<"vctzf", 0xE752, cttz, v128f, v128f, 2>;
5400b57cec5SDimitry Andric  def VCTZG : UnaryVRRa<"vctzg", 0xE752, cttz, v128g, v128g, 3>;
5410b57cec5SDimitry Andric
5425ffd83dbSDimitry Andric  let isCommutable = 1 in {
5430b57cec5SDimitry Andric    // Not exclusive or.
5440b57cec5SDimitry Andric    let Predicates = [FeatureVectorEnhancements1] in
5450b57cec5SDimitry Andric      def VNX : BinaryVRRc<"vnx", 0xE76C, null_frag, v128any, v128any>;
5460b57cec5SDimitry Andric
5470b57cec5SDimitry Andric    // Exclusive or.
5480b57cec5SDimitry Andric    def VX : BinaryVRRc<"vx", 0xE76D, null_frag, v128any, v128any>;
5495ffd83dbSDimitry Andric  }
5500b57cec5SDimitry Andric
5510b57cec5SDimitry Andric  // Galois field multiply sum.
5520b57cec5SDimitry Andric  def VGFM  : BinaryVRRcGeneric<"vgfm", 0xE7B4>;
5530b57cec5SDimitry Andric  def VGFMB : BinaryVRRc<"vgfmb", 0xE7B4, int_s390_vgfmb, v128h, v128b, 0>;
5540b57cec5SDimitry Andric  def VGFMH : BinaryVRRc<"vgfmh", 0xE7B4, int_s390_vgfmh, v128f, v128h, 1>;
5550b57cec5SDimitry Andric  def VGFMF : BinaryVRRc<"vgfmf", 0xE7B4, int_s390_vgfmf, v128g, v128f, 2>;
5560b57cec5SDimitry Andric  def VGFMG : BinaryVRRc<"vgfmg", 0xE7B4, int_s390_vgfmg, v128q, v128g, 3>;
5570b57cec5SDimitry Andric
5580b57cec5SDimitry Andric  // Galois field multiply sum and accumulate.
5590b57cec5SDimitry Andric  def VGFMA  : TernaryVRRdGeneric<"vgfma", 0xE7BC>;
5600b57cec5SDimitry Andric  def VGFMAB : TernaryVRRd<"vgfmab", 0xE7BC, int_s390_vgfmab, v128h, v128b, 0>;
5610b57cec5SDimitry Andric  def VGFMAH : TernaryVRRd<"vgfmah", 0xE7BC, int_s390_vgfmah, v128f, v128h, 1>;
5620b57cec5SDimitry Andric  def VGFMAF : TernaryVRRd<"vgfmaf", 0xE7BC, int_s390_vgfmaf, v128g, v128f, 2>;
5630b57cec5SDimitry Andric  def VGFMAG : TernaryVRRd<"vgfmag", 0xE7BC, int_s390_vgfmag, v128q, v128g, 3>;
5640b57cec5SDimitry Andric
5650b57cec5SDimitry Andric  // Load complement.
5660b57cec5SDimitry Andric  def VLC  : UnaryVRRaGeneric<"vlc", 0xE7DE>;
5670b57cec5SDimitry Andric  def VLCB : UnaryVRRa<"vlcb", 0xE7DE, z_vneg, v128b, v128b, 0>;
5680b57cec5SDimitry Andric  def VLCH : UnaryVRRa<"vlch", 0xE7DE, z_vneg, v128h, v128h, 1>;
5690b57cec5SDimitry Andric  def VLCF : UnaryVRRa<"vlcf", 0xE7DE, z_vneg, v128f, v128f, 2>;
5700b57cec5SDimitry Andric  def VLCG : UnaryVRRa<"vlcg", 0xE7DE, z_vneg, v128g, v128g, 3>;
5710b57cec5SDimitry Andric
5720b57cec5SDimitry Andric  // Load positive.
5730b57cec5SDimitry Andric  def VLP  : UnaryVRRaGeneric<"vlp", 0xE7DF>;
574e8d8bef9SDimitry Andric  def VLPB : UnaryVRRa<"vlpb", 0xE7DF, abs, v128b, v128b, 0>;
575e8d8bef9SDimitry Andric  def VLPH : UnaryVRRa<"vlph", 0xE7DF, abs, v128h, v128h, 1>;
576e8d8bef9SDimitry Andric  def VLPF : UnaryVRRa<"vlpf", 0xE7DF, abs, v128f, v128f, 2>;
577e8d8bef9SDimitry Andric  def VLPG : UnaryVRRa<"vlpg", 0xE7DF, abs, v128g, v128g, 3>;
5780b57cec5SDimitry Andric
5795ffd83dbSDimitry Andric  let isCommutable = 1 in {
5800b57cec5SDimitry Andric    // Maximum.
5810b57cec5SDimitry Andric    def VMX  : BinaryVRRcGeneric<"vmx", 0xE7FF>;
5820b57cec5SDimitry Andric    def VMXB : BinaryVRRc<"vmxb", 0xE7FF, null_frag, v128b, v128b, 0>;
5830b57cec5SDimitry Andric    def VMXH : BinaryVRRc<"vmxh", 0xE7FF, null_frag, v128h, v128h, 1>;
5840b57cec5SDimitry Andric    def VMXF : BinaryVRRc<"vmxf", 0xE7FF, null_frag, v128f, v128f, 2>;
5850b57cec5SDimitry Andric    def VMXG : BinaryVRRc<"vmxg", 0xE7FF, null_frag, v128g, v128g, 3>;
5860b57cec5SDimitry Andric
5870b57cec5SDimitry Andric    // Maximum logical.
5880b57cec5SDimitry Andric    def VMXL  : BinaryVRRcGeneric<"vmxl", 0xE7FD>;
5890b57cec5SDimitry Andric    def VMXLB : BinaryVRRc<"vmxlb", 0xE7FD, null_frag, v128b, v128b, 0>;
5900b57cec5SDimitry Andric    def VMXLH : BinaryVRRc<"vmxlh", 0xE7FD, null_frag, v128h, v128h, 1>;
5910b57cec5SDimitry Andric    def VMXLF : BinaryVRRc<"vmxlf", 0xE7FD, null_frag, v128f, v128f, 2>;
5920b57cec5SDimitry Andric    def VMXLG : BinaryVRRc<"vmxlg", 0xE7FD, null_frag, v128g, v128g, 3>;
5935ffd83dbSDimitry Andric  }
5940b57cec5SDimitry Andric
5955ffd83dbSDimitry Andric  let isCommutable = 1 in {
5960b57cec5SDimitry Andric    // Minimum.
5970b57cec5SDimitry Andric    def VMN  : BinaryVRRcGeneric<"vmn", 0xE7FE>;
5980b57cec5SDimitry Andric    def VMNB : BinaryVRRc<"vmnb", 0xE7FE, null_frag, v128b, v128b, 0>;
5990b57cec5SDimitry Andric    def VMNH : BinaryVRRc<"vmnh", 0xE7FE, null_frag, v128h, v128h, 1>;
6000b57cec5SDimitry Andric    def VMNF : BinaryVRRc<"vmnf", 0xE7FE, null_frag, v128f, v128f, 2>;
6010b57cec5SDimitry Andric    def VMNG : BinaryVRRc<"vmng", 0xE7FE, null_frag, v128g, v128g, 3>;
6020b57cec5SDimitry Andric
6030b57cec5SDimitry Andric    // Minimum logical.
6040b57cec5SDimitry Andric    def VMNL  : BinaryVRRcGeneric<"vmnl", 0xE7FC>;
6050b57cec5SDimitry Andric    def VMNLB : BinaryVRRc<"vmnlb", 0xE7FC, null_frag, v128b, v128b, 0>;
6060b57cec5SDimitry Andric    def VMNLH : BinaryVRRc<"vmnlh", 0xE7FC, null_frag, v128h, v128h, 1>;
6070b57cec5SDimitry Andric    def VMNLF : BinaryVRRc<"vmnlf", 0xE7FC, null_frag, v128f, v128f, 2>;
6080b57cec5SDimitry Andric    def VMNLG : BinaryVRRc<"vmnlg", 0xE7FC, null_frag, v128g, v128g, 3>;
6095ffd83dbSDimitry Andric  }
6100b57cec5SDimitry Andric
6115ffd83dbSDimitry Andric  let isCommutable = 1 in {
6120b57cec5SDimitry Andric    // Multiply and add low.
6130b57cec5SDimitry Andric    def VMAL   : TernaryVRRdGeneric<"vmal", 0xE7AA>;
6140b57cec5SDimitry Andric    def VMALB  : TernaryVRRd<"vmalb",  0xE7AA, z_muladd, v128b, v128b, 0>;
6150b57cec5SDimitry Andric    def VMALHW : TernaryVRRd<"vmalhw", 0xE7AA, z_muladd, v128h, v128h, 1>;
6160b57cec5SDimitry Andric    def VMALF  : TernaryVRRd<"vmalf",  0xE7AA, z_muladd, v128f, v128f, 2>;
6170b57cec5SDimitry Andric
6180b57cec5SDimitry Andric    // Multiply and add high.
6190b57cec5SDimitry Andric    def VMAH  : TernaryVRRdGeneric<"vmah", 0xE7AB>;
6200b57cec5SDimitry Andric    def VMAHB : TernaryVRRd<"vmahb", 0xE7AB, int_s390_vmahb, v128b, v128b, 0>;
6210b57cec5SDimitry Andric    def VMAHH : TernaryVRRd<"vmahh", 0xE7AB, int_s390_vmahh, v128h, v128h, 1>;
6220b57cec5SDimitry Andric    def VMAHF : TernaryVRRd<"vmahf", 0xE7AB, int_s390_vmahf, v128f, v128f, 2>;
6230b57cec5SDimitry Andric
6240b57cec5SDimitry Andric    // Multiply and add logical high.
6250b57cec5SDimitry Andric    def VMALH  : TernaryVRRdGeneric<"vmalh", 0xE7A9>;
6260b57cec5SDimitry Andric    def VMALHB : TernaryVRRd<"vmalhb", 0xE7A9, int_s390_vmalhb, v128b, v128b, 0>;
6270b57cec5SDimitry Andric    def VMALHH : TernaryVRRd<"vmalhh", 0xE7A9, int_s390_vmalhh, v128h, v128h, 1>;
6280b57cec5SDimitry Andric    def VMALHF : TernaryVRRd<"vmalhf", 0xE7A9, int_s390_vmalhf, v128f, v128f, 2>;
6290b57cec5SDimitry Andric
6300b57cec5SDimitry Andric    // Multiply and add even.
6310b57cec5SDimitry Andric    def VMAE  : TernaryVRRdGeneric<"vmae", 0xE7AE>;
6320b57cec5SDimitry Andric    def VMAEB : TernaryVRRd<"vmaeb", 0xE7AE, int_s390_vmaeb, v128h, v128b, 0>;
6330b57cec5SDimitry Andric    def VMAEH : TernaryVRRd<"vmaeh", 0xE7AE, int_s390_vmaeh, v128f, v128h, 1>;
6340b57cec5SDimitry Andric    def VMAEF : TernaryVRRd<"vmaef", 0xE7AE, int_s390_vmaef, v128g, v128f, 2>;
6350b57cec5SDimitry Andric
6360b57cec5SDimitry Andric    // Multiply and add logical even.
6370b57cec5SDimitry Andric    def VMALE  : TernaryVRRdGeneric<"vmale", 0xE7AC>;
6380b57cec5SDimitry Andric    def VMALEB : TernaryVRRd<"vmaleb", 0xE7AC, int_s390_vmaleb, v128h, v128b, 0>;
6390b57cec5SDimitry Andric    def VMALEH : TernaryVRRd<"vmaleh", 0xE7AC, int_s390_vmaleh, v128f, v128h, 1>;
6400b57cec5SDimitry Andric    def VMALEF : TernaryVRRd<"vmalef", 0xE7AC, int_s390_vmalef, v128g, v128f, 2>;
6410b57cec5SDimitry Andric
6420b57cec5SDimitry Andric    // Multiply and add odd.
6430b57cec5SDimitry Andric    def VMAO  : TernaryVRRdGeneric<"vmao", 0xE7AF>;
6440b57cec5SDimitry Andric    def VMAOB : TernaryVRRd<"vmaob", 0xE7AF, int_s390_vmaob, v128h, v128b, 0>;
6450b57cec5SDimitry Andric    def VMAOH : TernaryVRRd<"vmaoh", 0xE7AF, int_s390_vmaoh, v128f, v128h, 1>;
6460b57cec5SDimitry Andric    def VMAOF : TernaryVRRd<"vmaof", 0xE7AF, int_s390_vmaof, v128g, v128f, 2>;
6470b57cec5SDimitry Andric
6480b57cec5SDimitry Andric    // Multiply and add logical odd.
6490b57cec5SDimitry Andric    def VMALO  : TernaryVRRdGeneric<"vmalo", 0xE7AD>;
6500b57cec5SDimitry Andric    def VMALOB : TernaryVRRd<"vmalob", 0xE7AD, int_s390_vmalob, v128h, v128b, 0>;
6510b57cec5SDimitry Andric    def VMALOH : TernaryVRRd<"vmaloh", 0xE7AD, int_s390_vmaloh, v128f, v128h, 1>;
6520b57cec5SDimitry Andric    def VMALOF : TernaryVRRd<"vmalof", 0xE7AD, int_s390_vmalof, v128g, v128f, 2>;
6535ffd83dbSDimitry Andric  }
6540b57cec5SDimitry Andric
6555ffd83dbSDimitry Andric  let isCommutable = 1 in {
6560b57cec5SDimitry Andric    // Multiply high.
6570b57cec5SDimitry Andric    def VMH  : BinaryVRRcGeneric<"vmh", 0xE7A3>;
6580b57cec5SDimitry Andric    def VMHB : BinaryVRRc<"vmhb", 0xE7A3, int_s390_vmhb, v128b, v128b, 0>;
6590b57cec5SDimitry Andric    def VMHH : BinaryVRRc<"vmhh", 0xE7A3, int_s390_vmhh, v128h, v128h, 1>;
6600b57cec5SDimitry Andric    def VMHF : BinaryVRRc<"vmhf", 0xE7A3, int_s390_vmhf, v128f, v128f, 2>;
6610b57cec5SDimitry Andric
6620b57cec5SDimitry Andric    // Multiply logical high.
6630b57cec5SDimitry Andric    def VMLH  : BinaryVRRcGeneric<"vmlh", 0xE7A1>;
6640b57cec5SDimitry Andric    def VMLHB : BinaryVRRc<"vmlhb", 0xE7A1, int_s390_vmlhb, v128b, v128b, 0>;
6650b57cec5SDimitry Andric    def VMLHH : BinaryVRRc<"vmlhh", 0xE7A1, int_s390_vmlhh, v128h, v128h, 1>;
6660b57cec5SDimitry Andric    def VMLHF : BinaryVRRc<"vmlhf", 0xE7A1, int_s390_vmlhf, v128f, v128f, 2>;
6670b57cec5SDimitry Andric
6680b57cec5SDimitry Andric    // Multiply low.
6690b57cec5SDimitry Andric    def VML   : BinaryVRRcGeneric<"vml", 0xE7A2>;
6700b57cec5SDimitry Andric    def VMLB  : BinaryVRRc<"vmlb",  0xE7A2, mul, v128b, v128b, 0>;
6710b57cec5SDimitry Andric    def VMLHW : BinaryVRRc<"vmlhw", 0xE7A2, mul, v128h, v128h, 1>;
6720b57cec5SDimitry Andric    def VMLF  : BinaryVRRc<"vmlf",  0xE7A2, mul, v128f, v128f, 2>;
6730b57cec5SDimitry Andric
6740b57cec5SDimitry Andric    // Multiply even.
6750b57cec5SDimitry Andric    def VME  : BinaryVRRcGeneric<"vme", 0xE7A6>;
6760b57cec5SDimitry Andric    def VMEB : BinaryVRRc<"vmeb", 0xE7A6, int_s390_vmeb, v128h, v128b, 0>;
6770b57cec5SDimitry Andric    def VMEH : BinaryVRRc<"vmeh", 0xE7A6, int_s390_vmeh, v128f, v128h, 1>;
6780b57cec5SDimitry Andric    def VMEF : BinaryVRRc<"vmef", 0xE7A6, int_s390_vmef, v128g, v128f, 2>;
6790b57cec5SDimitry Andric
6800b57cec5SDimitry Andric    // Multiply logical even.
6810b57cec5SDimitry Andric    def VMLE  : BinaryVRRcGeneric<"vmle", 0xE7A4>;
6820b57cec5SDimitry Andric    def VMLEB : BinaryVRRc<"vmleb", 0xE7A4, int_s390_vmleb, v128h, v128b, 0>;
6830b57cec5SDimitry Andric    def VMLEH : BinaryVRRc<"vmleh", 0xE7A4, int_s390_vmleh, v128f, v128h, 1>;
6840b57cec5SDimitry Andric    def VMLEF : BinaryVRRc<"vmlef", 0xE7A4, int_s390_vmlef, v128g, v128f, 2>;
6850b57cec5SDimitry Andric
6860b57cec5SDimitry Andric    // Multiply odd.
6870b57cec5SDimitry Andric    def VMO  : BinaryVRRcGeneric<"vmo", 0xE7A7>;
6880b57cec5SDimitry Andric    def VMOB : BinaryVRRc<"vmob", 0xE7A7, int_s390_vmob, v128h, v128b, 0>;
6890b57cec5SDimitry Andric    def VMOH : BinaryVRRc<"vmoh", 0xE7A7, int_s390_vmoh, v128f, v128h, 1>;
6900b57cec5SDimitry Andric    def VMOF : BinaryVRRc<"vmof", 0xE7A7, int_s390_vmof, v128g, v128f, 2>;
6910b57cec5SDimitry Andric
6920b57cec5SDimitry Andric    // Multiply logical odd.
6930b57cec5SDimitry Andric    def VMLO  : BinaryVRRcGeneric<"vmlo", 0xE7A5>;
6940b57cec5SDimitry Andric    def VMLOB : BinaryVRRc<"vmlob", 0xE7A5, int_s390_vmlob, v128h, v128b, 0>;
6950b57cec5SDimitry Andric    def VMLOH : BinaryVRRc<"vmloh", 0xE7A5, int_s390_vmloh, v128f, v128h, 1>;
6960b57cec5SDimitry Andric    def VMLOF : BinaryVRRc<"vmlof", 0xE7A5, int_s390_vmlof, v128g, v128f, 2>;
6975ffd83dbSDimitry Andric  }
6980b57cec5SDimitry Andric
6990b57cec5SDimitry Andric  // Multiply sum logical.
7005ffd83dbSDimitry Andric  let Predicates = [FeatureVectorEnhancements1], isCommutable = 1 in {
7010b57cec5SDimitry Andric    def VMSL  : QuaternaryVRRdGeneric<"vmsl", 0xE7B8>;
7020b57cec5SDimitry Andric    def VMSLG : QuaternaryVRRd<"vmslg", 0xE7B8, int_s390_vmslg,
7030b57cec5SDimitry Andric                               v128q, v128g, v128g, v128q, 3>;
7040b57cec5SDimitry Andric  }
7050b57cec5SDimitry Andric
7060b57cec5SDimitry Andric  // Nand.
7075ffd83dbSDimitry Andric  let Predicates = [FeatureVectorEnhancements1], isCommutable = 1 in
7080b57cec5SDimitry Andric    def VNN : BinaryVRRc<"vnn", 0xE76E, null_frag, v128any, v128any>;
7090b57cec5SDimitry Andric
7100b57cec5SDimitry Andric  // Nor.
7115ffd83dbSDimitry Andric  let isCommutable = 1 in
7120b57cec5SDimitry Andric    def VNO : BinaryVRRc<"vno", 0xE76B, null_frag, v128any, v128any>;
7130b57cec5SDimitry Andric  def : InstAlias<"vnot\t$V1, $V2", (VNO VR128:$V1, VR128:$V2, VR128:$V2), 0>;
7140b57cec5SDimitry Andric
7150b57cec5SDimitry Andric  // Or.
7165ffd83dbSDimitry Andric  let isCommutable = 1 in
7170b57cec5SDimitry Andric    def VO : BinaryVRRc<"vo", 0xE76A, null_frag, v128any, v128any>;
7180b57cec5SDimitry Andric
7190b57cec5SDimitry Andric  // Or with complement.
7200b57cec5SDimitry Andric  let Predicates = [FeatureVectorEnhancements1] in
7210b57cec5SDimitry Andric    def VOC : BinaryVRRc<"voc", 0xE76F, null_frag, v128any, v128any>;
7220b57cec5SDimitry Andric
7230b57cec5SDimitry Andric  // Population count.
7240b57cec5SDimitry Andric  def VPOPCT : UnaryVRRaGeneric<"vpopct", 0xE750>;
7250b57cec5SDimitry Andric  def : Pat<(v16i8 (z_popcnt VR128:$x)), (VPOPCT VR128:$x, 0)>;
7260b57cec5SDimitry Andric  let Predicates = [FeatureVectorEnhancements1] in {
7270b57cec5SDimitry Andric    def VPOPCTB : UnaryVRRa<"vpopctb", 0xE750, ctpop, v128b, v128b, 0>;
7280b57cec5SDimitry Andric    def VPOPCTH : UnaryVRRa<"vpopcth", 0xE750, ctpop, v128h, v128h, 1>;
7290b57cec5SDimitry Andric    def VPOPCTF : UnaryVRRa<"vpopctf", 0xE750, ctpop, v128f, v128f, 2>;
7300b57cec5SDimitry Andric    def VPOPCTG : UnaryVRRa<"vpopctg", 0xE750, ctpop, v128g, v128g, 3>;
7310b57cec5SDimitry Andric  }
7320b57cec5SDimitry Andric
7330b57cec5SDimitry Andric  // Element rotate left logical (with vector shift amount).
7340b57cec5SDimitry Andric  def VERLLV  : BinaryVRRcGeneric<"verllv", 0xE773>;
7355f757f3fSDimitry Andric  def VERLLVB : BinaryVRRc<"verllvb", 0xE773, rotl, v128b, v128b, 0>;
7365f757f3fSDimitry Andric  def VERLLVH : BinaryVRRc<"verllvh", 0xE773, rotl, v128h, v128h, 1>;
7375f757f3fSDimitry Andric  def VERLLVF : BinaryVRRc<"verllvf", 0xE773, rotl, v128f, v128f, 2>;
7385f757f3fSDimitry Andric  def VERLLVG : BinaryVRRc<"verllvg", 0xE773, rotl, v128g, v128g, 3>;
7390b57cec5SDimitry Andric
7400b57cec5SDimitry Andric  // Element rotate left logical (with scalar shift amount).
7410b57cec5SDimitry Andric  def VERLL  : BinaryVRSaGeneric<"verll", 0xE733>;
7425f757f3fSDimitry Andric  def VERLLB : BinaryVRSa<"verllb", 0xE733, z_vrotl_by_scalar, v128b, v128b, 0>;
7435f757f3fSDimitry Andric  def VERLLH : BinaryVRSa<"verllh", 0xE733, z_vrotl_by_scalar, v128h, v128h, 1>;
7445f757f3fSDimitry Andric  def VERLLF : BinaryVRSa<"verllf", 0xE733, z_vrotl_by_scalar, v128f, v128f, 2>;
7455f757f3fSDimitry Andric  def VERLLG : BinaryVRSa<"verllg", 0xE733, z_vrotl_by_scalar, v128g, v128g, 3>;
7460b57cec5SDimitry Andric
7470b57cec5SDimitry Andric  // Element rotate and insert under mask.
7480b57cec5SDimitry Andric  def VERIM  : QuaternaryVRIdGeneric<"verim", 0xE772>;
7490b57cec5SDimitry Andric  def VERIMB : QuaternaryVRId<"verimb", 0xE772, int_s390_verimb, v128b, v128b, 0>;
7500b57cec5SDimitry Andric  def VERIMH : QuaternaryVRId<"verimh", 0xE772, int_s390_verimh, v128h, v128h, 1>;
7510b57cec5SDimitry Andric  def VERIMF : QuaternaryVRId<"verimf", 0xE772, int_s390_verimf, v128f, v128f, 2>;
7520b57cec5SDimitry Andric  def VERIMG : QuaternaryVRId<"verimg", 0xE772, int_s390_verimg, v128g, v128g, 3>;
7530b57cec5SDimitry Andric
7540b57cec5SDimitry Andric  // Element shift left (with vector shift amount).
7550b57cec5SDimitry Andric  def VESLV  : BinaryVRRcGeneric<"veslv", 0xE770>;
7560b57cec5SDimitry Andric  def VESLVB : BinaryVRRc<"veslvb", 0xE770, z_vshl, v128b, v128b, 0>;
7570b57cec5SDimitry Andric  def VESLVH : BinaryVRRc<"veslvh", 0xE770, z_vshl, v128h, v128h, 1>;
7580b57cec5SDimitry Andric  def VESLVF : BinaryVRRc<"veslvf", 0xE770, z_vshl, v128f, v128f, 2>;
7590b57cec5SDimitry Andric  def VESLVG : BinaryVRRc<"veslvg", 0xE770, z_vshl, v128g, v128g, 3>;
7600b57cec5SDimitry Andric
7610b57cec5SDimitry Andric  // Element shift left (with scalar shift amount).
7620b57cec5SDimitry Andric  def VESL  : BinaryVRSaGeneric<"vesl", 0xE730>;
7630b57cec5SDimitry Andric  def VESLB : BinaryVRSa<"veslb", 0xE730, z_vshl_by_scalar, v128b, v128b, 0>;
7640b57cec5SDimitry Andric  def VESLH : BinaryVRSa<"veslh", 0xE730, z_vshl_by_scalar, v128h, v128h, 1>;
7650b57cec5SDimitry Andric  def VESLF : BinaryVRSa<"veslf", 0xE730, z_vshl_by_scalar, v128f, v128f, 2>;
7660b57cec5SDimitry Andric  def VESLG : BinaryVRSa<"veslg", 0xE730, z_vshl_by_scalar, v128g, v128g, 3>;
7670b57cec5SDimitry Andric
7680b57cec5SDimitry Andric  // Element shift right arithmetic (with vector shift amount).
7690b57cec5SDimitry Andric  def VESRAV  : BinaryVRRcGeneric<"vesrav", 0xE77A>;
7700b57cec5SDimitry Andric  def VESRAVB : BinaryVRRc<"vesravb", 0xE77A, z_vsra, v128b, v128b, 0>;
7710b57cec5SDimitry Andric  def VESRAVH : BinaryVRRc<"vesravh", 0xE77A, z_vsra, v128h, v128h, 1>;
7720b57cec5SDimitry Andric  def VESRAVF : BinaryVRRc<"vesravf", 0xE77A, z_vsra, v128f, v128f, 2>;
7730b57cec5SDimitry Andric  def VESRAVG : BinaryVRRc<"vesravg", 0xE77A, z_vsra, v128g, v128g, 3>;
7740b57cec5SDimitry Andric
7750b57cec5SDimitry Andric  // Element shift right arithmetic (with scalar shift amount).
7760b57cec5SDimitry Andric  def VESRA  : BinaryVRSaGeneric<"vesra", 0xE73A>;
7770b57cec5SDimitry Andric  def VESRAB : BinaryVRSa<"vesrab", 0xE73A, z_vsra_by_scalar, v128b, v128b, 0>;
7780b57cec5SDimitry Andric  def VESRAH : BinaryVRSa<"vesrah", 0xE73A, z_vsra_by_scalar, v128h, v128h, 1>;
7790b57cec5SDimitry Andric  def VESRAF : BinaryVRSa<"vesraf", 0xE73A, z_vsra_by_scalar, v128f, v128f, 2>;
7800b57cec5SDimitry Andric  def VESRAG : BinaryVRSa<"vesrag", 0xE73A, z_vsra_by_scalar, v128g, v128g, 3>;
7810b57cec5SDimitry Andric
7820b57cec5SDimitry Andric  // Element shift right logical (with vector shift amount).
7830b57cec5SDimitry Andric  def VESRLV  : BinaryVRRcGeneric<"vesrlv", 0xE778>;
7840b57cec5SDimitry Andric  def VESRLVB : BinaryVRRc<"vesrlvb", 0xE778, z_vsrl, v128b, v128b, 0>;
7850b57cec5SDimitry Andric  def VESRLVH : BinaryVRRc<"vesrlvh", 0xE778, z_vsrl, v128h, v128h, 1>;
7860b57cec5SDimitry Andric  def VESRLVF : BinaryVRRc<"vesrlvf", 0xE778, z_vsrl, v128f, v128f, 2>;
7870b57cec5SDimitry Andric  def VESRLVG : BinaryVRRc<"vesrlvg", 0xE778, z_vsrl, v128g, v128g, 3>;
7880b57cec5SDimitry Andric
7890b57cec5SDimitry Andric  // Element shift right logical (with scalar shift amount).
7900b57cec5SDimitry Andric  def VESRL  : BinaryVRSaGeneric<"vesrl", 0xE738>;
7910b57cec5SDimitry Andric  def VESRLB : BinaryVRSa<"vesrlb", 0xE738, z_vsrl_by_scalar, v128b, v128b, 0>;
7920b57cec5SDimitry Andric  def VESRLH : BinaryVRSa<"vesrlh", 0xE738, z_vsrl_by_scalar, v128h, v128h, 1>;
7930b57cec5SDimitry Andric  def VESRLF : BinaryVRSa<"vesrlf", 0xE738, z_vsrl_by_scalar, v128f, v128f, 2>;
7940b57cec5SDimitry Andric  def VESRLG : BinaryVRSa<"vesrlg", 0xE738, z_vsrl_by_scalar, v128g, v128g, 3>;
7950b57cec5SDimitry Andric
7960b57cec5SDimitry Andric  // Shift left.
7970b57cec5SDimitry Andric  def VSL : BinaryVRRc<"vsl", 0xE774, int_s390_vsl, v128b, v128b>;
7980b57cec5SDimitry Andric
7990b57cec5SDimitry Andric  // Shift left by byte.
8000b57cec5SDimitry Andric  def VSLB : BinaryVRRc<"vslb", 0xE775, int_s390_vslb, v128b, v128b>;
8010b57cec5SDimitry Andric
8020b57cec5SDimitry Andric  // Shift left double by byte.
8030b57cec5SDimitry Andric  def VSLDB : TernaryVRId<"vsldb", 0xE777, z_shl_double, v128b, v128b, 0>;
8048bcb0991SDimitry Andric  def : Pat<(int_s390_vsldb VR128:$x, VR128:$y, imm32zx8_timm:$z),
8050b57cec5SDimitry Andric            (VSLDB VR128:$x, VR128:$y, imm32zx8:$z)>;
8060b57cec5SDimitry Andric
8070b57cec5SDimitry Andric  // Shift left double by bit.
8080b57cec5SDimitry Andric  let Predicates = [FeatureVectorEnhancements2] in
8090b57cec5SDimitry Andric    def VSLD : TernaryVRId<"vsld", 0xE786, int_s390_vsld, v128b, v128b, 0>;
8100b57cec5SDimitry Andric
8110b57cec5SDimitry Andric  // Shift right arithmetic.
8120b57cec5SDimitry Andric  def VSRA : BinaryVRRc<"vsra", 0xE77E, int_s390_vsra, v128b, v128b>;
8130b57cec5SDimitry Andric
8140b57cec5SDimitry Andric  // Shift right arithmetic by byte.
8150b57cec5SDimitry Andric  def VSRAB : BinaryVRRc<"vsrab", 0xE77F, int_s390_vsrab, v128b, v128b>;
8160b57cec5SDimitry Andric
8170b57cec5SDimitry Andric  // Shift right logical.
8180b57cec5SDimitry Andric  def VSRL : BinaryVRRc<"vsrl", 0xE77C, int_s390_vsrl, v128b, v128b>;
8190b57cec5SDimitry Andric
8200b57cec5SDimitry Andric  // Shift right logical by byte.
8210b57cec5SDimitry Andric  def VSRLB : BinaryVRRc<"vsrlb", 0xE77D, int_s390_vsrlb, v128b, v128b>;
8220b57cec5SDimitry Andric
8230b57cec5SDimitry Andric  // Shift right double by bit.
8240b57cec5SDimitry Andric  let Predicates = [FeatureVectorEnhancements2] in
8250b57cec5SDimitry Andric    def VSRD : TernaryVRId<"vsrd", 0xE787, int_s390_vsrd, v128b, v128b, 0>;
8260b57cec5SDimitry Andric
8270b57cec5SDimitry Andric  // Subtract.
8280b57cec5SDimitry Andric  def VS  : BinaryVRRcGeneric<"vs", 0xE7F7>;
8290b57cec5SDimitry Andric  def VSB : BinaryVRRc<"vsb", 0xE7F7, sub, v128b, v128b, 0>;
8300b57cec5SDimitry Andric  def VSH : BinaryVRRc<"vsh", 0xE7F7, sub, v128h, v128h, 1>;
8310b57cec5SDimitry Andric  def VSF : BinaryVRRc<"vsf", 0xE7F7, sub, v128f, v128f, 2>;
8320b57cec5SDimitry Andric  def VSG : BinaryVRRc<"vsg", 0xE7F7, sub, v128g, v128g, 3>;
8335f757f3fSDimitry Andric  def VSQ : BinaryVRRc<"vsq", 0xE7F7, sub, v128q, v128q, 4>;
8340b57cec5SDimitry Andric
8350b57cec5SDimitry Andric  // Subtract compute borrow indication.
8360b57cec5SDimitry Andric  def VSCBI  : BinaryVRRcGeneric<"vscbi", 0xE7F5>;
8375f757f3fSDimitry Andric  def VSCBIB : BinaryVRRc<"vscbib", 0xE7F5, z_vscbi, v128b, v128b, 0>;
8385f757f3fSDimitry Andric  def VSCBIH : BinaryVRRc<"vscbih", 0xE7F5, z_vscbi, v128h, v128h, 1>;
8395f757f3fSDimitry Andric  def VSCBIF : BinaryVRRc<"vscbif", 0xE7F5, z_vscbi, v128f, v128f, 2>;
8405f757f3fSDimitry Andric  def VSCBIG : BinaryVRRc<"vscbig", 0xE7F5, z_vscbi, v128g, v128g, 3>;
8415f757f3fSDimitry Andric  def VSCBIQ : BinaryVRRc<"vscbiq", 0xE7F5, z_vscbi, v128q, v128q, 4>;
8420b57cec5SDimitry Andric
8430b57cec5SDimitry Andric  // Subtract with borrow indication.
8440b57cec5SDimitry Andric  def VSBI  : TernaryVRRdGeneric<"vsbi", 0xE7BF>;
8455f757f3fSDimitry Andric  def VSBIQ : TernaryVRRd<"vsbiq", 0xE7BF, z_vsbi, v128q, v128q, 4>;
8460b57cec5SDimitry Andric
8470b57cec5SDimitry Andric  // Subtract with borrow compute borrow indication.
8480b57cec5SDimitry Andric  def VSBCBI  : TernaryVRRdGeneric<"vsbcbi", 0xE7BD>;
8495f757f3fSDimitry Andric  def VSBCBIQ : TernaryVRRd<"vsbcbiq", 0xE7BD, z_vsbcbi, v128q, v128q, 4>;
8500b57cec5SDimitry Andric
8510b57cec5SDimitry Andric  // Sum across doubleword.
8520b57cec5SDimitry Andric  def VSUMG  : BinaryVRRcGeneric<"vsumg", 0xE765>;
8530b57cec5SDimitry Andric  def VSUMGH : BinaryVRRc<"vsumgh", 0xE765, z_vsum, v128g, v128h, 1>;
8540b57cec5SDimitry Andric  def VSUMGF : BinaryVRRc<"vsumgf", 0xE765, z_vsum, v128g, v128f, 2>;
8550b57cec5SDimitry Andric
8560b57cec5SDimitry Andric  // Sum across quadword.
8570b57cec5SDimitry Andric  def VSUMQ  : BinaryVRRcGeneric<"vsumq", 0xE767>;
8580b57cec5SDimitry Andric  def VSUMQF : BinaryVRRc<"vsumqf", 0xE767, z_vsum, v128q, v128f, 2>;
8590b57cec5SDimitry Andric  def VSUMQG : BinaryVRRc<"vsumqg", 0xE767, z_vsum, v128q, v128g, 3>;
8600b57cec5SDimitry Andric
8610b57cec5SDimitry Andric  // Sum across word.
8620b57cec5SDimitry Andric  def VSUM  : BinaryVRRcGeneric<"vsum", 0xE764>;
8630b57cec5SDimitry Andric  def VSUMB : BinaryVRRc<"vsumb", 0xE764, z_vsum, v128f, v128b, 0>;
8640b57cec5SDimitry Andric  def VSUMH : BinaryVRRc<"vsumh", 0xE764, z_vsum, v128f, v128h, 1>;
8650b57cec5SDimitry Andric}
8660b57cec5SDimitry Andric
8670b57cec5SDimitry Andric// Instantiate the bitwise ops for type TYPE.
8685f757f3fSDimitry Andricmulticlass BitwiseVectorOps<ValueType type, SDPatternOperator not_op> {
8690b57cec5SDimitry Andric  let Predicates = [FeatureVector] in {
8700b57cec5SDimitry Andric    def : Pat<(type (and VR128:$x, VR128:$y)), (VN VR128:$x, VR128:$y)>;
8715f757f3fSDimitry Andric    def : Pat<(type (and VR128:$x, (not_op VR128:$y))),
8720b57cec5SDimitry Andric              (VNC VR128:$x, VR128:$y)>;
8730b57cec5SDimitry Andric    def : Pat<(type (or VR128:$x, VR128:$y)), (VO VR128:$x, VR128:$y)>;
8740b57cec5SDimitry Andric    def : Pat<(type (xor VR128:$x, VR128:$y)), (VX VR128:$x, VR128:$y)>;
8750b57cec5SDimitry Andric    def : Pat<(type (or (and VR128:$x, VR128:$z),
8765f757f3fSDimitry Andric                        (and VR128:$y, (not_op VR128:$z)))),
8770b57cec5SDimitry Andric              (VSEL VR128:$x, VR128:$y, VR128:$z)>;
8785f757f3fSDimitry Andric    def : Pat<(type (not_op (or VR128:$x, VR128:$y))),
8790b57cec5SDimitry Andric              (VNO VR128:$x, VR128:$y)>;
8805f757f3fSDimitry Andric    def : Pat<(type (not_op VR128:$x)), (VNO VR128:$x, VR128:$x)>;
8810b57cec5SDimitry Andric  }
8820b57cec5SDimitry Andric  let Predicates = [FeatureVectorEnhancements1] in {
8835f757f3fSDimitry Andric    def : Pat<(type (not_op (xor VR128:$x, VR128:$y))),
8840b57cec5SDimitry Andric              (VNX VR128:$x, VR128:$y)>;
8855f757f3fSDimitry Andric    def : Pat<(type (not_op (and VR128:$x, VR128:$y))),
8860b57cec5SDimitry Andric              (VNN VR128:$x, VR128:$y)>;
8875f757f3fSDimitry Andric    def : Pat<(type (or VR128:$x, (not_op VR128:$y))),
8880b57cec5SDimitry Andric              (VOC VR128:$x, VR128:$y)>;
8890b57cec5SDimitry Andric  }
8900b57cec5SDimitry Andric}
8910b57cec5SDimitry Andric
8925f757f3fSDimitry Andricdefm : BitwiseVectorOps<v16i8, z_vnot>;
8935f757f3fSDimitry Andricdefm : BitwiseVectorOps<v8i16, z_vnot>;
8945f757f3fSDimitry Andricdefm : BitwiseVectorOps<v4i32, z_vnot>;
8955f757f3fSDimitry Andricdefm : BitwiseVectorOps<v2i64, z_vnot>;
8965f757f3fSDimitry Andricdefm : BitwiseVectorOps<i128, not>;
8970b57cec5SDimitry Andric
8980b57cec5SDimitry Andric// Instantiate additional patterns for absolute-related expressions on
8990b57cec5SDimitry Andric// type TYPE.  LC is the negate instruction for TYPE and LP is the absolute
9000b57cec5SDimitry Andric// instruction.
9010b57cec5SDimitry Andricmulticlass IntegerAbsoluteVectorOps<ValueType type, Instruction lc,
9020b57cec5SDimitry Andric                                    Instruction lp, int shift> {
9030b57cec5SDimitry Andric  let Predicates = [FeatureVector] in {
9040b57cec5SDimitry Andric    def : Pat<(type (vselect (type (z_vicmph_zero VR128:$x)),
9050b57cec5SDimitry Andric                             (z_vneg VR128:$x), VR128:$x)),
9060b57cec5SDimitry Andric              (lc (lp VR128:$x))>;
9070b57cec5SDimitry Andric    def : Pat<(type (vselect (type (z_vnot (z_vicmph_zero VR128:$x))),
9080b57cec5SDimitry Andric                             VR128:$x, (z_vneg VR128:$x))),
9090b57cec5SDimitry Andric              (lc (lp VR128:$x))>;
9100b57cec5SDimitry Andric    def : Pat<(type (vselect (type (z_vicmpl_zero VR128:$x)),
9110b57cec5SDimitry Andric                             VR128:$x, (z_vneg VR128:$x))),
9120b57cec5SDimitry Andric              (lc (lp VR128:$x))>;
9130b57cec5SDimitry Andric    def : Pat<(type (vselect (type (z_vnot (z_vicmpl_zero VR128:$x))),
9140b57cec5SDimitry Andric                             (z_vneg VR128:$x), VR128:$x)),
9150b57cec5SDimitry Andric              (lc (lp VR128:$x))>;
9160b57cec5SDimitry Andric    def : Pat<(type (or (and (z_vsra_by_scalar VR128:$x, (i32 shift)),
9170b57cec5SDimitry Andric                             (z_vneg VR128:$x)),
9180b57cec5SDimitry Andric                        (and (z_vnot (z_vsra_by_scalar VR128:$x, (i32 shift))),
9190b57cec5SDimitry Andric                             VR128:$x))),
9200b57cec5SDimitry Andric              (lp VR128:$x)>;
9210b57cec5SDimitry Andric    def : Pat<(type (or (and (z_vsra_by_scalar VR128:$x, (i32 shift)),
9220b57cec5SDimitry Andric                             VR128:$x),
9230b57cec5SDimitry Andric                        (and (z_vnot (z_vsra_by_scalar VR128:$x, (i32 shift))),
9240b57cec5SDimitry Andric                             (z_vneg VR128:$x)))),
9250b57cec5SDimitry Andric              (lc (lp VR128:$x))>;
9260b57cec5SDimitry Andric  }
9270b57cec5SDimitry Andric}
9280b57cec5SDimitry Andric
9290b57cec5SDimitry Andricdefm : IntegerAbsoluteVectorOps<v16i8, VLCB, VLPB, 7>;
9300b57cec5SDimitry Andricdefm : IntegerAbsoluteVectorOps<v8i16, VLCH, VLPH, 15>;
9310b57cec5SDimitry Andricdefm : IntegerAbsoluteVectorOps<v4i32, VLCF, VLPF, 31>;
9320b57cec5SDimitry Andricdefm : IntegerAbsoluteVectorOps<v2i64, VLCG, VLPG, 63>;
9330b57cec5SDimitry Andric
9340b57cec5SDimitry Andric// Instantiate minimum- and maximum-related patterns for TYPE.  CMPH is the
9350b57cec5SDimitry Andric// signed or unsigned "set if greater than" comparison instruction and
9360b57cec5SDimitry Andric// MIN and MAX are the associated minimum and maximum instructions.
9370b57cec5SDimitry Andricmulticlass IntegerMinMaxVectorOps<ValueType type, SDPatternOperator cmph,
9380b57cec5SDimitry Andric                                  Instruction min, Instruction max> {
9390b57cec5SDimitry Andric  let Predicates = [FeatureVector] in {
9400b57cec5SDimitry Andric    def : Pat<(type (vselect (cmph VR128:$x, VR128:$y), VR128:$x, VR128:$y)),
9410b57cec5SDimitry Andric              (max VR128:$x, VR128:$y)>;
9420b57cec5SDimitry Andric    def : Pat<(type (vselect (cmph VR128:$x, VR128:$y), VR128:$y, VR128:$x)),
9430b57cec5SDimitry Andric              (min VR128:$x, VR128:$y)>;
9440b57cec5SDimitry Andric    def : Pat<(type (vselect (z_vnot (cmph VR128:$x, VR128:$y)),
9450b57cec5SDimitry Andric                             VR128:$x, VR128:$y)),
9460b57cec5SDimitry Andric              (min VR128:$x, VR128:$y)>;
9470b57cec5SDimitry Andric    def : Pat<(type (vselect (z_vnot (cmph VR128:$x, VR128:$y)),
9480b57cec5SDimitry Andric                             VR128:$y, VR128:$x)),
9490b57cec5SDimitry Andric              (max VR128:$x, VR128:$y)>;
9500b57cec5SDimitry Andric  }
9510b57cec5SDimitry Andric}
9520b57cec5SDimitry Andric
9530b57cec5SDimitry Andric// Signed min/max.
9540b57cec5SDimitry Andricdefm : IntegerMinMaxVectorOps<v16i8, z_vicmph, VMNB, VMXB>;
9550b57cec5SDimitry Andricdefm : IntegerMinMaxVectorOps<v8i16, z_vicmph, VMNH, VMXH>;
9560b57cec5SDimitry Andricdefm : IntegerMinMaxVectorOps<v4i32, z_vicmph, VMNF, VMXF>;
9570b57cec5SDimitry Andricdefm : IntegerMinMaxVectorOps<v2i64, z_vicmph, VMNG, VMXG>;
9580b57cec5SDimitry Andric
9590b57cec5SDimitry Andric// Unsigned min/max.
9600b57cec5SDimitry Andricdefm : IntegerMinMaxVectorOps<v16i8, z_vicmphl, VMNLB, VMXLB>;
9610b57cec5SDimitry Andricdefm : IntegerMinMaxVectorOps<v8i16, z_vicmphl, VMNLH, VMXLH>;
9620b57cec5SDimitry Andricdefm : IntegerMinMaxVectorOps<v4i32, z_vicmphl, VMNLF, VMXLF>;
9630b57cec5SDimitry Andricdefm : IntegerMinMaxVectorOps<v2i64, z_vicmphl, VMNLG, VMXLG>;
9640b57cec5SDimitry Andric
9655f757f3fSDimitry Andric// Instantiate full-vector shifts.
9665f757f3fSDimitry Andricmulticlass FullVectorShiftOps<SDPatternOperator shift,
9675f757f3fSDimitry Andric                              Instruction sbit, Instruction sbyte> {
9685f757f3fSDimitry Andric  let Predicates = [FeatureVector] in {
9695f757f3fSDimitry Andric    def : Pat<(shift (i128 VR128:$x), imm32nobytes:$amt),
9705f757f3fSDimitry Andric              (sbit VR128:$x, (VREPIB (UIMM8 imm:$amt)))>;
9715f757f3fSDimitry Andric    def : Pat<(shift (i128 VR128:$x), imm32nobits:$amt),
9725f757f3fSDimitry Andric              (sbyte VR128:$x, (VREPIB (UIMM8 imm:$amt)))>;
9735f757f3fSDimitry Andric    def : Pat<(shift (i128 VR128:$x), imm32:$amt),
9745f757f3fSDimitry Andric              (sbit (sbyte VR128:$x, (VREPIB (UIMM8 imm:$amt))),
9755f757f3fSDimitry Andric                    (VREPIB (UIMM8 imm:$amt)))>;
9765f757f3fSDimitry Andric    def : Pat<(shift (i128 VR128:$x), GR32:$amt),
9775f757f3fSDimitry Andric              (sbit (sbyte VR128:$x, (VREPB (VLVGP32 GR32:$amt, GR32:$amt), 15)),
9785f757f3fSDimitry Andric                    (VREPB (VLVGP32 GR32:$amt, GR32:$amt), 15))>;
9795f757f3fSDimitry Andric  }
9805f757f3fSDimitry Andric}
9815f757f3fSDimitry Andricdefm : FullVectorShiftOps<vshiftop<shl>, VSL, VSLB>;
9825f757f3fSDimitry Andricdefm : FullVectorShiftOps<vshiftop<srl>, VSRL, VSRLB>;
9835f757f3fSDimitry Andricdefm : FullVectorShiftOps<vshiftop<sra>, VSRA, VSRAB>;
9845f757f3fSDimitry Andric
9850b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
9860b57cec5SDimitry Andric// Integer comparison
9870b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
9880b57cec5SDimitry Andric
9890b57cec5SDimitry Andriclet Predicates = [FeatureVector] in {
9900b57cec5SDimitry Andric  // Element compare.
9910b57cec5SDimitry Andric  let Defs = [CC] in {
9920b57cec5SDimitry Andric    def VEC  : CompareVRRaGeneric<"vec", 0xE7DB>;
9930b57cec5SDimitry Andric    def VECB : CompareVRRa<"vecb", 0xE7DB, null_frag, v128b, 0>;
9940b57cec5SDimitry Andric    def VECH : CompareVRRa<"vech", 0xE7DB, null_frag, v128h, 1>;
9950b57cec5SDimitry Andric    def VECF : CompareVRRa<"vecf", 0xE7DB, null_frag, v128f, 2>;
9960b57cec5SDimitry Andric    def VECG : CompareVRRa<"vecg", 0xE7DB, null_frag, v128g, 3>;
9970b57cec5SDimitry Andric  }
9980b57cec5SDimitry Andric
9990b57cec5SDimitry Andric  // Element compare logical.
10000b57cec5SDimitry Andric  let Defs = [CC] in {
10010b57cec5SDimitry Andric    def VECL  : CompareVRRaGeneric<"vecl", 0xE7D9>;
10020b57cec5SDimitry Andric    def VECLB : CompareVRRa<"veclb", 0xE7D9, null_frag, v128b, 0>;
10030b57cec5SDimitry Andric    def VECLH : CompareVRRa<"veclh", 0xE7D9, null_frag, v128h, 1>;
10040b57cec5SDimitry Andric    def VECLF : CompareVRRa<"veclf", 0xE7D9, null_frag, v128f, 2>;
10050b57cec5SDimitry Andric    def VECLG : CompareVRRa<"veclg", 0xE7D9, null_frag, v128g, 3>;
10060b57cec5SDimitry Andric  }
10070b57cec5SDimitry Andric
10080b57cec5SDimitry Andric  // Compare equal.
10090b57cec5SDimitry Andric  def  VCEQ  : BinaryVRRbSPairGeneric<"vceq", 0xE7F8>;
10100b57cec5SDimitry Andric  defm VCEQB : BinaryVRRbSPair<"vceqb", 0xE7F8, z_vicmpe, z_vicmpes,
10110b57cec5SDimitry Andric                               v128b, v128b, 0>;
10120b57cec5SDimitry Andric  defm VCEQH : BinaryVRRbSPair<"vceqh", 0xE7F8, z_vicmpe, z_vicmpes,
10130b57cec5SDimitry Andric                               v128h, v128h, 1>;
10140b57cec5SDimitry Andric  defm VCEQF : BinaryVRRbSPair<"vceqf", 0xE7F8, z_vicmpe, z_vicmpes,
10150b57cec5SDimitry Andric                               v128f, v128f, 2>;
10160b57cec5SDimitry Andric  defm VCEQG : BinaryVRRbSPair<"vceqg", 0xE7F8, z_vicmpe, z_vicmpes,
10170b57cec5SDimitry Andric                               v128g, v128g, 3>;
10180b57cec5SDimitry Andric
10190b57cec5SDimitry Andric  // Compare high.
10200b57cec5SDimitry Andric  def  VCH  : BinaryVRRbSPairGeneric<"vch", 0xE7FB>;
10210b57cec5SDimitry Andric  defm VCHB : BinaryVRRbSPair<"vchb", 0xE7FB, z_vicmph, z_vicmphs,
10220b57cec5SDimitry Andric                              v128b, v128b, 0>;
10230b57cec5SDimitry Andric  defm VCHH : BinaryVRRbSPair<"vchh", 0xE7FB, z_vicmph, z_vicmphs,
10240b57cec5SDimitry Andric                              v128h, v128h, 1>;
10250b57cec5SDimitry Andric  defm VCHF : BinaryVRRbSPair<"vchf", 0xE7FB, z_vicmph, z_vicmphs,
10260b57cec5SDimitry Andric                              v128f, v128f, 2>;
10270b57cec5SDimitry Andric  defm VCHG : BinaryVRRbSPair<"vchg", 0xE7FB, z_vicmph, z_vicmphs,
10280b57cec5SDimitry Andric                              v128g, v128g, 3>;
10290b57cec5SDimitry Andric
10300b57cec5SDimitry Andric  // Compare high logical.
10310b57cec5SDimitry Andric  def  VCHL  : BinaryVRRbSPairGeneric<"vchl", 0xE7F9>;
10320b57cec5SDimitry Andric  defm VCHLB : BinaryVRRbSPair<"vchlb", 0xE7F9, z_vicmphl, z_vicmphls,
10330b57cec5SDimitry Andric                               v128b, v128b, 0>;
10340b57cec5SDimitry Andric  defm VCHLH : BinaryVRRbSPair<"vchlh", 0xE7F9, z_vicmphl, z_vicmphls,
10350b57cec5SDimitry Andric                               v128h, v128h, 1>;
10360b57cec5SDimitry Andric  defm VCHLF : BinaryVRRbSPair<"vchlf", 0xE7F9, z_vicmphl, z_vicmphls,
10370b57cec5SDimitry Andric                               v128f, v128f, 2>;
10380b57cec5SDimitry Andric  defm VCHLG : BinaryVRRbSPair<"vchlg", 0xE7F9, z_vicmphl, z_vicmphls,
10390b57cec5SDimitry Andric                               v128g, v128g, 3>;
10400b57cec5SDimitry Andric
10410b57cec5SDimitry Andric  // Test under mask.
10420b57cec5SDimitry Andric  let Defs = [CC] in
10430b57cec5SDimitry Andric    def VTM : CompareVRRa<"vtm", 0xE7D8, z_vtm, v128b, 0>;
10440b57cec5SDimitry Andric}
10450b57cec5SDimitry Andric
10460b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
10470b57cec5SDimitry Andric// Floating-point arithmetic
10480b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
10490b57cec5SDimitry Andric
10500b57cec5SDimitry Andric// See comments in SystemZInstrFP.td for the suppression flags and
10510b57cec5SDimitry Andric// rounding modes.
10520b57cec5SDimitry Andricmulticlass VectorRounding<Instruction insn, TypedReg tr> {
10530b57cec5SDimitry Andric  def : FPConversion<insn, any_frint,      tr, tr, 0, 0>;
10540b57cec5SDimitry Andric  def : FPConversion<insn, any_fnearbyint, tr, tr, 4, 0>;
10550b57cec5SDimitry Andric  def : FPConversion<insn, any_ffloor,     tr, tr, 4, 7>;
10560b57cec5SDimitry Andric  def : FPConversion<insn, any_fceil,      tr, tr, 4, 6>;
10570b57cec5SDimitry Andric  def : FPConversion<insn, any_ftrunc,     tr, tr, 4, 5>;
10580b57cec5SDimitry Andric  def : FPConversion<insn, any_fround,     tr, tr, 4, 1>;
10590b57cec5SDimitry Andric}
10600b57cec5SDimitry Andric
10610b57cec5SDimitry Andriclet Predicates = [FeatureVector] in {
10620b57cec5SDimitry Andric  // Add.
10635ffd83dbSDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1, isCommutable = 1 in {
10640b57cec5SDimitry Andric    def VFA   : BinaryVRRcFloatGeneric<"vfa", 0xE7E3>;
10650b57cec5SDimitry Andric    def VFADB : BinaryVRRc<"vfadb", 0xE7E3, any_fadd, v128db, v128db, 3, 0>;
10665ffd83dbSDimitry Andric    def WFADB : BinaryVRRc<"wfadb", 0xE7E3, any_fadd, v64db, v64db, 3, 8, 0,
10675ffd83dbSDimitry Andric                           "adbr">;
10680b57cec5SDimitry Andric    let Predicates = [FeatureVectorEnhancements1] in {
10690b57cec5SDimitry Andric      def VFASB : BinaryVRRc<"vfasb", 0xE7E3, any_fadd, v128sb, v128sb, 2, 0>;
10705ffd83dbSDimitry Andric      def WFASB : BinaryVRRc<"wfasb", 0xE7E3, any_fadd, v32sb, v32sb, 2, 8, 0,
10715ffd83dbSDimitry Andric                             "aebr">;
10720b57cec5SDimitry Andric      def WFAXB : BinaryVRRc<"wfaxb", 0xE7E3, any_fadd, v128xb, v128xb, 4, 8>;
10730b57cec5SDimitry Andric    }
10740b57cec5SDimitry Andric  }
10750b57cec5SDimitry Andric
10760b57cec5SDimitry Andric  // Convert from fixed.
10770b57cec5SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1 in {
10780b57cec5SDimitry Andric    def VCDG  : TernaryVRRaFloatGeneric<"vcdg", 0xE7C3>;
10790b57cec5SDimitry Andric    def VCDGB : TernaryVRRa<"vcdgb", 0xE7C3, null_frag, v128db, v128g, 3, 0>;
10800b57cec5SDimitry Andric    def WCDGB : TernaryVRRa<"wcdgb", 0xE7C3, null_frag, v64db, v64g, 3, 8>;
10810b57cec5SDimitry Andric  }
1082480093f4SDimitry Andric  def : FPConversion<VCDGB, any_sint_to_fp, v128db, v128g, 0, 0>;
10830b57cec5SDimitry Andric  let Predicates = [FeatureVectorEnhancements2] in {
10840b57cec5SDimitry Andric    let Uses = [FPC], mayRaiseFPException = 1 in {
10850b57cec5SDimitry Andric      let isAsmParserOnly = 1 in
10860b57cec5SDimitry Andric        def VCFPS  : TernaryVRRaFloatGeneric<"vcfps", 0xE7C3>;
10870b57cec5SDimitry Andric      def VCEFB : TernaryVRRa<"vcefb", 0xE7C3, null_frag, v128sb, v128g, 2, 0>;
10880b57cec5SDimitry Andric      def WCEFB : TernaryVRRa<"wcefb", 0xE7C3, null_frag, v32sb, v32f, 2, 8>;
10890b57cec5SDimitry Andric    }
1090480093f4SDimitry Andric    def : FPConversion<VCEFB, any_sint_to_fp, v128sb, v128f, 0, 0>;
10910b57cec5SDimitry Andric  }
10920b57cec5SDimitry Andric
10930b57cec5SDimitry Andric  // Convert from logical.
10940b57cec5SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1 in {
10950b57cec5SDimitry Andric    def VCDLG  : TernaryVRRaFloatGeneric<"vcdlg", 0xE7C1>;
10960b57cec5SDimitry Andric    def VCDLGB : TernaryVRRa<"vcdlgb", 0xE7C1, null_frag, v128db, v128g, 3, 0>;
10970b57cec5SDimitry Andric    def WCDLGB : TernaryVRRa<"wcdlgb", 0xE7C1, null_frag, v64db, v64g, 3, 8>;
10980b57cec5SDimitry Andric  }
1099480093f4SDimitry Andric  def : FPConversion<VCDLGB, any_uint_to_fp, v128db, v128g, 0, 0>;
11000b57cec5SDimitry Andric  let Predicates = [FeatureVectorEnhancements2] in {
11010b57cec5SDimitry Andric    let Uses = [FPC], mayRaiseFPException = 1 in {
11020b57cec5SDimitry Andric      let isAsmParserOnly = 1 in
11030b57cec5SDimitry Andric        def VCFPL  : TernaryVRRaFloatGeneric<"vcfpl", 0xE7C1>;
11040b57cec5SDimitry Andric      def VCELFB : TernaryVRRa<"vcelfb", 0xE7C1, null_frag, v128sb, v128g, 2, 0>;
11050b57cec5SDimitry Andric      def WCELFB : TernaryVRRa<"wcelfb", 0xE7C1, null_frag, v32sb, v32f, 2, 8>;
11060b57cec5SDimitry Andric    }
1107480093f4SDimitry Andric    def : FPConversion<VCELFB, any_uint_to_fp, v128sb, v128f, 0, 0>;
11080b57cec5SDimitry Andric  }
11090b57cec5SDimitry Andric
11100b57cec5SDimitry Andric  // Convert to fixed.
11110b57cec5SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1 in {
11120b57cec5SDimitry Andric    def VCGD  : TernaryVRRaFloatGeneric<"vcgd", 0xE7C2>;
11130b57cec5SDimitry Andric    def VCGDB : TernaryVRRa<"vcgdb", 0xE7C2, null_frag, v128g, v128db, 3, 0>;
11140b57cec5SDimitry Andric    def WCGDB : TernaryVRRa<"wcgdb", 0xE7C2, null_frag, v64g, v64db, 3, 8>;
11150b57cec5SDimitry Andric  }
11160b57cec5SDimitry Andric  // Rounding mode should agree with SystemZInstrFP.td.
11178bcb0991SDimitry Andric  def : FPConversion<VCGDB, any_fp_to_sint, v128g, v128db, 0, 5>;
11180b57cec5SDimitry Andric  let Predicates = [FeatureVectorEnhancements2] in {
11190b57cec5SDimitry Andric    let Uses = [FPC], mayRaiseFPException = 1 in {
11200b57cec5SDimitry Andric      let isAsmParserOnly = 1 in
11210b57cec5SDimitry Andric        def VCSFP  : TernaryVRRaFloatGeneric<"vcsfp", 0xE7C2>;
11220b57cec5SDimitry Andric      def VCFEB : TernaryVRRa<"vcfeb", 0xE7C2, null_frag, v128sb, v128g, 2, 0>;
11230b57cec5SDimitry Andric      def WCFEB : TernaryVRRa<"wcfeb", 0xE7C2, null_frag, v32sb, v32f, 2, 8>;
11240b57cec5SDimitry Andric    }
11250b57cec5SDimitry Andric    // Rounding mode should agree with SystemZInstrFP.td.
11268bcb0991SDimitry Andric    def : FPConversion<VCFEB, any_fp_to_sint, v128f, v128sb, 0, 5>;
11270b57cec5SDimitry Andric  }
11280b57cec5SDimitry Andric
11290b57cec5SDimitry Andric  // Convert to logical.
11300b57cec5SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1 in {
11310b57cec5SDimitry Andric    def VCLGD  : TernaryVRRaFloatGeneric<"vclgd", 0xE7C0>;
11320b57cec5SDimitry Andric    def VCLGDB : TernaryVRRa<"vclgdb", 0xE7C0, null_frag, v128g, v128db, 3, 0>;
11330b57cec5SDimitry Andric    def WCLGDB : TernaryVRRa<"wclgdb", 0xE7C0, null_frag, v64g, v64db, 3, 8>;
11340b57cec5SDimitry Andric  }
11350b57cec5SDimitry Andric  // Rounding mode should agree with SystemZInstrFP.td.
11368bcb0991SDimitry Andric  def : FPConversion<VCLGDB, any_fp_to_uint, v128g, v128db, 0, 5>;
11370b57cec5SDimitry Andric  let Predicates = [FeatureVectorEnhancements2] in {
11380b57cec5SDimitry Andric    let Uses = [FPC], mayRaiseFPException = 1 in {
11390b57cec5SDimitry Andric      let isAsmParserOnly = 1 in
11400b57cec5SDimitry Andric        def VCLFP  : TernaryVRRaFloatGeneric<"vclfp", 0xE7C0>;
11410b57cec5SDimitry Andric      def VCLFEB : TernaryVRRa<"vclfeb", 0xE7C0, null_frag, v128sb, v128g, 2, 0>;
11420b57cec5SDimitry Andric      def WCLFEB : TernaryVRRa<"wclfeb", 0xE7C0, null_frag, v32sb, v32f, 2, 8>;
11430b57cec5SDimitry Andric    }
11440b57cec5SDimitry Andric    // Rounding mode should agree with SystemZInstrFP.td.
11458bcb0991SDimitry Andric    def : FPConversion<VCLFEB, any_fp_to_uint, v128f, v128sb, 0, 5>;
11460b57cec5SDimitry Andric  }
11470b57cec5SDimitry Andric
11480b57cec5SDimitry Andric  // Divide.
11490b57cec5SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1 in {
11500b57cec5SDimitry Andric    def VFD   : BinaryVRRcFloatGeneric<"vfd", 0xE7E5>;
11510b57cec5SDimitry Andric    def VFDDB : BinaryVRRc<"vfddb", 0xE7E5, any_fdiv, v128db, v128db, 3, 0>;
11525ffd83dbSDimitry Andric    def WFDDB : BinaryVRRc<"wfddb", 0xE7E5, any_fdiv, v64db, v64db, 3, 8, 0,
11535ffd83dbSDimitry Andric                           "ddbr">;
11540b57cec5SDimitry Andric    let Predicates = [FeatureVectorEnhancements1] in {
11550b57cec5SDimitry Andric      def VFDSB : BinaryVRRc<"vfdsb", 0xE7E5, any_fdiv, v128sb, v128sb, 2, 0>;
11565ffd83dbSDimitry Andric      def WFDSB : BinaryVRRc<"wfdsb", 0xE7E5, any_fdiv, v32sb, v32sb, 2, 8, 0,
11575ffd83dbSDimitry Andric                             "debr">;
11580b57cec5SDimitry Andric      def WFDXB : BinaryVRRc<"wfdxb", 0xE7E5, any_fdiv, v128xb, v128xb, 4, 8>;
11590b57cec5SDimitry Andric    }
11600b57cec5SDimitry Andric  }
11610b57cec5SDimitry Andric
11620b57cec5SDimitry Andric  // Load FP integer.
11630b57cec5SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1 in {
11640b57cec5SDimitry Andric    def VFI   : TernaryVRRaFloatGeneric<"vfi", 0xE7C7>;
11650b57cec5SDimitry Andric    def VFIDB : TernaryVRRa<"vfidb", 0xE7C7, int_s390_vfidb, v128db, v128db, 3, 0>;
11660b57cec5SDimitry Andric    def WFIDB : TernaryVRRa<"wfidb", 0xE7C7, null_frag, v64db, v64db, 3, 8>;
11670b57cec5SDimitry Andric  }
11680b57cec5SDimitry Andric  defm : VectorRounding<VFIDB, v128db>;
11690b57cec5SDimitry Andric  defm : VectorRounding<WFIDB, v64db>;
11700b57cec5SDimitry Andric  let Predicates = [FeatureVectorEnhancements1] in {
11710b57cec5SDimitry Andric    let Uses = [FPC], mayRaiseFPException = 1 in {
11720b57cec5SDimitry Andric      def VFISB : TernaryVRRa<"vfisb", 0xE7C7, int_s390_vfisb, v128sb, v128sb, 2, 0>;
11730b57cec5SDimitry Andric      def WFISB : TernaryVRRa<"wfisb", 0xE7C7, null_frag, v32sb, v32sb, 2, 8>;
11740b57cec5SDimitry Andric      def WFIXB : TernaryVRRa<"wfixb", 0xE7C7, null_frag, v128xb, v128xb, 4, 8>;
11750b57cec5SDimitry Andric    }
11760b57cec5SDimitry Andric    defm : VectorRounding<VFISB, v128sb>;
11770b57cec5SDimitry Andric    defm : VectorRounding<WFISB, v32sb>;
11780b57cec5SDimitry Andric    defm : VectorRounding<WFIXB, v128xb>;
11790b57cec5SDimitry Andric  }
11800b57cec5SDimitry Andric
11810b57cec5SDimitry Andric  // Load lengthened.
11820b57cec5SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1 in {
11830b57cec5SDimitry Andric    def VLDE  : UnaryVRRaFloatGeneric<"vlde", 0xE7C4>;
1184480093f4SDimitry Andric    def VLDEB : UnaryVRRa<"vldeb", 0xE7C4, z_any_vextend, v128db, v128sb, 2, 0>;
11855ffd83dbSDimitry Andric    def WLDEB : UnaryVRRa<"wldeb", 0xE7C4, any_fpextend, v64db, v32sb, 2, 8, 0,
11865ffd83dbSDimitry Andric                          "ldebr">;
11870b57cec5SDimitry Andric  }
11880b57cec5SDimitry Andric  let Predicates = [FeatureVectorEnhancements1] in {
11890b57cec5SDimitry Andric    let Uses = [FPC], mayRaiseFPException = 1 in {
11900b57cec5SDimitry Andric      let isAsmParserOnly = 1 in {
11910b57cec5SDimitry Andric        def VFLL  : UnaryVRRaFloatGeneric<"vfll", 0xE7C4>;
11920b57cec5SDimitry Andric        def VFLLS : UnaryVRRa<"vflls", 0xE7C4, null_frag, v128db, v128sb, 2, 0>;
11930b57cec5SDimitry Andric        def WFLLS : UnaryVRRa<"wflls", 0xE7C4, null_frag, v64db, v32sb, 2, 8>;
11940b57cec5SDimitry Andric      }
11950b57cec5SDimitry Andric      def WFLLD : UnaryVRRa<"wflld", 0xE7C4, any_fpextend, v128xb, v64db, 3, 8>;
11960b57cec5SDimitry Andric    }
11970b57cec5SDimitry Andric    def : Pat<(f128 (any_fpextend (f32 VR32:$src))),
11980b57cec5SDimitry Andric              (WFLLD (WLDEB VR32:$src))>;
11990b57cec5SDimitry Andric  }
12000b57cec5SDimitry Andric
12010b57cec5SDimitry Andric  // Load rounded.
12020b57cec5SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1 in {
12030b57cec5SDimitry Andric    def VLED  : TernaryVRRaFloatGeneric<"vled", 0xE7C5>;
12040b57cec5SDimitry Andric    def VLEDB : TernaryVRRa<"vledb", 0xE7C5, null_frag, v128sb, v128db, 3, 0>;
12050b57cec5SDimitry Andric    def WLEDB : TernaryVRRa<"wledb", 0xE7C5, null_frag, v32sb, v64db, 3, 8>;
12060b57cec5SDimitry Andric  }
1207480093f4SDimitry Andric  def : Pat<(v4f32 (z_any_vround (v2f64 VR128:$src))), (VLEDB VR128:$src, 0, 0)>;
12080b57cec5SDimitry Andric  def : FPConversion<WLEDB, any_fpround, v32sb, v64db, 0, 0>;
12090b57cec5SDimitry Andric  let Predicates = [FeatureVectorEnhancements1] in {
12100b57cec5SDimitry Andric    let Uses = [FPC], mayRaiseFPException = 1 in {
12110b57cec5SDimitry Andric      let isAsmParserOnly = 1 in {
12120b57cec5SDimitry Andric        def VFLR  : TernaryVRRaFloatGeneric<"vflr", 0xE7C5>;
12130b57cec5SDimitry Andric        def VFLRD : TernaryVRRa<"vflrd", 0xE7C5, null_frag, v128sb, v128db, 3, 0>;
12140b57cec5SDimitry Andric        def WFLRD : TernaryVRRa<"wflrd", 0xE7C5, null_frag, v32sb, v64db, 3, 8>;
12150b57cec5SDimitry Andric      }
12160b57cec5SDimitry Andric      def WFLRX : TernaryVRRa<"wflrx", 0xE7C5, null_frag, v64db, v128xb, 4, 8>;
12170b57cec5SDimitry Andric    }
12180b57cec5SDimitry Andric    def : FPConversion<WFLRX, any_fpround, v64db, v128xb, 0, 0>;
12190b57cec5SDimitry Andric    def : Pat<(f32 (any_fpround (f128 VR128:$src))),
12200b57cec5SDimitry Andric              (WLEDB (WFLRX VR128:$src, 0, 3), 0, 0)>;
12210b57cec5SDimitry Andric  }
12220b57cec5SDimitry Andric
12230b57cec5SDimitry Andric  // Maximum.
12240b57cec5SDimitry Andric  multiclass VectorMax<Instruction insn, TypedReg tr> {
12250b57cec5SDimitry Andric    def : FPMinMax<insn, any_fmaxnum, tr, 4>;
1226480093f4SDimitry Andric    def : FPMinMax<insn, any_fmaximum, tr, 1>;
12270b57cec5SDimitry Andric  }
12280b57cec5SDimitry Andric  let Predicates = [FeatureVectorEnhancements1] in {
12295ffd83dbSDimitry Andric    let Uses = [FPC], mayRaiseFPException = 1, isCommutable = 1 in {
12300b57cec5SDimitry Andric      def VFMAX   : TernaryVRRcFloatGeneric<"vfmax", 0xE7EF>;
12310b57cec5SDimitry Andric      def VFMAXDB : TernaryVRRcFloat<"vfmaxdb", 0xE7EF, int_s390_vfmaxdb,
12320b57cec5SDimitry Andric                                     v128db, v128db, 3, 0>;
12330b57cec5SDimitry Andric      def WFMAXDB : TernaryVRRcFloat<"wfmaxdb", 0xE7EF, null_frag,
12340b57cec5SDimitry Andric                                     v64db, v64db, 3, 8>;
12350b57cec5SDimitry Andric      def VFMAXSB : TernaryVRRcFloat<"vfmaxsb", 0xE7EF, int_s390_vfmaxsb,
12360b57cec5SDimitry Andric                                     v128sb, v128sb, 2, 0>;
12370b57cec5SDimitry Andric      def WFMAXSB : TernaryVRRcFloat<"wfmaxsb", 0xE7EF, null_frag,
12380b57cec5SDimitry Andric                                     v32sb, v32sb, 2, 8>;
12390b57cec5SDimitry Andric      def WFMAXXB : TernaryVRRcFloat<"wfmaxxb", 0xE7EF, null_frag,
12400b57cec5SDimitry Andric                                     v128xb, v128xb, 4, 8>;
12410b57cec5SDimitry Andric    }
12420b57cec5SDimitry Andric    defm : VectorMax<VFMAXDB, v128db>;
12430b57cec5SDimitry Andric    defm : VectorMax<WFMAXDB, v64db>;
12440b57cec5SDimitry Andric    defm : VectorMax<VFMAXSB, v128sb>;
12450b57cec5SDimitry Andric    defm : VectorMax<WFMAXSB, v32sb>;
12460b57cec5SDimitry Andric    defm : VectorMax<WFMAXXB, v128xb>;
12470b57cec5SDimitry Andric  }
12480b57cec5SDimitry Andric
12490b57cec5SDimitry Andric  // Minimum.
12500b57cec5SDimitry Andric  multiclass VectorMin<Instruction insn, TypedReg tr> {
12510b57cec5SDimitry Andric    def : FPMinMax<insn, any_fminnum, tr, 4>;
1252480093f4SDimitry Andric    def : FPMinMax<insn, any_fminimum, tr, 1>;
12530b57cec5SDimitry Andric  }
12540b57cec5SDimitry Andric  let Predicates = [FeatureVectorEnhancements1] in {
12555ffd83dbSDimitry Andric    let Uses = [FPC], mayRaiseFPException = 1, isCommutable = 1 in {
12560b57cec5SDimitry Andric      def VFMIN   : TernaryVRRcFloatGeneric<"vfmin", 0xE7EE>;
12570b57cec5SDimitry Andric      def VFMINDB : TernaryVRRcFloat<"vfmindb", 0xE7EE, int_s390_vfmindb,
12580b57cec5SDimitry Andric                                     v128db, v128db, 3, 0>;
12590b57cec5SDimitry Andric      def WFMINDB : TernaryVRRcFloat<"wfmindb", 0xE7EE, null_frag,
12600b57cec5SDimitry Andric                                     v64db, v64db, 3, 8>;
12610b57cec5SDimitry Andric      def VFMINSB : TernaryVRRcFloat<"vfminsb", 0xE7EE, int_s390_vfminsb,
12620b57cec5SDimitry Andric                                     v128sb, v128sb, 2, 0>;
12630b57cec5SDimitry Andric      def WFMINSB : TernaryVRRcFloat<"wfminsb", 0xE7EE, null_frag,
12640b57cec5SDimitry Andric                                     v32sb, v32sb, 2, 8>;
12650b57cec5SDimitry Andric      def WFMINXB : TernaryVRRcFloat<"wfminxb", 0xE7EE, null_frag,
12660b57cec5SDimitry Andric                                     v128xb, v128xb, 4, 8>;
12670b57cec5SDimitry Andric    }
12680b57cec5SDimitry Andric    defm : VectorMin<VFMINDB, v128db>;
12690b57cec5SDimitry Andric    defm : VectorMin<WFMINDB, v64db>;
12700b57cec5SDimitry Andric    defm : VectorMin<VFMINSB, v128sb>;
12710b57cec5SDimitry Andric    defm : VectorMin<WFMINSB, v32sb>;
12720b57cec5SDimitry Andric    defm : VectorMin<WFMINXB, v128xb>;
12730b57cec5SDimitry Andric  }
12740b57cec5SDimitry Andric
12750b57cec5SDimitry Andric  // Multiply.
12765ffd83dbSDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1, isCommutable = 1 in {
12770b57cec5SDimitry Andric    def VFM   : BinaryVRRcFloatGeneric<"vfm", 0xE7E7>;
12780b57cec5SDimitry Andric    def VFMDB : BinaryVRRc<"vfmdb", 0xE7E7, any_fmul, v128db, v128db, 3, 0>;
12795ffd83dbSDimitry Andric    def WFMDB : BinaryVRRc<"wfmdb", 0xE7E7, any_fmul, v64db, v64db, 3, 8, 0,
12805ffd83dbSDimitry Andric                           "mdbr">;
12810b57cec5SDimitry Andric    let Predicates = [FeatureVectorEnhancements1] in {
12820b57cec5SDimitry Andric      def VFMSB : BinaryVRRc<"vfmsb", 0xE7E7, any_fmul, v128sb, v128sb, 2, 0>;
12835ffd83dbSDimitry Andric      def WFMSB : BinaryVRRc<"wfmsb", 0xE7E7, any_fmul, v32sb, v32sb, 2, 8, 0,
12845ffd83dbSDimitry Andric                             "meebr">;
12850b57cec5SDimitry Andric      def WFMXB : BinaryVRRc<"wfmxb", 0xE7E7, any_fmul, v128xb, v128xb, 4, 8>;
12860b57cec5SDimitry Andric    }
12870b57cec5SDimitry Andric  }
12880b57cec5SDimitry Andric
12890b57cec5SDimitry Andric  // Multiply and add.
12905ffd83dbSDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1, isCommutable = 1 in {
12910b57cec5SDimitry Andric    def VFMA   : TernaryVRReFloatGeneric<"vfma", 0xE78F>;
12920b57cec5SDimitry Andric    def VFMADB : TernaryVRRe<"vfmadb", 0xE78F, any_fma, v128db, v128db, 0, 3>;
12935ffd83dbSDimitry Andric    def WFMADB : TernaryVRRe<"wfmadb", 0xE78F, any_fma, v64db, v64db, 8, 3,
12945ffd83dbSDimitry Andric                             "madbr">;
12950b57cec5SDimitry Andric    let Predicates = [FeatureVectorEnhancements1] in {
12960b57cec5SDimitry Andric      def VFMASB : TernaryVRRe<"vfmasb", 0xE78F, any_fma, v128sb, v128sb, 0, 2>;
12975ffd83dbSDimitry Andric      def WFMASB : TernaryVRRe<"wfmasb", 0xE78F, any_fma, v32sb, v32sb, 8, 2,
12985ffd83dbSDimitry Andric                               "maebr">;
12990b57cec5SDimitry Andric      def WFMAXB : TernaryVRRe<"wfmaxb", 0xE78F, any_fma, v128xb, v128xb, 8, 4>;
13000b57cec5SDimitry Andric    }
13010b57cec5SDimitry Andric  }
13020b57cec5SDimitry Andric
13030b57cec5SDimitry Andric  // Multiply and subtract.
13045ffd83dbSDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1, isCommutable = 1 in {
13050b57cec5SDimitry Andric    def VFMS   : TernaryVRReFloatGeneric<"vfms", 0xE78E>;
13060b57cec5SDimitry Andric    def VFMSDB : TernaryVRRe<"vfmsdb", 0xE78E, any_fms, v128db, v128db, 0, 3>;
13075ffd83dbSDimitry Andric    def WFMSDB : TernaryVRRe<"wfmsdb", 0xE78E, any_fms, v64db, v64db, 8, 3,
13085ffd83dbSDimitry Andric                             "msdbr">;
13090b57cec5SDimitry Andric    let Predicates = [FeatureVectorEnhancements1] in {
13100b57cec5SDimitry Andric      def VFMSSB : TernaryVRRe<"vfmssb", 0xE78E, any_fms, v128sb, v128sb, 0, 2>;
13115ffd83dbSDimitry Andric      def WFMSSB : TernaryVRRe<"wfmssb", 0xE78E, any_fms, v32sb, v32sb, 8, 2,
13125ffd83dbSDimitry Andric                               "msebr">;
13130b57cec5SDimitry Andric      def WFMSXB : TernaryVRRe<"wfmsxb", 0xE78E, any_fms, v128xb, v128xb, 8, 4>;
13140b57cec5SDimitry Andric    }
13150b57cec5SDimitry Andric  }
13160b57cec5SDimitry Andric
13170b57cec5SDimitry Andric  // Negative multiply and add.
13185ffd83dbSDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1, isCommutable = 1,
13190b57cec5SDimitry Andric      Predicates = [FeatureVectorEnhancements1] in {
13200b57cec5SDimitry Andric    def VFNMA   : TernaryVRReFloatGeneric<"vfnma", 0xE79F>;
13210b57cec5SDimitry Andric    def VFNMADB : TernaryVRRe<"vfnmadb", 0xE79F, any_fnma, v128db, v128db, 0, 3>;
13220b57cec5SDimitry Andric    def WFNMADB : TernaryVRRe<"wfnmadb", 0xE79F, any_fnma, v64db, v64db, 8, 3>;
13230b57cec5SDimitry Andric    def VFNMASB : TernaryVRRe<"vfnmasb", 0xE79F, any_fnma, v128sb, v128sb, 0, 2>;
13240b57cec5SDimitry Andric    def WFNMASB : TernaryVRRe<"wfnmasb", 0xE79F, any_fnma, v32sb, v32sb, 8, 2>;
13250b57cec5SDimitry Andric    def WFNMAXB : TernaryVRRe<"wfnmaxb", 0xE79F, any_fnma, v128xb, v128xb, 8, 4>;
13260b57cec5SDimitry Andric  }
13270b57cec5SDimitry Andric
13280b57cec5SDimitry Andric  // Negative multiply and subtract.
13295ffd83dbSDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1, isCommutable = 1,
13300b57cec5SDimitry Andric      Predicates = [FeatureVectorEnhancements1] in {
13310b57cec5SDimitry Andric    def VFNMS   : TernaryVRReFloatGeneric<"vfnms", 0xE79E>;
13320b57cec5SDimitry Andric    def VFNMSDB : TernaryVRRe<"vfnmsdb", 0xE79E, any_fnms, v128db, v128db, 0, 3>;
13330b57cec5SDimitry Andric    def WFNMSDB : TernaryVRRe<"wfnmsdb", 0xE79E, any_fnms, v64db, v64db, 8, 3>;
13340b57cec5SDimitry Andric    def VFNMSSB : TernaryVRRe<"vfnmssb", 0xE79E, any_fnms, v128sb, v128sb, 0, 2>;
13350b57cec5SDimitry Andric    def WFNMSSB : TernaryVRRe<"wfnmssb", 0xE79E, any_fnms, v32sb, v32sb, 8, 2>;
13360b57cec5SDimitry Andric    def WFNMSXB : TernaryVRRe<"wfnmsxb", 0xE79E, any_fnms, v128xb, v128xb, 8, 4>;
13370b57cec5SDimitry Andric  }
13380b57cec5SDimitry Andric
13390b57cec5SDimitry Andric  // Perform sign operation.
13400b57cec5SDimitry Andric  def VFPSO   : BinaryVRRaFloatGeneric<"vfpso", 0xE7CC>;
13410b57cec5SDimitry Andric  def VFPSODB : BinaryVRRa<"vfpsodb", 0xE7CC, null_frag, v128db, v128db, 3, 0>;
13420b57cec5SDimitry Andric  def WFPSODB : BinaryVRRa<"wfpsodb", 0xE7CC, null_frag, v64db, v64db, 3, 8>;
13430b57cec5SDimitry Andric  let Predicates = [FeatureVectorEnhancements1] in {
13440b57cec5SDimitry Andric    def VFPSOSB : BinaryVRRa<"vfpsosb", 0xE7CC, null_frag, v128sb, v128sb, 2, 0>;
13450b57cec5SDimitry Andric    def WFPSOSB : BinaryVRRa<"wfpsosb", 0xE7CC, null_frag, v32sb, v32sb, 2, 8>;
13460b57cec5SDimitry Andric    def WFPSOXB : BinaryVRRa<"wfpsoxb", 0xE7CC, null_frag, v128xb, v128xb, 4, 8>;
13470b57cec5SDimitry Andric  }
13480b57cec5SDimitry Andric
13490b57cec5SDimitry Andric  // Load complement.
13500b57cec5SDimitry Andric  def VFLCDB : UnaryVRRa<"vflcdb", 0xE7CC, fneg, v128db, v128db, 3, 0, 0>;
13510b57cec5SDimitry Andric  def WFLCDB : UnaryVRRa<"wflcdb", 0xE7CC, fneg, v64db, v64db, 3, 8, 0>;
13520b57cec5SDimitry Andric  let Predicates = [FeatureVectorEnhancements1] in {
13530b57cec5SDimitry Andric    def VFLCSB : UnaryVRRa<"vflcsb", 0xE7CC, fneg, v128sb, v128sb, 2, 0, 0>;
13540b57cec5SDimitry Andric    def WFLCSB : UnaryVRRa<"wflcsb", 0xE7CC, fneg, v32sb, v32sb, 2, 8, 0>;
13550b57cec5SDimitry Andric    def WFLCXB : UnaryVRRa<"wflcxb", 0xE7CC, fneg, v128xb, v128xb, 4, 8, 0>;
13560b57cec5SDimitry Andric  }
13570b57cec5SDimitry Andric
13580b57cec5SDimitry Andric  // Load negative.
13590b57cec5SDimitry Andric  def VFLNDB : UnaryVRRa<"vflndb", 0xE7CC, fnabs, v128db, v128db, 3, 0, 1>;
13600b57cec5SDimitry Andric  def WFLNDB : UnaryVRRa<"wflndb", 0xE7CC, fnabs, v64db, v64db, 3, 8, 1>;
13610b57cec5SDimitry Andric  let Predicates = [FeatureVectorEnhancements1] in {
13620b57cec5SDimitry Andric    def VFLNSB : UnaryVRRa<"vflnsb", 0xE7CC, fnabs, v128sb, v128sb, 2, 0, 1>;
13630b57cec5SDimitry Andric    def WFLNSB : UnaryVRRa<"wflnsb", 0xE7CC, fnabs, v32sb, v32sb, 2, 8, 1>;
13640b57cec5SDimitry Andric    def WFLNXB : UnaryVRRa<"wflnxb", 0xE7CC, fnabs, v128xb, v128xb, 4, 8, 1>;
13650b57cec5SDimitry Andric  }
13660b57cec5SDimitry Andric
13670b57cec5SDimitry Andric  // Load positive.
13680b57cec5SDimitry Andric  def VFLPDB : UnaryVRRa<"vflpdb", 0xE7CC, fabs, v128db, v128db, 3, 0, 2>;
13690b57cec5SDimitry Andric  def WFLPDB : UnaryVRRa<"wflpdb", 0xE7CC, fabs, v64db, v64db, 3, 8, 2>;
13700b57cec5SDimitry Andric  let Predicates = [FeatureVectorEnhancements1] in {
13710b57cec5SDimitry Andric    def VFLPSB : UnaryVRRa<"vflpsb", 0xE7CC, fabs, v128sb, v128sb, 2, 0, 2>;
13720b57cec5SDimitry Andric    def WFLPSB : UnaryVRRa<"wflpsb", 0xE7CC, fabs, v32sb, v32sb, 2, 8, 2>;
13730b57cec5SDimitry Andric    def WFLPXB : UnaryVRRa<"wflpxb", 0xE7CC, fabs, v128xb, v128xb, 4, 8, 2>;
13740b57cec5SDimitry Andric  }
13750b57cec5SDimitry Andric
13760b57cec5SDimitry Andric  // Square root.
13770b57cec5SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1 in {
13780b57cec5SDimitry Andric    def VFSQ   : UnaryVRRaFloatGeneric<"vfsq", 0xE7CE>;
13790b57cec5SDimitry Andric    def VFSQDB : UnaryVRRa<"vfsqdb", 0xE7CE, any_fsqrt, v128db, v128db, 3, 0>;
13805ffd83dbSDimitry Andric    def WFSQDB : UnaryVRRa<"wfsqdb", 0xE7CE, any_fsqrt, v64db, v64db, 3, 8, 0,
13815ffd83dbSDimitry Andric                           "sqdbr">;
13820b57cec5SDimitry Andric    let Predicates = [FeatureVectorEnhancements1] in {
13830b57cec5SDimitry Andric      def VFSQSB : UnaryVRRa<"vfsqsb", 0xE7CE, any_fsqrt, v128sb, v128sb, 2, 0>;
13845ffd83dbSDimitry Andric      def WFSQSB : UnaryVRRa<"wfsqsb", 0xE7CE, any_fsqrt, v32sb, v32sb, 2, 8, 0,
13855ffd83dbSDimitry Andric                             "sqebr">;
13860b57cec5SDimitry Andric      def WFSQXB : UnaryVRRa<"wfsqxb", 0xE7CE, any_fsqrt, v128xb, v128xb, 4, 8>;
13870b57cec5SDimitry Andric    }
13880b57cec5SDimitry Andric  }
13890b57cec5SDimitry Andric
13900b57cec5SDimitry Andric  // Subtract.
13910b57cec5SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1 in {
13920b57cec5SDimitry Andric    def VFS   : BinaryVRRcFloatGeneric<"vfs", 0xE7E2>;
13930b57cec5SDimitry Andric    def VFSDB : BinaryVRRc<"vfsdb", 0xE7E2, any_fsub, v128db, v128db, 3, 0>;
13945ffd83dbSDimitry Andric    def WFSDB : BinaryVRRc<"wfsdb", 0xE7E2, any_fsub, v64db, v64db, 3, 8, 0,
13955ffd83dbSDimitry Andric                           "sdbr">;
13960b57cec5SDimitry Andric    let Predicates = [FeatureVectorEnhancements1] in {
13970b57cec5SDimitry Andric      def VFSSB : BinaryVRRc<"vfssb", 0xE7E2, any_fsub, v128sb, v128sb, 2, 0>;
13985ffd83dbSDimitry Andric      def WFSSB : BinaryVRRc<"wfssb", 0xE7E2, any_fsub, v32sb, v32sb, 2, 8, 0,
13995ffd83dbSDimitry Andric                             "sebr">;
14000b57cec5SDimitry Andric      def WFSXB : BinaryVRRc<"wfsxb", 0xE7E2, any_fsub, v128xb, v128xb, 4, 8>;
14010b57cec5SDimitry Andric    }
14020b57cec5SDimitry Andric  }
14030b57cec5SDimitry Andric
14040b57cec5SDimitry Andric  // Test data class immediate.
14050b57cec5SDimitry Andric  let Defs = [CC] in {
14060b57cec5SDimitry Andric    def VFTCI   : BinaryVRIeFloatGeneric<"vftci", 0xE74A>;
14070b57cec5SDimitry Andric    def VFTCIDB : BinaryVRIe<"vftcidb", 0xE74A, z_vftci, v128g, v128db, 3, 0>;
14080b57cec5SDimitry Andric    def WFTCIDB : BinaryVRIe<"wftcidb", 0xE74A, null_frag, v64g, v64db, 3, 8>;
14090b57cec5SDimitry Andric    let Predicates = [FeatureVectorEnhancements1] in {
14100b57cec5SDimitry Andric      def VFTCISB : BinaryVRIe<"vftcisb", 0xE74A, z_vftci, v128f, v128sb, 2, 0>;
14110b57cec5SDimitry Andric      def WFTCISB : BinaryVRIe<"wftcisb", 0xE74A, null_frag, v32f, v32sb, 2, 8>;
14120b57cec5SDimitry Andric      def WFTCIXB : BinaryVRIe<"wftcixb", 0xE74A, null_frag, v128q, v128xb, 4, 8>;
14130b57cec5SDimitry Andric    }
14140b57cec5SDimitry Andric  }
14150b57cec5SDimitry Andric}
14160b57cec5SDimitry Andric
14170b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
14180b57cec5SDimitry Andric// Floating-point comparison
14190b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
14200b57cec5SDimitry Andric
14210b57cec5SDimitry Andriclet Predicates = [FeatureVector] in {
14220b57cec5SDimitry Andric  // Compare scalar.
14230b57cec5SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1, Defs = [CC] in {
14240b57cec5SDimitry Andric    def WFC   : CompareVRRaFloatGeneric<"wfc", 0xE7CB>;
14255ffd83dbSDimitry Andric    def WFCDB : CompareVRRa<"wfcdb", 0xE7CB, z_any_fcmp, v64db, 3, "cdbr">;
14260b57cec5SDimitry Andric    let Predicates = [FeatureVectorEnhancements1] in {
14275ffd83dbSDimitry Andric      def WFCSB : CompareVRRa<"wfcsb", 0xE7CB, z_any_fcmp, v32sb, 2, "cebr">;
1428480093f4SDimitry Andric      def WFCXB : CompareVRRa<"wfcxb", 0xE7CB, z_any_fcmp, v128xb, 4>;
14290b57cec5SDimitry Andric    }
14300b57cec5SDimitry Andric  }
14310b57cec5SDimitry Andric
14320b57cec5SDimitry Andric  // Compare and signal scalar.
14330b57cec5SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1, Defs = [CC] in {
14340b57cec5SDimitry Andric    def WFK   : CompareVRRaFloatGeneric<"wfk", 0xE7CA>;
14355ffd83dbSDimitry Andric    def WFKDB : CompareVRRa<"wfkdb", 0xE7CA, z_strict_fcmps, v64db, 3, "kdbr">;
14360b57cec5SDimitry Andric    let Predicates = [FeatureVectorEnhancements1] in {
14375ffd83dbSDimitry Andric      def WFKSB : CompareVRRa<"wfksb", 0xE7CA, z_strict_fcmps, v32sb, 2, "kebr">;
1438480093f4SDimitry Andric      def WFKXB : CompareVRRa<"wfkxb", 0xE7CA, z_strict_fcmps, v128xb, 4>;
14390b57cec5SDimitry Andric    }
14400b57cec5SDimitry Andric  }
14410b57cec5SDimitry Andric
14420b57cec5SDimitry Andric  // Compare equal.
14430b57cec5SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1 in {
14440b57cec5SDimitry Andric    def  VFCE   : BinaryVRRcSPairFloatGeneric<"vfce", 0xE7E8>;
1445480093f4SDimitry Andric    defm VFCEDB : BinaryVRRcSPair<"vfcedb", 0xE7E8, z_any_vfcmpe, z_vfcmpes,
14460b57cec5SDimitry Andric                                  v128g, v128db, 3, 0>;
14470b57cec5SDimitry Andric    defm WFCEDB : BinaryVRRcSPair<"wfcedb", 0xE7E8, null_frag, null_frag,
14480b57cec5SDimitry Andric                                  v64g, v64db, 3, 8>;
14490b57cec5SDimitry Andric    let Predicates = [FeatureVectorEnhancements1] in {
1450480093f4SDimitry Andric      defm VFCESB : BinaryVRRcSPair<"vfcesb", 0xE7E8, z_any_vfcmpe, z_vfcmpes,
14510b57cec5SDimitry Andric                                    v128f, v128sb, 2, 0>;
14520b57cec5SDimitry Andric      defm WFCESB : BinaryVRRcSPair<"wfcesb", 0xE7E8, null_frag, null_frag,
14530b57cec5SDimitry Andric                                    v32f, v32sb, 2, 8>;
14540b57cec5SDimitry Andric      defm WFCEXB : BinaryVRRcSPair<"wfcexb", 0xE7E8, null_frag, null_frag,
14550b57cec5SDimitry Andric                                    v128q, v128xb, 4, 8>;
14560b57cec5SDimitry Andric    }
14570b57cec5SDimitry Andric  }
14580b57cec5SDimitry Andric
14590b57cec5SDimitry Andric  // Compare and signal equal.
14600b57cec5SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1,
14610b57cec5SDimitry Andric      Predicates = [FeatureVectorEnhancements1] in {
1462480093f4SDimitry Andric    defm VFKEDB : BinaryVRRcSPair<"vfkedb", 0xE7E8, z_strict_vfcmpes, null_frag,
14630b57cec5SDimitry Andric                                  v128g, v128db, 3, 4>;
14640b57cec5SDimitry Andric    defm WFKEDB : BinaryVRRcSPair<"wfkedb", 0xE7E8, null_frag, null_frag,
14650b57cec5SDimitry Andric                                  v64g, v64db, 3, 12>;
1466480093f4SDimitry Andric    defm VFKESB : BinaryVRRcSPair<"vfkesb", 0xE7E8, z_strict_vfcmpes, null_frag,
14670b57cec5SDimitry Andric                                  v128f, v128sb, 2, 4>;
14680b57cec5SDimitry Andric    defm WFKESB : BinaryVRRcSPair<"wfkesb", 0xE7E8, null_frag, null_frag,
14690b57cec5SDimitry Andric                                  v32f, v32sb, 2, 12>;
14700b57cec5SDimitry Andric    defm WFKEXB : BinaryVRRcSPair<"wfkexb", 0xE7E8, null_frag, null_frag,
14710b57cec5SDimitry Andric                                  v128q, v128xb, 4, 12>;
14720b57cec5SDimitry Andric  }
14730b57cec5SDimitry Andric
14740b57cec5SDimitry Andric  // Compare high.
14750b57cec5SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1 in {
14760b57cec5SDimitry Andric    def  VFCH   : BinaryVRRcSPairFloatGeneric<"vfch", 0xE7EB>;
1477480093f4SDimitry Andric    defm VFCHDB : BinaryVRRcSPair<"vfchdb", 0xE7EB, z_any_vfcmph, z_vfcmphs,
14780b57cec5SDimitry Andric                                  v128g, v128db, 3, 0>;
14790b57cec5SDimitry Andric    defm WFCHDB : BinaryVRRcSPair<"wfchdb", 0xE7EB, null_frag, null_frag,
14800b57cec5SDimitry Andric                                  v64g, v64db, 3, 8>;
14810b57cec5SDimitry Andric    let Predicates = [FeatureVectorEnhancements1] in {
1482480093f4SDimitry Andric      defm VFCHSB : BinaryVRRcSPair<"vfchsb", 0xE7EB, z_any_vfcmph, z_vfcmphs,
14830b57cec5SDimitry Andric                                    v128f, v128sb, 2, 0>;
14840b57cec5SDimitry Andric      defm WFCHSB : BinaryVRRcSPair<"wfchsb", 0xE7EB, null_frag, null_frag,
14850b57cec5SDimitry Andric                                    v32f, v32sb, 2, 8>;
14860b57cec5SDimitry Andric      defm WFCHXB : BinaryVRRcSPair<"wfchxb", 0xE7EB, null_frag, null_frag,
14870b57cec5SDimitry Andric                                    v128q, v128xb, 4, 8>;
14880b57cec5SDimitry Andric    }
14890b57cec5SDimitry Andric  }
14900b57cec5SDimitry Andric
14910b57cec5SDimitry Andric  // Compare and signal high.
14920b57cec5SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1,
14930b57cec5SDimitry Andric      Predicates = [FeatureVectorEnhancements1] in {
1494480093f4SDimitry Andric    defm VFKHDB : BinaryVRRcSPair<"vfkhdb", 0xE7EB, z_strict_vfcmphs, null_frag,
14950b57cec5SDimitry Andric                                  v128g, v128db, 3, 4>;
14960b57cec5SDimitry Andric    defm WFKHDB : BinaryVRRcSPair<"wfkhdb", 0xE7EB, null_frag, null_frag,
14970b57cec5SDimitry Andric                                  v64g, v64db, 3, 12>;
1498480093f4SDimitry Andric    defm VFKHSB : BinaryVRRcSPair<"vfkhsb", 0xE7EB, z_strict_vfcmphs, null_frag,
14990b57cec5SDimitry Andric                                  v128f, v128sb, 2, 4>;
15000b57cec5SDimitry Andric    defm WFKHSB : BinaryVRRcSPair<"wfkhsb", 0xE7EB, null_frag, null_frag,
15010b57cec5SDimitry Andric                                  v32f, v32sb, 2, 12>;
15020b57cec5SDimitry Andric    defm WFKHXB : BinaryVRRcSPair<"wfkhxb", 0xE7EB, null_frag, null_frag,
15030b57cec5SDimitry Andric                                  v128q, v128xb, 4, 12>;
15040b57cec5SDimitry Andric  }
15050b57cec5SDimitry Andric
15060b57cec5SDimitry Andric  // Compare high or equal.
15070b57cec5SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1 in {
15080b57cec5SDimitry Andric    def  VFCHE   : BinaryVRRcSPairFloatGeneric<"vfche", 0xE7EA>;
1509480093f4SDimitry Andric    defm VFCHEDB : BinaryVRRcSPair<"vfchedb", 0xE7EA, z_any_vfcmphe, z_vfcmphes,
15100b57cec5SDimitry Andric                                   v128g, v128db, 3, 0>;
15110b57cec5SDimitry Andric    defm WFCHEDB : BinaryVRRcSPair<"wfchedb", 0xE7EA, null_frag, null_frag,
15120b57cec5SDimitry Andric                                   v64g, v64db, 3, 8>;
15130b57cec5SDimitry Andric    let Predicates = [FeatureVectorEnhancements1] in {
1514480093f4SDimitry Andric      defm VFCHESB : BinaryVRRcSPair<"vfchesb", 0xE7EA, z_any_vfcmphe, z_vfcmphes,
15150b57cec5SDimitry Andric                                     v128f, v128sb, 2, 0>;
15160b57cec5SDimitry Andric      defm WFCHESB : BinaryVRRcSPair<"wfchesb", 0xE7EA, null_frag, null_frag,
15170b57cec5SDimitry Andric                                     v32f, v32sb, 2, 8>;
15180b57cec5SDimitry Andric      defm WFCHEXB : BinaryVRRcSPair<"wfchexb", 0xE7EA, null_frag, null_frag,
15190b57cec5SDimitry Andric                                     v128q, v128xb, 4, 8>;
15200b57cec5SDimitry Andric    }
15210b57cec5SDimitry Andric  }
15220b57cec5SDimitry Andric
15230b57cec5SDimitry Andric  // Compare and signal high or equal.
15240b57cec5SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1,
15250b57cec5SDimitry Andric      Predicates = [FeatureVectorEnhancements1] in {
1526480093f4SDimitry Andric    defm VFKHEDB : BinaryVRRcSPair<"vfkhedb", 0xE7EA, z_strict_vfcmphes, null_frag,
15270b57cec5SDimitry Andric                                   v128g, v128db, 3, 4>;
15280b57cec5SDimitry Andric    defm WFKHEDB : BinaryVRRcSPair<"wfkhedb", 0xE7EA, null_frag, null_frag,
15290b57cec5SDimitry Andric                                   v64g, v64db, 3, 12>;
1530480093f4SDimitry Andric    defm VFKHESB : BinaryVRRcSPair<"vfkhesb", 0xE7EA, z_strict_vfcmphes, null_frag,
15310b57cec5SDimitry Andric                                   v128f, v128sb, 2, 4>;
15320b57cec5SDimitry Andric    defm WFKHESB : BinaryVRRcSPair<"wfkhesb", 0xE7EA, null_frag, null_frag,
15330b57cec5SDimitry Andric                                   v32f, v32sb, 2, 12>;
15340b57cec5SDimitry Andric    defm WFKHEXB : BinaryVRRcSPair<"wfkhexb", 0xE7EA, null_frag, null_frag,
15350b57cec5SDimitry Andric                                   v128q, v128xb, 4, 12>;
15360b57cec5SDimitry Andric  }
15370b57cec5SDimitry Andric}
15380b57cec5SDimitry Andric
15390b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
15405f757f3fSDimitry Andric// Support for 128-bit integer values in vector registers
15415f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
15425f757f3fSDimitry Andric
15435f757f3fSDimitry Andric// Loads and stores.
15445f757f3fSDimitry Andriclet Predicates = [FeatureVector] in {
15455f757f3fSDimitry Andric  def : Pat<(i128 (load bdxaddr12only:$addr)),
15465f757f3fSDimitry Andric            (VL bdxaddr12only:$addr)>;
15475f757f3fSDimitry Andric  def : Pat<(store (i128 VR128:$src), bdxaddr12only:$addr),
15485f757f3fSDimitry Andric            (VST VR128:$src, bdxaddr12only:$addr)>;
15495f757f3fSDimitry Andric}
15505f757f3fSDimitry Andric
15515f757f3fSDimitry Andric// Full i128 move from GPR pair.
15525f757f3fSDimitry Andriclet Predicates = [FeatureVector] in
15535f757f3fSDimitry Andric  def : Pat<(i128 (or (zext GR64:$x), (shl (anyext GR64:$y), (i32 64)))),
15545f757f3fSDimitry Andric            (VLVGP GR64:$y, GR64:$x)>;
15555f757f3fSDimitry Andric
15565f757f3fSDimitry Andric// Any-extensions from GPR to i128.
15575f757f3fSDimitry Andriclet Predicates = [FeatureVector] in {
15585f757f3fSDimitry Andric  def : Pat<(i128 (anyext GR32:$x)), (VLVGP32 GR32:$x, GR32:$x)>;
15595f757f3fSDimitry Andric  def : Pat<(i128 (anyext GR64:$x)), (VLVGP GR64:$x, GR64:$x)>;
15605f757f3fSDimitry Andric}
15615f757f3fSDimitry Andric
15625f757f3fSDimitry Andric// Any-extending loads into i128.
15635f757f3fSDimitry Andriclet Predicates = [FeatureVector] in {
1564*0fca6ea1SDimitry Andric  def : Pat<(i128 (z_extloadi8 bdxaddr12only:$addr)),
15655f757f3fSDimitry Andric            (VLREPB bdxaddr12only:$addr)>;
1566*0fca6ea1SDimitry Andric  def : Pat<(i128 (z_extloadi16 bdxaddr12only:$addr)),
15675f757f3fSDimitry Andric            (VLREPH bdxaddr12only:$addr)>;
1568*0fca6ea1SDimitry Andric  def : Pat<(i128 (z_extloadi32 bdxaddr12only:$addr)),
15695f757f3fSDimitry Andric            (VLREPF bdxaddr12only:$addr)>;
1570*0fca6ea1SDimitry Andric  def : Pat<(i128 (z_extloadi64 bdxaddr12only:$addr)),
15715f757f3fSDimitry Andric            (VLREPG bdxaddr12only:$addr)>;
15725f757f3fSDimitry Andric}
15735f757f3fSDimitry Andric
15745f757f3fSDimitry Andric// Truncations from i128 to GPR.
15755f757f3fSDimitry Andriclet Predicates = [FeatureVector] in {
15765f757f3fSDimitry Andric  def : Pat<(i32 (trunc (i128 VR128:$vec))),
15775f757f3fSDimitry Andric            (EXTRACT_SUBREG (VLGVF VR128:$vec, zero_reg, 3), subreg_l32)>;
15785f757f3fSDimitry Andric  def : Pat<(i32 (trunc (srl (i128 VR128:$vec), (i32 32)))),
15795f757f3fSDimitry Andric            (EXTRACT_SUBREG (VLGVF VR128:$vec, zero_reg, 2), subreg_l32)>;
15805f757f3fSDimitry Andric  def : Pat<(i32 (trunc (srl (i128 VR128:$vec), (i32 64)))),
15815f757f3fSDimitry Andric            (EXTRACT_SUBREG (VLGVF VR128:$vec, zero_reg, 1), subreg_l32)>;
15825f757f3fSDimitry Andric  def : Pat<(i32 (trunc (srl (i128 VR128:$vec), (i32 96)))),
15835f757f3fSDimitry Andric            (EXTRACT_SUBREG (VLGVF VR128:$vec, zero_reg, 0), subreg_l32)>;
15845f757f3fSDimitry Andric  def : Pat<(i64 (trunc (i128 VR128:$vec))),
15855f757f3fSDimitry Andric            (VLGVG VR128:$vec, zero_reg, 1)>;
15865f757f3fSDimitry Andric  def : Pat<(i64 (trunc (srl (i128 VR128:$vec), (i32 64)))),
15875f757f3fSDimitry Andric            (VLGVG VR128:$vec, zero_reg, 0)>;
15885f757f3fSDimitry Andric}
15895f757f3fSDimitry Andric
15905f757f3fSDimitry Andric// Truncating stores from i128.
15915f757f3fSDimitry Andriclet Predicates = [FeatureVector] in {
15925f757f3fSDimitry Andric  def : Pat<(truncstorei8 (i128 VR128:$x), bdxaddr12only:$addr),
15935f757f3fSDimitry Andric            (VSTEB VR128:$x, bdxaddr12only:$addr, 15)>;
15945f757f3fSDimitry Andric  def : Pat<(truncstorei16 (i128 VR128:$x), bdxaddr12only:$addr),
15955f757f3fSDimitry Andric            (VSTEH VR128:$x, bdxaddr12only:$addr, 7)>;
15965f757f3fSDimitry Andric  def : Pat<(truncstorei32 (i128 VR128:$x), bdxaddr12only:$addr),
15975f757f3fSDimitry Andric            (VSTEF VR128:$x, bdxaddr12only:$addr, 3)>;
15985f757f3fSDimitry Andric  def : Pat<(truncstorei32 (srl (i128 VR128:$x), (i32 32)), bdxaddr12only:$addr),
15995f757f3fSDimitry Andric            (VSTEF VR128:$x, bdxaddr12only:$addr, 2)>;
16005f757f3fSDimitry Andric  def : Pat<(truncstorei32 (srl (i128 VR128:$x), (i32 64)), bdxaddr12only:$addr),
16015f757f3fSDimitry Andric            (VSTEF VR128:$x, bdxaddr12only:$addr, 1)>;
16025f757f3fSDimitry Andric  def : Pat<(truncstorei32 (srl (i128 VR128:$x), (i32 96)), bdxaddr12only:$addr),
16035f757f3fSDimitry Andric            (VSTEF VR128:$x, bdxaddr12only:$addr, 0)>;
16045f757f3fSDimitry Andric  def : Pat<(truncstorei64 (i128 VR128:$x), bdxaddr12only:$addr),
16055f757f3fSDimitry Andric            (VSTEG VR128:$x, bdxaddr12only:$addr, 1)>;
16065f757f3fSDimitry Andric  def : Pat<(truncstorei64 (srl (i128 VR128:$x), (i32 64)), bdxaddr12only:$addr),
16075f757f3fSDimitry Andric            (VSTEG VR128:$x, bdxaddr12only:$addr, 0)>;
16085f757f3fSDimitry Andric}
16095f757f3fSDimitry Andric
16105f757f3fSDimitry Andric// Zero-extensions from GPR to i128.
16115f757f3fSDimitry Andriclet Predicates = [FeatureVector] in {
16125f757f3fSDimitry Andric  def : Pat<(i128 (zext8 (anyext GR32:$x))),
16135f757f3fSDimitry Andric            (VLVGB (VGBM 0), GR32:$x, zero_reg, 15)>;
16145f757f3fSDimitry Andric  def : Pat<(i128 (zext16 (anyext GR32:$x))),
16155f757f3fSDimitry Andric            (VLVGH (VGBM 0), GR32:$x, zero_reg, 7)>;
16165f757f3fSDimitry Andric  def : Pat<(i128 (zext GR32:$x)),
16175f757f3fSDimitry Andric            (VLVGF (VGBM 0), GR32:$x, zero_reg, 3)>;
16185f757f3fSDimitry Andric  def : Pat<(i128 (zext GR64:$x)),
16195f757f3fSDimitry Andric            (VLVGG (VGBM 0), GR64:$x, zero_reg, 1)>;
16205f757f3fSDimitry Andric}
16215f757f3fSDimitry Andric
16225f757f3fSDimitry Andric// Zero-extending loads into i128.
16235f757f3fSDimitry Andriclet Predicates = [FeatureVector] in {
1624*0fca6ea1SDimitry Andric  def : Pat<(i128 (z_zextloadi8 bdxaddr12only:$addr)),
16255f757f3fSDimitry Andric            (VLEB (VGBM 0), bdxaddr12only:$addr, 15)>;
1626*0fca6ea1SDimitry Andric  def : Pat<(i128 (z_zextloadi16 bdxaddr12only:$addr)),
16275f757f3fSDimitry Andric            (VLEH (VGBM 0), bdxaddr12only:$addr, 7)>;
1628*0fca6ea1SDimitry Andric  def : Pat<(i128 (z_zextloadi32 bdxaddr12only:$addr)),
16295f757f3fSDimitry Andric            (VLEF (VGBM 0), bdxaddr12only:$addr, 3)>;
1630*0fca6ea1SDimitry Andric  def : Pat<(i128 (z_zextloadi64 bdxaddr12only:$addr)),
16315f757f3fSDimitry Andric            (VLEG (VGBM 0), bdxaddr12only:$addr, 1)>;
16325f757f3fSDimitry Andric}
16335f757f3fSDimitry Andric
16345f757f3fSDimitry Andric// In-register i128 sign-extensions.
16355f757f3fSDimitry Andriclet Predicates = [FeatureVector] in {
16365f757f3fSDimitry Andric  def : Pat<(i128 (sext_inreg VR128:$x, i8)),
16375f757f3fSDimitry Andric            (VSRAB (VREPB VR128:$x, 15), (VREPIB 120))>;
16385f757f3fSDimitry Andric  def : Pat<(i128 (sext_inreg VR128:$x, i16)),
16395f757f3fSDimitry Andric            (VSRAB (VREPH VR128:$x, 7), (VREPIB 112))>;
16405f757f3fSDimitry Andric  def : Pat<(i128 (sext_inreg VR128:$x, i32)),
16415f757f3fSDimitry Andric            (VSRAB (VREPF VR128:$x, 3), (VREPIB 96))>;
16425f757f3fSDimitry Andric  def : Pat<(i128 (sext_inreg VR128:$x, i64)),
16435f757f3fSDimitry Andric            (VSRAB (VREPG VR128:$x, 1), (VREPIB 64))>;
16445f757f3fSDimitry Andric}
16455f757f3fSDimitry Andric
16465f757f3fSDimitry Andric// Sign-extensions from GPR to i128.
16475f757f3fSDimitry Andriclet Predicates = [FeatureVector] in {
16485f757f3fSDimitry Andric  def : Pat<(i128 (sext_inreg (anyext GR32:$x), i8)),
16495f757f3fSDimitry Andric            (VLVGP (SRAG (LGBR (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
16505f757f3fSDimitry Andric                                 GR32:$x, subreg_l32)), zero_reg, 63),
16515f757f3fSDimitry Andric                   (LGBR (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
16525f757f3fSDimitry Andric                            GR32:$x, subreg_l32)))>;
16535f757f3fSDimitry Andric  def : Pat<(i128 (sext_inreg (anyext GR32:$x), i16)),
16545f757f3fSDimitry Andric            (VLVGP (SRAG (LGHR (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
16555f757f3fSDimitry Andric                                  GR32:$x, subreg_l32)), zero_reg, 63),
16565f757f3fSDimitry Andric                   (LGHR (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
16575f757f3fSDimitry Andric                            GR32:$x, subreg_l32)))>;
16585f757f3fSDimitry Andric  def : Pat<(i128 (sext GR32:$x)),
16595f757f3fSDimitry Andric            (VLVGP (SRAG (LGFR GR32:$x), zero_reg, 63), (LGFR GR32:$x))>;
16605f757f3fSDimitry Andric  def : Pat<(i128 (sext GR64:$x)),
16615f757f3fSDimitry Andric            (VLVGP (SRAG GR64:$x, zero_reg, 63), GR64:$x)>;
16625f757f3fSDimitry Andric}
16635f757f3fSDimitry Andric
16645f757f3fSDimitry Andric// Sign-extending loads into i128.
16655f757f3fSDimitry Andriclet Predicates = [FeatureVector] in {
1666*0fca6ea1SDimitry Andric  def : Pat<(i128 (z_sextloadi8 bdxaddr12only:$addr)),
16675f757f3fSDimitry Andric            (VSRAB (VLREPB bdxaddr12only:$addr), (VREPIB 120))>;
1668*0fca6ea1SDimitry Andric  def : Pat<(i128 (z_sextloadi16 bdxaddr12only:$addr)),
16695f757f3fSDimitry Andric            (VSRAB (VLREPH bdxaddr12only:$addr), (VREPIB 112))>;
1670*0fca6ea1SDimitry Andric  def : Pat<(i128 (z_sextloadi32 bdxaddr12only:$addr)),
16715f757f3fSDimitry Andric            (VSRAB (VLREPF bdxaddr12only:$addr), (VREPIB 96))>;
1672*0fca6ea1SDimitry Andric  def : Pat<(i128 (z_sextloadi64 bdxaddr12only:$addr)),
16735f757f3fSDimitry Andric            (VSRAB (VLREPG bdxaddr12only:$addr), (VREPIB 64))>;
16745f757f3fSDimitry Andric}
16755f757f3fSDimitry Andric
16765f757f3fSDimitry Andric// i128 comparison pseudo-instructions.
16775f757f3fSDimitry Andriclet Predicates = [FeatureVector], Defs = [CC],
16785f757f3fSDimitry Andric    usesCustomInserter = 1, hasNoSchedulingInfo = 1 in {
16795f757f3fSDimitry Andric  def SCmp128Hi : Pseudo<(outs), (ins VR128:$src1, VR128:$src2),
16805f757f3fSDimitry Andric                         [(set CC, (z_scmp128hi (i128 VR128:$src1),
16815f757f3fSDimitry Andric                                                (i128 VR128:$src2)))]>;
16825f757f3fSDimitry Andric  def UCmp128Hi : Pseudo<(outs), (ins VR128:$src1, VR128:$src2),
16835f757f3fSDimitry Andric                         [(set CC, (z_ucmp128hi (i128 VR128:$src1),
16845f757f3fSDimitry Andric                                                (i128 VR128:$src2)))]>;
16855f757f3fSDimitry Andric}
16865f757f3fSDimitry Andric
16875f757f3fSDimitry Andric// i128 select pseudo-instructions.
16885f757f3fSDimitry Andriclet Predicates = [FeatureVector] in
16895f757f3fSDimitry Andric  def Select128 : SelectWrapper<i128, VR128>;
16905f757f3fSDimitry Andric
16915f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
16920b57cec5SDimitry Andric// Conversions
16930b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
16940b57cec5SDimitry Andric
1695*0fca6ea1SDimitry Andriclet Predicates = [FeatureVector] in {
16960b57cec5SDimitry Andricdef : Pat<(v16i8 (bitconvert (v8i16 VR128:$src))), (v16i8 VR128:$src)>;
16970b57cec5SDimitry Andricdef : Pat<(v16i8 (bitconvert (v4i32 VR128:$src))), (v16i8 VR128:$src)>;
16980b57cec5SDimitry Andricdef : Pat<(v16i8 (bitconvert (v2i64 VR128:$src))), (v16i8 VR128:$src)>;
16995f757f3fSDimitry Andricdef : Pat<(v16i8 (bitconvert (i128  VR128:$src))), (v16i8 VR128:$src)>;
17000b57cec5SDimitry Andricdef : Pat<(v16i8 (bitconvert (v4f32 VR128:$src))), (v16i8 VR128:$src)>;
17010b57cec5SDimitry Andricdef : Pat<(v16i8 (bitconvert (v2f64 VR128:$src))), (v16i8 VR128:$src)>;
17020b57cec5SDimitry Andricdef : Pat<(v16i8 (bitconvert (f128  VR128:$src))), (v16i8 VR128:$src)>;
17030b57cec5SDimitry Andric
17040b57cec5SDimitry Andricdef : Pat<(v8i16 (bitconvert (v16i8 VR128:$src))), (v8i16 VR128:$src)>;
17050b57cec5SDimitry Andricdef : Pat<(v8i16 (bitconvert (v4i32 VR128:$src))), (v8i16 VR128:$src)>;
17060b57cec5SDimitry Andricdef : Pat<(v8i16 (bitconvert (v2i64 VR128:$src))), (v8i16 VR128:$src)>;
17075f757f3fSDimitry Andricdef : Pat<(v8i16 (bitconvert (i128  VR128:$src))), (v8i16 VR128:$src)>;
17080b57cec5SDimitry Andricdef : Pat<(v8i16 (bitconvert (v4f32 VR128:$src))), (v8i16 VR128:$src)>;
17090b57cec5SDimitry Andricdef : Pat<(v8i16 (bitconvert (v2f64 VR128:$src))), (v8i16 VR128:$src)>;
17100b57cec5SDimitry Andricdef : Pat<(v8i16 (bitconvert (f128  VR128:$src))), (v8i16 VR128:$src)>;
17110b57cec5SDimitry Andric
17120b57cec5SDimitry Andricdef : Pat<(v4i32 (bitconvert (v16i8 VR128:$src))), (v4i32 VR128:$src)>;
17130b57cec5SDimitry Andricdef : Pat<(v4i32 (bitconvert (v8i16 VR128:$src))), (v4i32 VR128:$src)>;
17140b57cec5SDimitry Andricdef : Pat<(v4i32 (bitconvert (v2i64 VR128:$src))), (v4i32 VR128:$src)>;
17155f757f3fSDimitry Andricdef : Pat<(v4i32 (bitconvert (i128  VR128:$src))), (v4i32 VR128:$src)>;
17160b57cec5SDimitry Andricdef : Pat<(v4i32 (bitconvert (v4f32 VR128:$src))), (v4i32 VR128:$src)>;
17170b57cec5SDimitry Andricdef : Pat<(v4i32 (bitconvert (v2f64 VR128:$src))), (v4i32 VR128:$src)>;
17180b57cec5SDimitry Andricdef : Pat<(v4i32 (bitconvert (f128  VR128:$src))), (v4i32 VR128:$src)>;
17190b57cec5SDimitry Andric
17200b57cec5SDimitry Andricdef : Pat<(v2i64 (bitconvert (v16i8 VR128:$src))), (v2i64 VR128:$src)>;
17210b57cec5SDimitry Andricdef : Pat<(v2i64 (bitconvert (v8i16 VR128:$src))), (v2i64 VR128:$src)>;
17220b57cec5SDimitry Andricdef : Pat<(v2i64 (bitconvert (v4i32 VR128:$src))), (v2i64 VR128:$src)>;
17235f757f3fSDimitry Andricdef : Pat<(v2i64 (bitconvert (i128  VR128:$src))), (v2i64 VR128:$src)>;
17240b57cec5SDimitry Andricdef : Pat<(v2i64 (bitconvert (v4f32 VR128:$src))), (v2i64 VR128:$src)>;
17250b57cec5SDimitry Andricdef : Pat<(v2i64 (bitconvert (v2f64 VR128:$src))), (v2i64 VR128:$src)>;
17260b57cec5SDimitry Andricdef : Pat<(v2i64 (bitconvert (f128  VR128:$src))), (v2i64 VR128:$src)>;
17270b57cec5SDimitry Andric
17280b57cec5SDimitry Andricdef : Pat<(v4f32 (bitconvert (v16i8 VR128:$src))), (v4f32 VR128:$src)>;
17290b57cec5SDimitry Andricdef : Pat<(v4f32 (bitconvert (v8i16 VR128:$src))), (v4f32 VR128:$src)>;
17300b57cec5SDimitry Andricdef : Pat<(v4f32 (bitconvert (v4i32 VR128:$src))), (v4f32 VR128:$src)>;
17315f757f3fSDimitry Andricdef : Pat<(v4f32 (bitconvert (i128  VR128:$src))), (v4f32 VR128:$src)>;
17320b57cec5SDimitry Andricdef : Pat<(v4f32 (bitconvert (v2i64 VR128:$src))), (v4f32 VR128:$src)>;
17330b57cec5SDimitry Andricdef : Pat<(v4f32 (bitconvert (v2f64 VR128:$src))), (v4f32 VR128:$src)>;
17340b57cec5SDimitry Andricdef : Pat<(v4f32 (bitconvert (f128  VR128:$src))), (v4f32 VR128:$src)>;
17350b57cec5SDimitry Andric
17360b57cec5SDimitry Andricdef : Pat<(v2f64 (bitconvert (v16i8 VR128:$src))), (v2f64 VR128:$src)>;
17370b57cec5SDimitry Andricdef : Pat<(v2f64 (bitconvert (v8i16 VR128:$src))), (v2f64 VR128:$src)>;
17380b57cec5SDimitry Andricdef : Pat<(v2f64 (bitconvert (v4i32 VR128:$src))), (v2f64 VR128:$src)>;
17395f757f3fSDimitry Andricdef : Pat<(v2f64 (bitconvert (i128  VR128:$src))), (v2f64 VR128:$src)>;
17400b57cec5SDimitry Andricdef : Pat<(v2f64 (bitconvert (v2i64 VR128:$src))), (v2f64 VR128:$src)>;
17410b57cec5SDimitry Andricdef : Pat<(v2f64 (bitconvert (v4f32 VR128:$src))), (v2f64 VR128:$src)>;
17420b57cec5SDimitry Andricdef : Pat<(v2f64 (bitconvert (f128  VR128:$src))), (v2f64 VR128:$src)>;
17430b57cec5SDimitry Andric
17440b57cec5SDimitry Andricdef : Pat<(f128  (bitconvert (v16i8 VR128:$src))), (f128  VR128:$src)>;
17450b57cec5SDimitry Andricdef : Pat<(f128  (bitconvert (v8i16 VR128:$src))), (f128  VR128:$src)>;
17460b57cec5SDimitry Andricdef : Pat<(f128  (bitconvert (v4i32 VR128:$src))), (f128  VR128:$src)>;
17470b57cec5SDimitry Andricdef : Pat<(f128  (bitconvert (v2i64 VR128:$src))), (f128  VR128:$src)>;
17485f757f3fSDimitry Andricdef : Pat<(f128  (bitconvert (i128  VR128:$src))), (f128  VR128:$src)>;
17490b57cec5SDimitry Andricdef : Pat<(f128  (bitconvert (v4f32 VR128:$src))), (f128  VR128:$src)>;
17500b57cec5SDimitry Andricdef : Pat<(f128  (bitconvert (v2f64 VR128:$src))), (f128  VR128:$src)>;
17510b57cec5SDimitry Andric
17525f757f3fSDimitry Andricdef : Pat<(i128  (bitconvert (v16i8 VR128:$src))), (i128  VR128:$src)>;
17535f757f3fSDimitry Andricdef : Pat<(i128  (bitconvert (v8i16 VR128:$src))), (i128  VR128:$src)>;
17545f757f3fSDimitry Andricdef : Pat<(i128  (bitconvert (v4i32 VR128:$src))), (i128  VR128:$src)>;
17555f757f3fSDimitry Andricdef : Pat<(i128  (bitconvert (v2i64 VR128:$src))), (i128  VR128:$src)>;
17565f757f3fSDimitry Andricdef : Pat<(i128  (bitconvert (v4f32 VR128:$src))), (i128  VR128:$src)>;
17575f757f3fSDimitry Andricdef : Pat<(i128  (bitconvert (v2f64 VR128:$src))), (i128  VR128:$src)>;
17585f757f3fSDimitry Andricdef : Pat<(i128  (bitconvert (f128  VR128:$src))), (i128  VR128:$src)>;
1759*0fca6ea1SDimitry Andric} // End Predicates = [FeatureVector]
17605f757f3fSDimitry Andric
17610b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
17620b57cec5SDimitry Andric// Replicating scalars
17630b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
17640b57cec5SDimitry Andric
17650b57cec5SDimitry Andric// Define patterns for replicating a scalar GR32 into a vector of type TYPE.
17660b57cec5SDimitry Andric// INDEX is 8 minus the element size in bytes.
17670b57cec5SDimitry Andricclass VectorReplicateScalar<ValueType type, Instruction insn, bits<16> index>
17680b57cec5SDimitry Andric  : Pat<(type (z_replicate GR32:$scalar)),
17690b57cec5SDimitry Andric        (insn (VLVGP32 GR32:$scalar, GR32:$scalar), index)>;
17700b57cec5SDimitry Andric
17710b57cec5SDimitry Andricdef : VectorReplicateScalar<v16i8, VREPB, 7>;
17720b57cec5SDimitry Andricdef : VectorReplicateScalar<v8i16, VREPH, 3>;
17730b57cec5SDimitry Andricdef : VectorReplicateScalar<v4i32, VREPF, 1>;
17740b57cec5SDimitry Andric
17755ffd83dbSDimitry Andric// i64 replications are just a single instruction.
17760b57cec5SDimitry Andricdef : Pat<(v2i64 (z_replicate GR64:$scalar)),
17770b57cec5SDimitry Andric          (VLVGP GR64:$scalar, GR64:$scalar)>;
17780b57cec5SDimitry Andric
17790b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
17800b57cec5SDimitry Andric// Floating-point insertion and extraction
17810b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
17820b57cec5SDimitry Andric
17830b57cec5SDimitry Andric// Moving 32-bit values between GPRs and FPRs can be done using VLVGF
17840b57cec5SDimitry Andric// and VLGVF.
17850b57cec5SDimitry Andriclet Predicates = [FeatureVector] in {
17860b57cec5SDimitry Andric  def LEFR : UnaryAliasVRS<VR32, GR32>;
17870b57cec5SDimitry Andric  def LFER : UnaryAliasVRS<GR64, VR32>;
17880b57cec5SDimitry Andric  def : Pat<(f32 (bitconvert (i32 GR32:$src))), (LEFR GR32:$src)>;
17890b57cec5SDimitry Andric  def : Pat<(i32 (bitconvert (f32 VR32:$src))),
17900b57cec5SDimitry Andric            (EXTRACT_SUBREG (LFER VR32:$src), subreg_l32)>;
17910b57cec5SDimitry Andric}
17920b57cec5SDimitry Andric
17930b57cec5SDimitry Andric// Floating-point values are stored in element 0 of the corresponding
17940b57cec5SDimitry Andric// vector register.  Scalar to vector conversion is just a subreg and
17950b57cec5SDimitry Andric// scalar replication can just replicate element 0 of the vector register.
17960b57cec5SDimitry Andricmulticlass ScalarToVectorFP<Instruction vrep, ValueType vt, RegisterOperand cls,
17970b57cec5SDimitry Andric                            SubRegIndex subreg> {
17980b57cec5SDimitry Andric  def : Pat<(vt (scalar_to_vector cls:$scalar)),
17990b57cec5SDimitry Andric            (INSERT_SUBREG (vt (IMPLICIT_DEF)), cls:$scalar, subreg)>;
18000b57cec5SDimitry Andric  def : Pat<(vt (z_replicate cls:$scalar)),
18010b57cec5SDimitry Andric            (vrep (INSERT_SUBREG (vt (IMPLICIT_DEF)), cls:$scalar,
18020b57cec5SDimitry Andric                                 subreg), 0)>;
18030b57cec5SDimitry Andric}
18040b57cec5SDimitry Andricdefm : ScalarToVectorFP<VREPF, v4f32, FP32, subreg_h32>;
18050b57cec5SDimitry Andricdefm : ScalarToVectorFP<VREPG, v2f64, FP64, subreg_h64>;
18060b57cec5SDimitry Andric
18070b57cec5SDimitry Andric// Match v2f64 insertions.  The AddedComplexity counters the 3 added by
18080b57cec5SDimitry Andric// TableGen for the base register operand in VLVG-based integer insertions
18090b57cec5SDimitry Andric// and ensures that this version is strictly better.
18100b57cec5SDimitry Andriclet AddedComplexity = 4 in {
18110b57cec5SDimitry Andric  def : Pat<(z_vector_insert (v2f64 VR128:$vec), FP64:$elt, 0),
18120b57cec5SDimitry Andric            (VPDI (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FP64:$elt,
18130b57cec5SDimitry Andric                                 subreg_h64), VR128:$vec, 1)>;
18140b57cec5SDimitry Andric  def : Pat<(z_vector_insert (v2f64 VR128:$vec), FP64:$elt, 1),
18150b57cec5SDimitry Andric            (VPDI VR128:$vec, (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FP64:$elt,
18160b57cec5SDimitry Andric                                             subreg_h64), 0)>;
18170b57cec5SDimitry Andric}
18180b57cec5SDimitry Andric
18190b57cec5SDimitry Andric// We extract floating-point element X by replicating (for elements other
18200b57cec5SDimitry Andric// than 0) and then taking a high subreg.  The AddedComplexity counters the
18210b57cec5SDimitry Andric// 3 added by TableGen for the base register operand in VLGV-based integer
18220b57cec5SDimitry Andric// extractions and ensures that this version is strictly better.
18230b57cec5SDimitry Andriclet AddedComplexity = 4 in {
18240b57cec5SDimitry Andric  def : Pat<(f32 (z_vector_extract (v4f32 VR128:$vec), 0)),
18250b57cec5SDimitry Andric            (EXTRACT_SUBREG VR128:$vec, subreg_h32)>;
18260b57cec5SDimitry Andric  def : Pat<(f32 (z_vector_extract (v4f32 VR128:$vec), imm32zx2:$index)),
18270b57cec5SDimitry Andric            (EXTRACT_SUBREG (VREPF VR128:$vec, imm32zx2:$index), subreg_h32)>;
18280b57cec5SDimitry Andric
18290b57cec5SDimitry Andric  def : Pat<(f64 (z_vector_extract (v2f64 VR128:$vec), 0)),
18300b57cec5SDimitry Andric            (EXTRACT_SUBREG VR128:$vec, subreg_h64)>;
18310b57cec5SDimitry Andric  def : Pat<(f64 (z_vector_extract (v2f64 VR128:$vec), imm32zx1:$index)),
18320b57cec5SDimitry Andric            (EXTRACT_SUBREG (VREPG VR128:$vec, imm32zx1:$index), subreg_h64)>;
18330b57cec5SDimitry Andric}
18340b57cec5SDimitry Andric
18350b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
18360b57cec5SDimitry Andric// Support for 128-bit floating-point values in vector registers
18370b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
18380b57cec5SDimitry Andric
18390b57cec5SDimitry Andriclet Predicates = [FeatureVectorEnhancements1] in {
18400b57cec5SDimitry Andric  def : Pat<(f128 (load bdxaddr12only:$addr)),
18410b57cec5SDimitry Andric            (VL bdxaddr12only:$addr)>;
18420b57cec5SDimitry Andric  def : Pat<(store (f128 VR128:$src), bdxaddr12only:$addr),
18430b57cec5SDimitry Andric            (VST VR128:$src, bdxaddr12only:$addr)>;
18440b57cec5SDimitry Andric
18450b57cec5SDimitry Andric  def : Pat<(f128 fpimm0), (VZERO)>;
18460b57cec5SDimitry Andric  def : Pat<(f128 fpimmneg0), (WFLNXB (VZERO))>;
18470b57cec5SDimitry Andric}
18480b57cec5SDimitry Andric
18490b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
18500b57cec5SDimitry Andric// String instructions
18510b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
18520b57cec5SDimitry Andric
18530b57cec5SDimitry Andriclet Predicates = [FeatureVector] in {
18540b57cec5SDimitry Andric  defm VFAE  : TernaryOptVRRbSPairGeneric<"vfae", 0xE782>;
18550b57cec5SDimitry Andric  defm VFAEB : TernaryOptVRRbSPair<"vfaeb", 0xE782, int_s390_vfaeb,
18560b57cec5SDimitry Andric                                   z_vfae_cc, v128b, v128b, 0>;
18570b57cec5SDimitry Andric  defm VFAEH : TernaryOptVRRbSPair<"vfaeh", 0xE782, int_s390_vfaeh,
18580b57cec5SDimitry Andric                                   z_vfae_cc, v128h, v128h, 1>;
18590b57cec5SDimitry Andric  defm VFAEF : TernaryOptVRRbSPair<"vfaef", 0xE782, int_s390_vfaef,
18600b57cec5SDimitry Andric                                   z_vfae_cc, v128f, v128f, 2>;
18610b57cec5SDimitry Andric  defm VFAEZB : TernaryOptVRRbSPair<"vfaezb", 0xE782, int_s390_vfaezb,
18620b57cec5SDimitry Andric                                    z_vfaez_cc, v128b, v128b, 0, 2>;
18630b57cec5SDimitry Andric  defm VFAEZH : TernaryOptVRRbSPair<"vfaezh", 0xE782, int_s390_vfaezh,
18640b57cec5SDimitry Andric                                    z_vfaez_cc, v128h, v128h, 1, 2>;
18650b57cec5SDimitry Andric  defm VFAEZF : TernaryOptVRRbSPair<"vfaezf", 0xE782, int_s390_vfaezf,
18660b57cec5SDimitry Andric                                    z_vfaez_cc, v128f, v128f, 2, 2>;
18670b57cec5SDimitry Andric
18680b57cec5SDimitry Andric  defm VFEE  : BinaryExtraVRRbSPairGeneric<"vfee", 0xE780>;
18690b57cec5SDimitry Andric  defm VFEEB : BinaryExtraVRRbSPair<"vfeeb", 0xE780, int_s390_vfeeb,
18700b57cec5SDimitry Andric                                    z_vfee_cc, v128b, v128b, 0>;
18710b57cec5SDimitry Andric  defm VFEEH : BinaryExtraVRRbSPair<"vfeeh", 0xE780, int_s390_vfeeh,
18720b57cec5SDimitry Andric                                    z_vfee_cc, v128h, v128h, 1>;
18730b57cec5SDimitry Andric  defm VFEEF : BinaryExtraVRRbSPair<"vfeef", 0xE780, int_s390_vfeef,
18740b57cec5SDimitry Andric                                    z_vfee_cc, v128f, v128f, 2>;
18750b57cec5SDimitry Andric  defm VFEEZB : BinaryVRRbSPair<"vfeezb", 0xE780, int_s390_vfeezb,
18760b57cec5SDimitry Andric                                z_vfeez_cc, v128b, v128b, 0, 2>;
18770b57cec5SDimitry Andric  defm VFEEZH : BinaryVRRbSPair<"vfeezh", 0xE780, int_s390_vfeezh,
18780b57cec5SDimitry Andric                                z_vfeez_cc, v128h, v128h, 1, 2>;
18790b57cec5SDimitry Andric  defm VFEEZF : BinaryVRRbSPair<"vfeezf", 0xE780, int_s390_vfeezf,
18800b57cec5SDimitry Andric                                z_vfeez_cc, v128f, v128f, 2, 2>;
18810b57cec5SDimitry Andric
18820b57cec5SDimitry Andric  defm VFENE  : BinaryExtraVRRbSPairGeneric<"vfene", 0xE781>;
18830b57cec5SDimitry Andric  defm VFENEB : BinaryExtraVRRbSPair<"vfeneb", 0xE781, int_s390_vfeneb,
18840b57cec5SDimitry Andric                                     z_vfene_cc, v128b, v128b, 0>;
18850b57cec5SDimitry Andric  defm VFENEH : BinaryExtraVRRbSPair<"vfeneh", 0xE781, int_s390_vfeneh,
18860b57cec5SDimitry Andric                                     z_vfene_cc, v128h, v128h, 1>;
18870b57cec5SDimitry Andric  defm VFENEF : BinaryExtraVRRbSPair<"vfenef", 0xE781, int_s390_vfenef,
18880b57cec5SDimitry Andric                                     z_vfene_cc, v128f, v128f, 2>;
18890b57cec5SDimitry Andric  defm VFENEZB : BinaryVRRbSPair<"vfenezb", 0xE781, int_s390_vfenezb,
18900b57cec5SDimitry Andric                                 z_vfenez_cc, v128b, v128b, 0, 2>;
18910b57cec5SDimitry Andric  defm VFENEZH : BinaryVRRbSPair<"vfenezh", 0xE781, int_s390_vfenezh,
18920b57cec5SDimitry Andric                                 z_vfenez_cc, v128h, v128h, 1, 2>;
18930b57cec5SDimitry Andric  defm VFENEZF : BinaryVRRbSPair<"vfenezf", 0xE781, int_s390_vfenezf,
18940b57cec5SDimitry Andric                                 z_vfenez_cc, v128f, v128f, 2, 2>;
18950b57cec5SDimitry Andric
18960b57cec5SDimitry Andric  defm VISTR  : UnaryExtraVRRaSPairGeneric<"vistr", 0xE75C>;
18970b57cec5SDimitry Andric  defm VISTRB : UnaryExtraVRRaSPair<"vistrb", 0xE75C, int_s390_vistrb,
18980b57cec5SDimitry Andric                                    z_vistr_cc, v128b, v128b, 0>;
18990b57cec5SDimitry Andric  defm VISTRH : UnaryExtraVRRaSPair<"vistrh", 0xE75C, int_s390_vistrh,
19000b57cec5SDimitry Andric                                    z_vistr_cc, v128h, v128h, 1>;
19010b57cec5SDimitry Andric  defm VISTRF : UnaryExtraVRRaSPair<"vistrf", 0xE75C, int_s390_vistrf,
19020b57cec5SDimitry Andric                                    z_vistr_cc, v128f, v128f, 2>;
19030b57cec5SDimitry Andric
19040b57cec5SDimitry Andric  defm VSTRC  : QuaternaryOptVRRdSPairGeneric<"vstrc", 0xE78A>;
19050b57cec5SDimitry Andric  defm VSTRCB : QuaternaryOptVRRdSPair<"vstrcb", 0xE78A, int_s390_vstrcb,
19060b57cec5SDimitry Andric                                       z_vstrc_cc, v128b, v128b, 0>;
19070b57cec5SDimitry Andric  defm VSTRCH : QuaternaryOptVRRdSPair<"vstrch", 0xE78A, int_s390_vstrch,
19080b57cec5SDimitry Andric                                       z_vstrc_cc, v128h, v128h, 1>;
19090b57cec5SDimitry Andric  defm VSTRCF : QuaternaryOptVRRdSPair<"vstrcf", 0xE78A, int_s390_vstrcf,
19100b57cec5SDimitry Andric                                       z_vstrc_cc, v128f, v128f, 2>;
19110b57cec5SDimitry Andric  defm VSTRCZB : QuaternaryOptVRRdSPair<"vstrczb", 0xE78A, int_s390_vstrczb,
19120b57cec5SDimitry Andric                                        z_vstrcz_cc, v128b, v128b, 0, 2>;
19130b57cec5SDimitry Andric  defm VSTRCZH : QuaternaryOptVRRdSPair<"vstrczh", 0xE78A, int_s390_vstrczh,
19140b57cec5SDimitry Andric                                        z_vstrcz_cc, v128h, v128h, 1, 2>;
19150b57cec5SDimitry Andric  defm VSTRCZF : QuaternaryOptVRRdSPair<"vstrczf", 0xE78A, int_s390_vstrczf,
19160b57cec5SDimitry Andric                                        z_vstrcz_cc, v128f, v128f, 2, 2>;
19170b57cec5SDimitry Andric}
19180b57cec5SDimitry Andric
19190b57cec5SDimitry Andriclet Predicates = [FeatureVectorEnhancements2] in {
19200b57cec5SDimitry Andric  defm VSTRS  : TernaryExtraVRRdGeneric<"vstrs", 0xE78B>;
19210b57cec5SDimitry Andric  defm VSTRSB : TernaryExtraVRRd<"vstrsb", 0xE78B,
19220b57cec5SDimitry Andric                                 z_vstrs_cc, v128b, v128b, 0>;
19230b57cec5SDimitry Andric  defm VSTRSH : TernaryExtraVRRd<"vstrsh", 0xE78B,
19240b57cec5SDimitry Andric                                 z_vstrs_cc, v128b, v128h, 1>;
19250b57cec5SDimitry Andric  defm VSTRSF : TernaryExtraVRRd<"vstrsf", 0xE78B,
19260b57cec5SDimitry Andric                                 z_vstrs_cc, v128b, v128f, 2>;
19270b57cec5SDimitry Andric  let Defs = [CC] in {
19280b57cec5SDimitry Andric    def VSTRSZB : TernaryVRRd<"vstrszb", 0xE78B,
19290b57cec5SDimitry Andric                              z_vstrsz_cc, v128b, v128b, 0, 2>;
19300b57cec5SDimitry Andric    def VSTRSZH : TernaryVRRd<"vstrszh", 0xE78B,
19310b57cec5SDimitry Andric                              z_vstrsz_cc, v128b, v128h, 1, 2>;
19320b57cec5SDimitry Andric    def VSTRSZF : TernaryVRRd<"vstrszf", 0xE78B,
19330b57cec5SDimitry Andric                              z_vstrsz_cc, v128b, v128f, 2, 2>;
19340b57cec5SDimitry Andric  }
19350b57cec5SDimitry Andric}
19360b57cec5SDimitry Andric
19370b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
1938fe6060f1SDimitry Andric// NNP assist instructions
1939fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
1940fe6060f1SDimitry Andric
1941fe6060f1SDimitry Andriclet Predicates = [FeatureVector, FeatureNNPAssist] in {
1942fe6060f1SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1 in
1943fe6060f1SDimitry Andric    def VCFN : UnaryVRRaFloatGeneric<"vcfn", 0xE65D>;
1944fe6060f1SDimitry Andric  def : Pat<(int_s390_vcfn VR128:$x, imm32zx4_timm:$m),
1945fe6060f1SDimitry Andric            (VCFN VR128:$x, 1, imm32zx4:$m)>;
1946fe6060f1SDimitry Andric
1947fe6060f1SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1 in
1948fe6060f1SDimitry Andric    def VCLFNL : UnaryVRRaFloatGeneric<"vclfnl", 0xE65E>;
1949fe6060f1SDimitry Andric  def : Pat<(int_s390_vclfnls VR128:$x, imm32zx4_timm:$m),
1950fe6060f1SDimitry Andric            (VCLFNL VR128:$x, 2, imm32zx4:$m)>;
1951fe6060f1SDimitry Andric
1952fe6060f1SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1 in
1953fe6060f1SDimitry Andric    def VCLFNH : UnaryVRRaFloatGeneric<"vclfnh", 0xE656>;
1954fe6060f1SDimitry Andric  def : Pat<(int_s390_vclfnhs VR128:$x, imm32zx4_timm:$m),
1955fe6060f1SDimitry Andric            (VCLFNH VR128:$x, 2, imm32zx4:$m)>;
1956fe6060f1SDimitry Andric
1957fe6060f1SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1 in
1958fe6060f1SDimitry Andric    def VCNF : UnaryVRRaFloatGeneric<"vcnf", 0xE655>;
1959fe6060f1SDimitry Andric  def : Pat<(int_s390_vcnf VR128:$x, imm32zx4_timm:$m),
1960fe6060f1SDimitry Andric            (VCNF VR128:$x, imm32zx4:$m, 1)>;
1961fe6060f1SDimitry Andric
1962fe6060f1SDimitry Andric  let Uses = [FPC], mayRaiseFPException = 1 in
1963fe6060f1SDimitry Andric    def VCRNF : BinaryVRRcFloatGeneric<"vcrnf", 0xE675>;
1964fe6060f1SDimitry Andric  def : Pat<(int_s390_vcrnfs VR128:$x, VR128:$y, imm32zx4_timm:$m),
1965fe6060f1SDimitry Andric            (VCRNF VR128:$x, VR128:$y, imm32zx4:$m, 2)>;
1966fe6060f1SDimitry Andric}
1967fe6060f1SDimitry Andric
1968fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
19690b57cec5SDimitry Andric// Packed-decimal instructions
19700b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
19710b57cec5SDimitry Andric
19720b57cec5SDimitry Andriclet Predicates = [FeatureVectorPackedDecimal] in {
19730b57cec5SDimitry Andric  def VLIP : BinaryVRIh<"vlip", 0xE649>;
19740b57cec5SDimitry Andric
19750b57cec5SDimitry Andric  def VPKZ : BinaryVSI<"vpkz", 0xE634, null_frag, 0>;
19760b57cec5SDimitry Andric  def VUPKZ : StoreLengthVSI<"vupkz", 0xE63C, null_frag, 0>;
19770b57cec5SDimitry Andric
19780b57cec5SDimitry Andric  let Defs = [CC] in {
19790b57cec5SDimitry Andric    let Predicates = [FeatureVectorPackedDecimalEnhancement] in {
19800b57cec5SDimitry Andric      def VCVBOpt : TernaryVRRi<"vcvb", 0xE650, GR32>;
19810b57cec5SDimitry Andric      def VCVBGOpt : TernaryVRRi<"vcvbg", 0xE652, GR64>;
19820b57cec5SDimitry Andric    }
19830b57cec5SDimitry Andric    def VCVB : BinaryVRRi<"vcvb", 0xE650, GR32>;
19840b57cec5SDimitry Andric    def VCVBG : BinaryVRRi<"vcvbg", 0xE652, GR64>;
19850b57cec5SDimitry Andric    def VCVD : TernaryVRIi<"vcvd", 0xE658, GR32>;
19860b57cec5SDimitry Andric    def VCVDG : TernaryVRIi<"vcvdg", 0xE65A, GR64>;
19870b57cec5SDimitry Andric
19880b57cec5SDimitry Andric    def VAP : QuaternaryVRIf<"vap", 0xE671>;
19890b57cec5SDimitry Andric    def VSP : QuaternaryVRIf<"vsp", 0xE673>;
19900b57cec5SDimitry Andric
19910b57cec5SDimitry Andric    def VMP : QuaternaryVRIf<"vmp", 0xE678>;
19920b57cec5SDimitry Andric    def VMSP : QuaternaryVRIf<"vmsp", 0xE679>;
19930b57cec5SDimitry Andric
19940b57cec5SDimitry Andric    def VDP : QuaternaryVRIf<"vdp", 0xE67A>;
19950b57cec5SDimitry Andric    def VRP : QuaternaryVRIf<"vrp", 0xE67B>;
19960b57cec5SDimitry Andric    def VSDP : QuaternaryVRIf<"vsdp", 0xE67E>;
19970b57cec5SDimitry Andric
19980b57cec5SDimitry Andric    def VSRP : QuaternaryVRIg<"vsrp", 0xE659>;
19990b57cec5SDimitry Andric    def VPSOP : QuaternaryVRIg<"vpsop", 0xE65B>;
20000b57cec5SDimitry Andric
20010b57cec5SDimitry Andric    def VTP : TestVRRg<"vtp", 0xE65F>;
20020b57cec5SDimitry Andric    def VCP : CompareVRRh<"vcp", 0xE677>;
20030b57cec5SDimitry Andric  }
20040b57cec5SDimitry Andric}
2005fe6060f1SDimitry Andric
2006fe6060f1SDimitry Andriclet Predicates = [FeatureVectorPackedDecimalEnhancement2] in {
2007fe6060f1SDimitry Andric  def VSCHP : BinaryExtraVRRbGeneric<"vschp", 0xE674>;
2008fe6060f1SDimitry Andric  def VSCHSP : BinaryExtraVRRb<"vschsp", 0xE674, 2>;
2009fe6060f1SDimitry Andric  def VSCHDP : BinaryExtraVRRb<"vschdp", 0xE674, 3>;
2010fe6060f1SDimitry Andric  def VSCHXP : BinaryExtraVRRb<"vschxp", 0xE674, 4>;
2011fe6060f1SDimitry Andric
2012fe6060f1SDimitry Andric  def VSCSHP : BinaryVRRb<"vscshp", 0xE67C, null_frag, v128b, v128b>;
2013fe6060f1SDimitry Andric
2014fe6060f1SDimitry Andric  def VCSPH : TernaryVRRj<"vcsph", 0xE67D>;
2015fe6060f1SDimitry Andric
2016fe6060f1SDimitry Andric  let Defs = [CC] in
2017fe6060f1SDimitry Andric    def VCLZDP : BinaryVRRk<"vclzdp", 0xE651>;
2018fe6060f1SDimitry Andric
2019fe6060f1SDimitry Andric  let Defs = [CC] in
2020fe6060f1SDimitry Andric    def VSRPR : QuaternaryVRIf<"vsrpr", 0xE672>;
2021fe6060f1SDimitry Andric
2022fe6060f1SDimitry Andric  let Defs = [CC] in {
2023fe6060f1SDimitry Andric    def VPKZR : QuaternaryVRIf<"vpkzr", 0xE670>;
2024fe6060f1SDimitry Andric    def VUPKZH : BinaryVRRk<"vupkzh", 0xE654>;
2025fe6060f1SDimitry Andric    def VUPKZL : BinaryVRRk<"vupkzl", 0xE65C>;
2026fe6060f1SDimitry Andric  }
2027fe6060f1SDimitry Andric}
2028