1a8b04e1cSUlrich Weigand//==- SystemZInstrVector.td - SystemZ Vector instructions ------*- tblgen-*-==//
2a8b04e1cSUlrich Weigand//
3a8b04e1cSUlrich Weigand//                     The LLVM Compiler Infrastructure
4a8b04e1cSUlrich Weigand//
5a8b04e1cSUlrich Weigand// This file is distributed under the University of Illinois Open Source
6a8b04e1cSUlrich Weigand// License. See LICENSE.TXT for details.
7a8b04e1cSUlrich Weigand//
8a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
9a8b04e1cSUlrich Weigand
10a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
11a8b04e1cSUlrich Weigand// Move instructions
12a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
13a8b04e1cSUlrich Weigand
14a8b04e1cSUlrich Weigandlet Predicates = [FeatureVector] in {
15a8b04e1cSUlrich Weigand  // Register move.
16a8b04e1cSUlrich Weigand  def VLR : UnaryVRRa<"vlr", 0xE756, null_frag, v128any, v128any>;
17a8b04e1cSUlrich Weigand
18a8b04e1cSUlrich Weigand  // Load GR from VR element.
19a8b04e1cSUlrich Weigand  def VLGVB : BinaryVRSc<"vlgvb", 0xE721, null_frag, v128b, 0>;
20a8b04e1cSUlrich Weigand  def VLGVH : BinaryVRSc<"vlgvh", 0xE721, null_frag, v128h, 1>;
21a8b04e1cSUlrich Weigand  def VLGVF : BinaryVRSc<"vlgvf", 0xE721, null_frag, v128f, 2>;
22ce4c1095SUlrich Weigand  def VLGVG : BinaryVRSc<"vlgvg", 0xE721, z_vector_extract, v128g, 3>;
23a8b04e1cSUlrich Weigand
24a8b04e1cSUlrich Weigand  // Load VR element from GR.
25ce4c1095SUlrich Weigand  def VLVGB : TernaryVRSb<"vlvgb", 0xE722, z_vector_insert,
26ce4c1095SUlrich Weigand                          v128b, v128b, GR32, 0>;
27ce4c1095SUlrich Weigand  def VLVGH : TernaryVRSb<"vlvgh", 0xE722, z_vector_insert,
28ce4c1095SUlrich Weigand                          v128h, v128h, GR32, 1>;
29ce4c1095SUlrich Weigand  def VLVGF : TernaryVRSb<"vlvgf", 0xE722, z_vector_insert,
30ce4c1095SUlrich Weigand                          v128f, v128f, GR32, 2>;
31ce4c1095SUlrich Weigand  def VLVGG : TernaryVRSb<"vlvgg", 0xE722, z_vector_insert,
32ce4c1095SUlrich Weigand                          v128g, v128g, GR64, 3>;
33a8b04e1cSUlrich Weigand
34a8b04e1cSUlrich Weigand  // Load VR from GRs disjoint.
35ce4c1095SUlrich Weigand  def VLVGP : BinaryVRRf<"vlvgp", 0xE762, z_join_dwords, v128g>;
36ce4c1095SUlrich Weigand  def VLVGP32 : BinaryAliasVRRf<GR32>;
37a8b04e1cSUlrich Weigand}
38a8b04e1cSUlrich Weigand
39ce4c1095SUlrich Weigand// Extractions always assign to the full GR64, even if the element would
40ce4c1095SUlrich Weigand// fit in the lower 32 bits.  Sub-i64 extracts therefore need to take a
41ce4c1095SUlrich Weigand// subreg of the result.
42ce4c1095SUlrich Weigandclass VectorExtractSubreg<ValueType type, Instruction insn>
43ce4c1095SUlrich Weigand  : Pat<(i32 (z_vector_extract (type VR128:$vec), shift12only:$index)),
44ce4c1095SUlrich Weigand        (EXTRACT_SUBREG (insn VR128:$vec, shift12only:$index), subreg_l32)>;
45ce4c1095SUlrich Weigand
46ce4c1095SUlrich Weiganddef : VectorExtractSubreg<v16i8, VLGVB>;
47ce4c1095SUlrich Weiganddef : VectorExtractSubreg<v8i16, VLGVH>;
48ce4c1095SUlrich Weiganddef : VectorExtractSubreg<v4i32, VLGVF>;
49ce4c1095SUlrich Weigand
50a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
51a8b04e1cSUlrich Weigand// Immediate instructions
52a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
53a8b04e1cSUlrich Weigand
54a8b04e1cSUlrich Weigandlet Predicates = [FeatureVector] in {
55a8b04e1cSUlrich Weigand  // Generate byte mask.
56a8b04e1cSUlrich Weigand  def VZERO : InherentVRIa<"vzero", 0xE744, 0>;
57a8b04e1cSUlrich Weigand  def VONE  : InherentVRIa<"vone", 0xE744, 0xffff>;
58ce4c1095SUlrich Weigand  def VGBM  : UnaryVRIa<"vgbm", 0xE744, z_byte_mask, v128b, imm32zx16>;
59a8b04e1cSUlrich Weigand
60a8b04e1cSUlrich Weigand  // Generate mask.
61ce4c1095SUlrich Weigand  def VGMB : BinaryVRIb<"vgmb", 0xE746, z_rotate_mask, v128b, 0>;
62ce4c1095SUlrich Weigand  def VGMH : BinaryVRIb<"vgmh", 0xE746, z_rotate_mask, v128h, 1>;
63ce4c1095SUlrich Weigand  def VGMF : BinaryVRIb<"vgmf", 0xE746, z_rotate_mask, v128f, 2>;
64ce4c1095SUlrich Weigand  def VGMG : BinaryVRIb<"vgmg", 0xE746, z_rotate_mask, v128g, 3>;
65a8b04e1cSUlrich Weigand
66a8b04e1cSUlrich Weigand  // Load element immediate.
67ce4c1095SUlrich Weigand  //
68ce4c1095SUlrich Weigand  // We want these instructions to be used ahead of VLVG* where possible.
69ce4c1095SUlrich Weigand  // However, VLVG* takes a variable BD-format index whereas VLEI takes
70ce4c1095SUlrich Weigand  // a plain immediate index.  This means that VLVG* has an extra "base"
71ce4c1095SUlrich Weigand  // register operand and is 3 units more complex.  Bumping the complexity
72ce4c1095SUlrich Weigand  // of the VLEI* instructions by 4 means that they are strictly better
73ce4c1095SUlrich Weigand  // than VLVG* in cases where both forms match.
74ce4c1095SUlrich Weigand  let AddedComplexity = 4 in {
75ce4c1095SUlrich Weigand    def VLEIB : TernaryVRIa<"vleib", 0xE740, z_vector_insert,
76a8b04e1cSUlrich Weigand                            v128b, v128b, imm32sx16trunc, imm32zx4>;
77ce4c1095SUlrich Weigand    def VLEIH : TernaryVRIa<"vleih", 0xE741, z_vector_insert,
78a8b04e1cSUlrich Weigand                            v128h, v128h, imm32sx16trunc, imm32zx3>;
79ce4c1095SUlrich Weigand    def VLEIF : TernaryVRIa<"vleif", 0xE743, z_vector_insert,
80a8b04e1cSUlrich Weigand                            v128f, v128f, imm32sx16, imm32zx2>;
81ce4c1095SUlrich Weigand    def VLEIG : TernaryVRIa<"vleig", 0xE742, z_vector_insert,
82a8b04e1cSUlrich Weigand                            v128g, v128g, imm64sx16, imm32zx1>;
83ce4c1095SUlrich Weigand  }
84a8b04e1cSUlrich Weigand
85a8b04e1cSUlrich Weigand  // Replicate immediate.
86ce4c1095SUlrich Weigand  def VREPIB : UnaryVRIa<"vrepib", 0xE745, z_replicate, v128b, imm32sx16, 0>;
87ce4c1095SUlrich Weigand  def VREPIH : UnaryVRIa<"vrepih", 0xE745, z_replicate, v128h, imm32sx16, 1>;
88ce4c1095SUlrich Weigand  def VREPIF : UnaryVRIa<"vrepif", 0xE745, z_replicate, v128f, imm32sx16, 2>;
89ce4c1095SUlrich Weigand  def VREPIG : UnaryVRIa<"vrepig", 0xE745, z_replicate, v128g, imm32sx16, 3>;
90a8b04e1cSUlrich Weigand}
91a8b04e1cSUlrich Weigand
92a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
93a8b04e1cSUlrich Weigand// Loads
94a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
95a8b04e1cSUlrich Weigand
96a8b04e1cSUlrich Weigandlet Predicates = [FeatureVector] in {
97a8b04e1cSUlrich Weigand  // Load.
98a8b04e1cSUlrich Weigand  def VL : UnaryVRX<"vl", 0xE706, null_frag, v128any, 16>;
99a8b04e1cSUlrich Weigand
100a8b04e1cSUlrich Weigand  // Load to block boundary.  The number of loaded bytes is only known
101a8b04e1cSUlrich Weigand  // at run time.
102a8b04e1cSUlrich Weigand  def VLBB : BinaryVRX<"vlbb", 0xE707, null_frag, v128any, 0>;
103a8b04e1cSUlrich Weigand
104a8b04e1cSUlrich Weigand  // Load count to block boundary.
105a8b04e1cSUlrich Weigand  let Defs = [CC] in
106a8b04e1cSUlrich Weigand    def LCBB : InstRXE<0xE727, (outs GR32:$R1),
107a8b04e1cSUlrich Weigand                               (ins bdxaddr12only:$XBD2, imm32zx4:$M3),
108a8b04e1cSUlrich Weigand                       "lcbb\t$R1, $XBD2, $M3", []>;
109a8b04e1cSUlrich Weigand
110a8b04e1cSUlrich Weigand  // Load with length.  The number of loaded bytes is only known at run time.
111a8b04e1cSUlrich Weigand  def VLL : BinaryVRSb<"vll", 0xE737, null_frag, 0>;
112a8b04e1cSUlrich Weigand
113a8b04e1cSUlrich Weigand  // Load multiple.
114a8b04e1cSUlrich Weigand  def VLM : LoadMultipleVRSa<"vlm", 0xE736>;
115a8b04e1cSUlrich Weigand
116a8b04e1cSUlrich Weigand  // Load and replicate
117ce4c1095SUlrich Weigand  def VLREPB : UnaryVRX<"vlrepb", 0xE705, z_replicate_loadi8,  v128b, 1, 0>;
118ce4c1095SUlrich Weigand  def VLREPH : UnaryVRX<"vlreph", 0xE705, z_replicate_loadi16, v128h, 2, 1>;
119ce4c1095SUlrich Weigand  def VLREPF : UnaryVRX<"vlrepf", 0xE705, z_replicate_loadi32, v128f, 4, 2>;
120ce4c1095SUlrich Weigand  def VLREPG : UnaryVRX<"vlrepg", 0xE705, z_replicate_loadi64, v128g, 8, 3>;
121*cd808237SUlrich Weigand  def : Pat<(v2f64 (z_replicate_loadf64 bdxaddr12only:$addr)),
122*cd808237SUlrich Weigand            (VLREPG bdxaddr12only:$addr)>;
123a8b04e1cSUlrich Weigand
124a8b04e1cSUlrich Weigand  // Load logical element and zero.
125ce4c1095SUlrich Weigand  def VLLEZB : UnaryVRX<"vllezb", 0xE704, z_vllezi8,  v128b, 1, 0>;
126ce4c1095SUlrich Weigand  def VLLEZH : UnaryVRX<"vllezh", 0xE704, z_vllezi16, v128h, 2, 1>;
127ce4c1095SUlrich Weigand  def VLLEZF : UnaryVRX<"vllezf", 0xE704, z_vllezi32, v128f, 4, 2>;
128ce4c1095SUlrich Weigand  def VLLEZG : UnaryVRX<"vllezg", 0xE704, z_vllezi64, v128g, 8, 3>;
129*cd808237SUlrich Weigand  def : Pat<(v2f64 (z_vllezf64 bdxaddr12only:$addr)),
130*cd808237SUlrich Weigand            (VLLEZG bdxaddr12only:$addr)>;
131a8b04e1cSUlrich Weigand
132a8b04e1cSUlrich Weigand  // Load element.
133ce4c1095SUlrich Weigand  def VLEB : TernaryVRX<"vleb", 0xE700, z_vlei8,  v128b, v128b, 1, imm32zx4>;
134ce4c1095SUlrich Weigand  def VLEH : TernaryVRX<"vleh", 0xE701, z_vlei16, v128h, v128h, 2, imm32zx3>;
135ce4c1095SUlrich Weigand  def VLEF : TernaryVRX<"vlef", 0xE703, z_vlei32, v128f, v128f, 4, imm32zx2>;
136ce4c1095SUlrich Weigand  def VLEG : TernaryVRX<"vleg", 0xE702, z_vlei64, v128g, v128g, 8, imm32zx1>;
137*cd808237SUlrich Weigand  def : Pat<(z_vlef64 (v2f64 VR128:$val), bdxaddr12only:$addr, imm32zx1:$index),
138*cd808237SUlrich Weigand            (VLEG VR128:$val, bdxaddr12only:$addr, imm32zx1:$index)>;
139a8b04e1cSUlrich Weigand
140a8b04e1cSUlrich Weigand  // Gather element.
141a8b04e1cSUlrich Weigand  def VGEF : TernaryVRV<"vgef", 0xE713, 4, imm32zx2>;
142a8b04e1cSUlrich Weigand  def VGEG : TernaryVRV<"vgeg", 0xE712, 8, imm32zx1>;
143a8b04e1cSUlrich Weigand}
144a8b04e1cSUlrich Weigand
145ce4c1095SUlrich Weigand// Use replicating loads if we're inserting a single element into an
146ce4c1095SUlrich Weigand// undefined vector.  This avoids a false dependency on the previous
147ce4c1095SUlrich Weigand// register contents.
148ce4c1095SUlrich Weigandmulticlass ReplicatePeephole<Instruction vlrep, ValueType vectype,
149ce4c1095SUlrich Weigand                             SDPatternOperator load, ValueType scalartype> {
150ce4c1095SUlrich Weigand  def : Pat<(vectype (z_vector_insert
151ce4c1095SUlrich Weigand                      (undef), (scalartype (load bdxaddr12only:$addr)), 0)),
152ce4c1095SUlrich Weigand            (vlrep bdxaddr12only:$addr)>;
153ce4c1095SUlrich Weigand  def : Pat<(vectype (scalar_to_vector
154ce4c1095SUlrich Weigand                      (scalartype (load bdxaddr12only:$addr)))),
155ce4c1095SUlrich Weigand            (vlrep bdxaddr12only:$addr)>;
156ce4c1095SUlrich Weigand}
157ce4c1095SUlrich Weiganddefm : ReplicatePeephole<VLREPB, v16i8, anyextloadi8, i32>;
158ce4c1095SUlrich Weiganddefm : ReplicatePeephole<VLREPH, v8i16, anyextloadi16, i32>;
159ce4c1095SUlrich Weiganddefm : ReplicatePeephole<VLREPF, v4i32, load, i32>;
160ce4c1095SUlrich Weiganddefm : ReplicatePeephole<VLREPG, v2i64, load, i64>;
161*cd808237SUlrich Weiganddefm : ReplicatePeephole<VLREPG, v2f64, load, f64>;
162ce4c1095SUlrich Weigand
163a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
164a8b04e1cSUlrich Weigand// Stores
165a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
166a8b04e1cSUlrich Weigand
167a8b04e1cSUlrich Weigandlet Predicates = [FeatureVector] in {
168a8b04e1cSUlrich Weigand  // Store.
169a8b04e1cSUlrich Weigand  def VST : StoreVRX<"vst", 0xE70E, null_frag, v128any, 16>;
170a8b04e1cSUlrich Weigand
171a8b04e1cSUlrich Weigand  // Store with length.  The number of stored bytes is only known at run time.
172a8b04e1cSUlrich Weigand  def VSTL : StoreLengthVRSb<"vstl", 0xE73F, null_frag, 0>;
173a8b04e1cSUlrich Weigand
174a8b04e1cSUlrich Weigand  // Store multiple.
175a8b04e1cSUlrich Weigand  def VSTM : StoreMultipleVRSa<"vstm", 0xE73E>;
176a8b04e1cSUlrich Weigand
177a8b04e1cSUlrich Weigand  // Store element.
178ce4c1095SUlrich Weigand  def VSTEB : StoreBinaryVRX<"vsteb", 0xE708, z_vstei8,  v128b, 1, imm32zx4>;
179ce4c1095SUlrich Weigand  def VSTEH : StoreBinaryVRX<"vsteh", 0xE709, z_vstei16, v128h, 2, imm32zx3>;
180ce4c1095SUlrich Weigand  def VSTEF : StoreBinaryVRX<"vstef", 0xE70B, z_vstei32, v128f, 4, imm32zx2>;
181ce4c1095SUlrich Weigand  def VSTEG : StoreBinaryVRX<"vsteg", 0xE70A, z_vstei64, v128g, 8, imm32zx1>;
182*cd808237SUlrich Weigand  def : Pat<(z_vstef64 (v2f64 VR128:$val), bdxaddr12only:$addr,
183*cd808237SUlrich Weigand                       imm32zx1:$index),
184*cd808237SUlrich Weigand            (VSTEG VR128:$val, bdxaddr12only:$addr, imm32zx1:$index)>;
185a8b04e1cSUlrich Weigand
186a8b04e1cSUlrich Weigand  // Scatter element.
187a8b04e1cSUlrich Weigand  def VSCEF : StoreBinaryVRV<"vscef", 0xE71B, 4, imm32zx2>;
188a8b04e1cSUlrich Weigand  def VSCEG : StoreBinaryVRV<"vsceg", 0xE71A, 8, imm32zx1>;
189a8b04e1cSUlrich Weigand}
190a8b04e1cSUlrich Weigand
191a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
192a8b04e1cSUlrich Weigand// Selects and permutes
193a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
194a8b04e1cSUlrich Weigand
195a8b04e1cSUlrich Weigandlet Predicates = [FeatureVector] in {
196a8b04e1cSUlrich Weigand  // Merge high.
197ce4c1095SUlrich Weigand  def VMRHB : BinaryVRRc<"vmrhb", 0xE761, z_merge_high, v128b, v128b, 0>;
198ce4c1095SUlrich Weigand  def VMRHH : BinaryVRRc<"vmrhh", 0xE761, z_merge_high, v128h, v128h, 1>;
199ce4c1095SUlrich Weigand  def VMRHF : BinaryVRRc<"vmrhf", 0xE761, z_merge_high, v128f, v128f, 2>;
200ce4c1095SUlrich Weigand  def VMRHG : BinaryVRRc<"vmrhg", 0xE761, z_merge_high, v128g, v128g, 3>;
201*cd808237SUlrich Weigand  def : BinaryRRWithType<VMRHG, VR128, z_merge_high, v2f64>;
202a8b04e1cSUlrich Weigand
203a8b04e1cSUlrich Weigand  // Merge low.
204ce4c1095SUlrich Weigand  def VMRLB : BinaryVRRc<"vmrlb", 0xE760, z_merge_low, v128b, v128b, 0>;
205ce4c1095SUlrich Weigand  def VMRLH : BinaryVRRc<"vmrlh", 0xE760, z_merge_low, v128h, v128h, 1>;
206ce4c1095SUlrich Weigand  def VMRLF : BinaryVRRc<"vmrlf", 0xE760, z_merge_low, v128f, v128f, 2>;
207ce4c1095SUlrich Weigand  def VMRLG : BinaryVRRc<"vmrlg", 0xE760, z_merge_low, v128g, v128g, 3>;
208*cd808237SUlrich Weigand  def : BinaryRRWithType<VMRLG, VR128, z_merge_low, v2f64>;
209a8b04e1cSUlrich Weigand
210a8b04e1cSUlrich Weigand  // Permute.
211ce4c1095SUlrich Weigand  def VPERM : TernaryVRRe<"vperm", 0xE78C, z_permute, v128b, v128b>;
212a8b04e1cSUlrich Weigand
213a8b04e1cSUlrich Weigand  // Permute doubleword immediate.
214ce4c1095SUlrich Weigand  def VPDI : TernaryVRRc<"vpdi", 0xE784, z_permute_dwords, v128g, v128g>;
215a8b04e1cSUlrich Weigand
216a8b04e1cSUlrich Weigand  // Replicate.
217ce4c1095SUlrich Weigand  def VREPB : BinaryVRIc<"vrepb", 0xE74D, z_splat, v128b, v128b, 0>;
218ce4c1095SUlrich Weigand  def VREPH : BinaryVRIc<"vreph", 0xE74D, z_splat, v128h, v128h, 1>;
219ce4c1095SUlrich Weigand  def VREPF : BinaryVRIc<"vrepf", 0xE74D, z_splat, v128f, v128f, 2>;
220ce4c1095SUlrich Weigand  def VREPG : BinaryVRIc<"vrepg", 0xE74D, z_splat, v128g, v128g, 3>;
221*cd808237SUlrich Weigand  def : Pat<(v2f64 (z_splat VR128:$vec, imm32zx16:$index)),
222*cd808237SUlrich Weigand            (VREPG VR128:$vec, imm32zx16:$index)>;
223a8b04e1cSUlrich Weigand
224a8b04e1cSUlrich Weigand  // Select.
225a8b04e1cSUlrich Weigand  def VSEL : TernaryVRRe<"vsel", 0xE78D, null_frag, v128any, v128any>;
226a8b04e1cSUlrich Weigand}
227a8b04e1cSUlrich Weigand
228a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
229a8b04e1cSUlrich Weigand// Widening and narrowing
230a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
231a8b04e1cSUlrich Weigand
232a8b04e1cSUlrich Weigandlet Predicates = [FeatureVector] in {
233a8b04e1cSUlrich Weigand  // Pack
234ce4c1095SUlrich Weigand  def VPKH : BinaryVRRc<"vpkh", 0xE794, z_pack, v128b, v128h, 1>;
235ce4c1095SUlrich Weigand  def VPKF : BinaryVRRc<"vpkf", 0xE794, z_pack, v128h, v128f, 2>;
236ce4c1095SUlrich Weigand  def VPKG : BinaryVRRc<"vpkg", 0xE794, z_pack, v128f, v128g, 3>;
237a8b04e1cSUlrich Weigand
238a8b04e1cSUlrich Weigand  // Pack saturate.
239a8b04e1cSUlrich Weigand  defm VPKSH : BinaryVRRbSPair<"vpksh", 0xE797, null_frag, null_frag,
240a8b04e1cSUlrich Weigand                               v128b, v128h, 1>;
241a8b04e1cSUlrich Weigand  defm VPKSF : BinaryVRRbSPair<"vpksf", 0xE797, null_frag, null_frag,
242a8b04e1cSUlrich Weigand                               v128h, v128f, 2>;
243a8b04e1cSUlrich Weigand  defm VPKSG : BinaryVRRbSPair<"vpksg", 0xE797, null_frag, null_frag,
244a8b04e1cSUlrich Weigand                               v128f, v128g, 3>;
245a8b04e1cSUlrich Weigand
246a8b04e1cSUlrich Weigand  // Pack saturate logical.
247a8b04e1cSUlrich Weigand  defm VPKLSH : BinaryVRRbSPair<"vpklsh", 0xE795, null_frag, null_frag,
248a8b04e1cSUlrich Weigand                                v128b, v128h, 1>;
249a8b04e1cSUlrich Weigand  defm VPKLSF : BinaryVRRbSPair<"vpklsf", 0xE795, null_frag, null_frag,
250a8b04e1cSUlrich Weigand                                v128h, v128f, 2>;
251a8b04e1cSUlrich Weigand  defm VPKLSG : BinaryVRRbSPair<"vpklsg", 0xE795, null_frag, null_frag,
252a8b04e1cSUlrich Weigand                                v128f, v128g, 3>;
253a8b04e1cSUlrich Weigand
254a8b04e1cSUlrich Weigand  // Sign-extend to doubleword.
255ce4c1095SUlrich Weigand  def VSEGB : UnaryVRRa<"vsegb", 0xE75F, z_vsei8,  v128g, v128g, 0>;
256ce4c1095SUlrich Weigand  def VSEGH : UnaryVRRa<"vsegh", 0xE75F, z_vsei16, v128g, v128g, 1>;
257ce4c1095SUlrich Weigand  def VSEGF : UnaryVRRa<"vsegf", 0xE75F, z_vsei32, v128g, v128g, 2>;
258ce4c1095SUlrich Weigand  def : Pat<(z_vsei8_by_parts  (v16i8 VR128:$src)), (VSEGB VR128:$src)>;
259ce4c1095SUlrich Weigand  def : Pat<(z_vsei16_by_parts (v8i16 VR128:$src)), (VSEGH VR128:$src)>;
260ce4c1095SUlrich Weigand  def : Pat<(z_vsei32_by_parts (v4i32 VR128:$src)), (VSEGF VR128:$src)>;
261a8b04e1cSUlrich Weigand
262a8b04e1cSUlrich Weigand  // Unpack high.
263a8b04e1cSUlrich Weigand  def VUPHB : UnaryVRRa<"vuphb", 0xE7D7, null_frag, v128h, v128b, 0>;
264a8b04e1cSUlrich Weigand  def VUPHH : UnaryVRRa<"vuphh", 0xE7D7, null_frag, v128f, v128h, 1>;
265a8b04e1cSUlrich Weigand  def VUPHF : UnaryVRRa<"vuphf", 0xE7D7, null_frag, v128g, v128f, 2>;
266a8b04e1cSUlrich Weigand
267a8b04e1cSUlrich Weigand  // Unpack logical high.
268a8b04e1cSUlrich Weigand  def VUPLHB : UnaryVRRa<"vuplhb", 0xE7D5, null_frag, v128h, v128b, 0>;
269a8b04e1cSUlrich Weigand  def VUPLHH : UnaryVRRa<"vuplhh", 0xE7D5, null_frag, v128f, v128h, 1>;
270a8b04e1cSUlrich Weigand  def VUPLHF : UnaryVRRa<"vuplhf", 0xE7D5, null_frag, v128g, v128f, 2>;
271a8b04e1cSUlrich Weigand
272a8b04e1cSUlrich Weigand  // Unpack low.
273a8b04e1cSUlrich Weigand  def VUPLB  : UnaryVRRa<"vuplb",  0xE7D6, null_frag, v128h, v128b, 0>;
274a8b04e1cSUlrich Weigand  def VUPLHW : UnaryVRRa<"vuplhw", 0xE7D6, null_frag, v128f, v128h, 1>;
275a8b04e1cSUlrich Weigand  def VUPLF  : UnaryVRRa<"vuplf",  0xE7D6, null_frag, v128g, v128f, 2>;
276a8b04e1cSUlrich Weigand
277a8b04e1cSUlrich Weigand  // Unpack logical low.
278a8b04e1cSUlrich Weigand  def VUPLLB : UnaryVRRa<"vupllb", 0xE7D4, null_frag, v128h, v128b, 0>;
279a8b04e1cSUlrich Weigand  def VUPLLH : UnaryVRRa<"vupllh", 0xE7D4, null_frag, v128f, v128h, 1>;
280a8b04e1cSUlrich Weigand  def VUPLLF : UnaryVRRa<"vupllf", 0xE7D4, null_frag, v128g, v128f, 2>;
281a8b04e1cSUlrich Weigand}
282a8b04e1cSUlrich Weigand
283a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
284ce4c1095SUlrich Weigand// Instantiating generic operations for specific types.
285ce4c1095SUlrich Weigand//===----------------------------------------------------------------------===//
286ce4c1095SUlrich Weigand
287ce4c1095SUlrich Weigandmulticlass GenericVectorOps<ValueType type, ValueType inttype> {
288ce4c1095SUlrich Weigand  let Predicates = [FeatureVector] in {
289ce4c1095SUlrich Weigand    def : Pat<(type (load bdxaddr12only:$addr)),
290ce4c1095SUlrich Weigand              (VL bdxaddr12only:$addr)>;
291ce4c1095SUlrich Weigand    def : Pat<(store (type VR128:$src), bdxaddr12only:$addr),
292ce4c1095SUlrich Weigand              (VST VR128:$src, bdxaddr12only:$addr)>;
293ce4c1095SUlrich Weigand    def : Pat<(type (vselect (inttype VR128:$x), VR128:$y, VR128:$z)),
294ce4c1095SUlrich Weigand              (VSEL VR128:$y, VR128:$z, VR128:$x)>;
295ce4c1095SUlrich Weigand    def : Pat<(type (vselect (inttype (z_vnot VR128:$x)), VR128:$y, VR128:$z)),
296ce4c1095SUlrich Weigand              (VSEL VR128:$z, VR128:$y, VR128:$x)>;
297ce4c1095SUlrich Weigand  }
298ce4c1095SUlrich Weigand}
299ce4c1095SUlrich Weigand
300ce4c1095SUlrich Weiganddefm : GenericVectorOps<v16i8, v16i8>;
301ce4c1095SUlrich Weiganddefm : GenericVectorOps<v8i16, v8i16>;
302ce4c1095SUlrich Weiganddefm : GenericVectorOps<v4i32, v4i32>;
303ce4c1095SUlrich Weiganddefm : GenericVectorOps<v2i64, v2i64>;
304*cd808237SUlrich Weiganddefm : GenericVectorOps<v2f64, v2i64>;
305ce4c1095SUlrich Weigand
306ce4c1095SUlrich Weigand//===----------------------------------------------------------------------===//
307a8b04e1cSUlrich Weigand// Integer arithmetic
308a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
309a8b04e1cSUlrich Weigand
310a8b04e1cSUlrich Weigandlet Predicates = [FeatureVector] in {
311a8b04e1cSUlrich Weigand  // Add.
312ce4c1095SUlrich Weigand  def VAB : BinaryVRRc<"vab", 0xE7F3, add, v128b, v128b, 0>;
313ce4c1095SUlrich Weigand  def VAH : BinaryVRRc<"vah", 0xE7F3, add, v128h, v128h, 1>;
314ce4c1095SUlrich Weigand  def VAF : BinaryVRRc<"vaf", 0xE7F3, add, v128f, v128f, 2>;
315ce4c1095SUlrich Weigand  def VAG : BinaryVRRc<"vag", 0xE7F3, add, v128g, v128g, 3>;
316a8b04e1cSUlrich Weigand  def VAQ : BinaryVRRc<"vaq", 0xE7F3, null_frag, v128q, v128q, 4>;
317a8b04e1cSUlrich Weigand
318a8b04e1cSUlrich Weigand  // Add compute carry.
319a8b04e1cSUlrich Weigand  def VACCB : BinaryVRRc<"vaccb", 0xE7F1, null_frag, v128b, v128b, 0>;
320a8b04e1cSUlrich Weigand  def VACCH : BinaryVRRc<"vacch", 0xE7F1, null_frag, v128h, v128h, 1>;
321a8b04e1cSUlrich Weigand  def VACCF : BinaryVRRc<"vaccf", 0xE7F1, null_frag, v128f, v128f, 2>;
322a8b04e1cSUlrich Weigand  def VACCG : BinaryVRRc<"vaccg", 0xE7F1, null_frag, v128g, v128g, 3>;
323a8b04e1cSUlrich Weigand  def VACCQ : BinaryVRRc<"vaccq", 0xE7F1, null_frag, v128q, v128q, 4>;
324a8b04e1cSUlrich Weigand
325a8b04e1cSUlrich Weigand  // Add with carry.
326a8b04e1cSUlrich Weigand  def VACQ : TernaryVRRd<"vacq", 0xE7BB, null_frag, v128q, v128q, 4>;
327a8b04e1cSUlrich Weigand
328a8b04e1cSUlrich Weigand  // Add with carry compute carry.
329a8b04e1cSUlrich Weigand  def VACCCQ : TernaryVRRd<"vacccq", 0xE7B9, null_frag, v128q, v128q, 4>;
330a8b04e1cSUlrich Weigand
331a8b04e1cSUlrich Weigand  // And.
332a8b04e1cSUlrich Weigand  def VN : BinaryVRRc<"vn", 0xE768, null_frag, v128any, v128any>;
333a8b04e1cSUlrich Weigand
334a8b04e1cSUlrich Weigand  // And with complement.
335a8b04e1cSUlrich Weigand  def VNC : BinaryVRRc<"vnc", 0xE769, null_frag, v128any, v128any>;
336a8b04e1cSUlrich Weigand
337a8b04e1cSUlrich Weigand  // Average.
338a8b04e1cSUlrich Weigand  def VAVGB : BinaryVRRc<"vavgb", 0xE7F2, null_frag, v128b, v128b, 0>;
339a8b04e1cSUlrich Weigand  def VAVGH : BinaryVRRc<"vavgh", 0xE7F2, null_frag, v128h, v128h, 1>;
340a8b04e1cSUlrich Weigand  def VAVGF : BinaryVRRc<"vavgf", 0xE7F2, null_frag, v128f, v128f, 2>;
341a8b04e1cSUlrich Weigand  def VAVGG : BinaryVRRc<"vavgg", 0xE7F2, null_frag, v128g, v128g, 3>;
342a8b04e1cSUlrich Weigand
343a8b04e1cSUlrich Weigand  // Average logical.
344a8b04e1cSUlrich Weigand  def VAVGLB : BinaryVRRc<"vavglb", 0xE7F0, null_frag, v128b, v128b, 0>;
345a8b04e1cSUlrich Weigand  def VAVGLH : BinaryVRRc<"vavglh", 0xE7F0, null_frag, v128h, v128h, 1>;
346a8b04e1cSUlrich Weigand  def VAVGLF : BinaryVRRc<"vavglf", 0xE7F0, null_frag, v128f, v128f, 2>;
347a8b04e1cSUlrich Weigand  def VAVGLG : BinaryVRRc<"vavglg", 0xE7F0, null_frag, v128g, v128g, 3>;
348a8b04e1cSUlrich Weigand
349a8b04e1cSUlrich Weigand  // Checksum.
350a8b04e1cSUlrich Weigand  def VCKSM : BinaryVRRc<"vcksm", 0xE766, null_frag, v128any, v128any>;
351a8b04e1cSUlrich Weigand
352a8b04e1cSUlrich Weigand  // Count leading zeros.
353ce4c1095SUlrich Weigand  def VCLZB : UnaryVRRa<"vclzb", 0xE753, ctlz, v128b, v128b, 0>;
354ce4c1095SUlrich Weigand  def VCLZH : UnaryVRRa<"vclzh", 0xE753, ctlz, v128h, v128h, 1>;
355ce4c1095SUlrich Weigand  def VCLZF : UnaryVRRa<"vclzf", 0xE753, ctlz, v128f, v128f, 2>;
356ce4c1095SUlrich Weigand  def VCLZG : UnaryVRRa<"vclzg", 0xE753, ctlz, v128g, v128g, 3>;
357a8b04e1cSUlrich Weigand
358a8b04e1cSUlrich Weigand  // Count trailing zeros.
359ce4c1095SUlrich Weigand  def VCTZB : UnaryVRRa<"vctzb", 0xE752, cttz, v128b, v128b, 0>;
360ce4c1095SUlrich Weigand  def VCTZH : UnaryVRRa<"vctzh", 0xE752, cttz, v128h, v128h, 1>;
361ce4c1095SUlrich Weigand  def VCTZF : UnaryVRRa<"vctzf", 0xE752, cttz, v128f, v128f, 2>;
362ce4c1095SUlrich Weigand  def VCTZG : UnaryVRRa<"vctzg", 0xE752, cttz, v128g, v128g, 3>;
363a8b04e1cSUlrich Weigand
364a8b04e1cSUlrich Weigand  // Exclusive or.
365a8b04e1cSUlrich Weigand  def VX : BinaryVRRc<"vx", 0xE76D, null_frag, v128any, v128any>;
366a8b04e1cSUlrich Weigand
367a8b04e1cSUlrich Weigand  // Galois field multiply sum.
368a8b04e1cSUlrich Weigand  def VGFMB : BinaryVRRc<"vgfmb", 0xE7B4, null_frag, v128b, v128b, 0>;
369a8b04e1cSUlrich Weigand  def VGFMH : BinaryVRRc<"vgfmh", 0xE7B4, null_frag, v128h, v128h, 1>;
370a8b04e1cSUlrich Weigand  def VGFMF : BinaryVRRc<"vgfmf", 0xE7B4, null_frag, v128f, v128f, 2>;
371a8b04e1cSUlrich Weigand  def VGFMG : BinaryVRRc<"vgfmg", 0xE7B4, null_frag, v128g, v128g, 3>;
372a8b04e1cSUlrich Weigand
373a8b04e1cSUlrich Weigand  // Galois field multiply sum and accumulate.
374a8b04e1cSUlrich Weigand  def VGFMAB : TernaryVRRd<"vgfmab", 0xE7BC, null_frag, v128b, v128b, 0>;
375a8b04e1cSUlrich Weigand  def VGFMAH : TernaryVRRd<"vgfmah", 0xE7BC, null_frag, v128h, v128h, 1>;
376a8b04e1cSUlrich Weigand  def VGFMAF : TernaryVRRd<"vgfmaf", 0xE7BC, null_frag, v128f, v128f, 2>;
377a8b04e1cSUlrich Weigand  def VGFMAG : TernaryVRRd<"vgfmag", 0xE7BC, null_frag, v128g, v128g, 3>;
378a8b04e1cSUlrich Weigand
379a8b04e1cSUlrich Weigand  // Load complement.
380ce4c1095SUlrich Weigand  def VLCB : UnaryVRRa<"vlcb", 0xE7DE, z_vneg, v128b, v128b, 0>;
381ce4c1095SUlrich Weigand  def VLCH : UnaryVRRa<"vlch", 0xE7DE, z_vneg, v128h, v128h, 1>;
382ce4c1095SUlrich Weigand  def VLCF : UnaryVRRa<"vlcf", 0xE7DE, z_vneg, v128f, v128f, 2>;
383ce4c1095SUlrich Weigand  def VLCG : UnaryVRRa<"vlcg", 0xE7DE, z_vneg, v128g, v128g, 3>;
384a8b04e1cSUlrich Weigand
385a8b04e1cSUlrich Weigand  // Load positive.
386ce4c1095SUlrich Weigand  def VLPB : UnaryVRRa<"vlpb", 0xE7DF, z_viabs8,  v128b, v128b, 0>;
387ce4c1095SUlrich Weigand  def VLPH : UnaryVRRa<"vlph", 0xE7DF, z_viabs16, v128h, v128h, 1>;
388ce4c1095SUlrich Weigand  def VLPF : UnaryVRRa<"vlpf", 0xE7DF, z_viabs32, v128f, v128f, 2>;
389ce4c1095SUlrich Weigand  def VLPG : UnaryVRRa<"vlpg", 0xE7DF, z_viabs64, v128g, v128g, 3>;
390a8b04e1cSUlrich Weigand
391a8b04e1cSUlrich Weigand  // Maximum.
392a8b04e1cSUlrich Weigand  def VMXB : BinaryVRRc<"vmxb", 0xE7FF, null_frag, v128b, v128b, 0>;
393a8b04e1cSUlrich Weigand  def VMXH : BinaryVRRc<"vmxh", 0xE7FF, null_frag, v128h, v128h, 1>;
394a8b04e1cSUlrich Weigand  def VMXF : BinaryVRRc<"vmxf", 0xE7FF, null_frag, v128f, v128f, 2>;
395a8b04e1cSUlrich Weigand  def VMXG : BinaryVRRc<"vmxg", 0xE7FF, null_frag, v128g, v128g, 3>;
396a8b04e1cSUlrich Weigand
397a8b04e1cSUlrich Weigand  // Maximum logical.
398a8b04e1cSUlrich Weigand  def VMXLB : BinaryVRRc<"vmxlb", 0xE7FD, null_frag, v128b, v128b, 0>;
399a8b04e1cSUlrich Weigand  def VMXLH : BinaryVRRc<"vmxlh", 0xE7FD, null_frag, v128h, v128h, 1>;
400a8b04e1cSUlrich Weigand  def VMXLF : BinaryVRRc<"vmxlf", 0xE7FD, null_frag, v128f, v128f, 2>;
401a8b04e1cSUlrich Weigand  def VMXLG : BinaryVRRc<"vmxlg", 0xE7FD, null_frag, v128g, v128g, 3>;
402a8b04e1cSUlrich Weigand
403a8b04e1cSUlrich Weigand  // Minimum.
404a8b04e1cSUlrich Weigand  def VMNB : BinaryVRRc<"vmnb", 0xE7FE, null_frag, v128b, v128b, 0>;
405a8b04e1cSUlrich Weigand  def VMNH : BinaryVRRc<"vmnh", 0xE7FE, null_frag, v128h, v128h, 1>;
406a8b04e1cSUlrich Weigand  def VMNF : BinaryVRRc<"vmnf", 0xE7FE, null_frag, v128f, v128f, 2>;
407a8b04e1cSUlrich Weigand  def VMNG : BinaryVRRc<"vmng", 0xE7FE, null_frag, v128g, v128g, 3>;
408a8b04e1cSUlrich Weigand
409a8b04e1cSUlrich Weigand  // Minimum logical.
410a8b04e1cSUlrich Weigand  def VMNLB : BinaryVRRc<"vmnlb", 0xE7FC, null_frag, v128b, v128b, 0>;
411a8b04e1cSUlrich Weigand  def VMNLH : BinaryVRRc<"vmnlh", 0xE7FC, null_frag, v128h, v128h, 1>;
412a8b04e1cSUlrich Weigand  def VMNLF : BinaryVRRc<"vmnlf", 0xE7FC, null_frag, v128f, v128f, 2>;
413a8b04e1cSUlrich Weigand  def VMNLG : BinaryVRRc<"vmnlg", 0xE7FC, null_frag, v128g, v128g, 3>;
414a8b04e1cSUlrich Weigand
415a8b04e1cSUlrich Weigand  // Multiply and add low.
416ce4c1095SUlrich Weigand  def VMALB  : TernaryVRRd<"vmalb",  0xE7AA, z_muladd, v128b, v128b, 0>;
417ce4c1095SUlrich Weigand  def VMALHW : TernaryVRRd<"vmalhw", 0xE7AA, z_muladd, v128h, v128h, 1>;
418ce4c1095SUlrich Weigand  def VMALF  : TernaryVRRd<"vmalf",  0xE7AA, z_muladd, v128f, v128f, 2>;
419a8b04e1cSUlrich Weigand
420a8b04e1cSUlrich Weigand  // Multiply and add high.
421a8b04e1cSUlrich Weigand  def VMAHB : TernaryVRRd<"vmahb", 0xE7AB, null_frag, v128b, v128b, 0>;
422a8b04e1cSUlrich Weigand  def VMAHH : TernaryVRRd<"vmahh", 0xE7AB, null_frag, v128h, v128h, 1>;
423a8b04e1cSUlrich Weigand  def VMAHF : TernaryVRRd<"vmahf", 0xE7AB, null_frag, v128f, v128f, 2>;
424a8b04e1cSUlrich Weigand
425a8b04e1cSUlrich Weigand  // Multiply and add logical high.
426a8b04e1cSUlrich Weigand  def VMALHB : TernaryVRRd<"vmalhb", 0xE7A9, null_frag, v128b, v128b, 0>;
427a8b04e1cSUlrich Weigand  def VMALHH : TernaryVRRd<"vmalhh", 0xE7A9, null_frag, v128h, v128h, 1>;
428a8b04e1cSUlrich Weigand  def VMALHF : TernaryVRRd<"vmalhf", 0xE7A9, null_frag, v128f, v128f, 2>;
429a8b04e1cSUlrich Weigand
430a8b04e1cSUlrich Weigand  // Multiply and add even.
431a8b04e1cSUlrich Weigand  def VMAEB : TernaryVRRd<"vmaeb", 0xE7AE, null_frag, v128h, v128b, 0>;
432a8b04e1cSUlrich Weigand  def VMAEH : TernaryVRRd<"vmaeh", 0xE7AE, null_frag, v128f, v128h, 1>;
433a8b04e1cSUlrich Weigand  def VMAEF : TernaryVRRd<"vmaef", 0xE7AE, null_frag, v128g, v128f, 2>;
434a8b04e1cSUlrich Weigand
435a8b04e1cSUlrich Weigand  // Multiply and add logical even.
436a8b04e1cSUlrich Weigand  def VMALEB : TernaryVRRd<"vmaleb", 0xE7AC, null_frag, v128h, v128b, 0>;
437a8b04e1cSUlrich Weigand  def VMALEH : TernaryVRRd<"vmaleh", 0xE7AC, null_frag, v128f, v128h, 1>;
438a8b04e1cSUlrich Weigand  def VMALEF : TernaryVRRd<"vmalef", 0xE7AC, null_frag, v128g, v128f, 2>;
439a8b04e1cSUlrich Weigand
440a8b04e1cSUlrich Weigand  // Multiply and add odd.
441a8b04e1cSUlrich Weigand  def VMAOB : TernaryVRRd<"vmaob", 0xE7AF, null_frag, v128h, v128b, 0>;
442a8b04e1cSUlrich Weigand  def VMAOH : TernaryVRRd<"vmaoh", 0xE7AF, null_frag, v128f, v128h, 1>;
443a8b04e1cSUlrich Weigand  def VMAOF : TernaryVRRd<"vmaof", 0xE7AF, null_frag, v128g, v128f, 2>;
444a8b04e1cSUlrich Weigand
445a8b04e1cSUlrich Weigand  // Multiply and add logical odd.
446a8b04e1cSUlrich Weigand  def VMALOB : TernaryVRRd<"vmalob", 0xE7AD, null_frag, v128h, v128b, 0>;
447a8b04e1cSUlrich Weigand  def VMALOH : TernaryVRRd<"vmaloh", 0xE7AD, null_frag, v128f, v128h, 1>;
448a8b04e1cSUlrich Weigand  def VMALOF : TernaryVRRd<"vmalof", 0xE7AD, null_frag, v128g, v128f, 2>;
449a8b04e1cSUlrich Weigand
450a8b04e1cSUlrich Weigand  // Multiply high.
451a8b04e1cSUlrich Weigand  def VMHB : BinaryVRRc<"vmhb", 0xE7A3, null_frag, v128b, v128b, 0>;
452a8b04e1cSUlrich Weigand  def VMHH : BinaryVRRc<"vmhh", 0xE7A3, null_frag, v128h, v128h, 1>;
453a8b04e1cSUlrich Weigand  def VMHF : BinaryVRRc<"vmhf", 0xE7A3, null_frag, v128f, v128f, 2>;
454a8b04e1cSUlrich Weigand
455a8b04e1cSUlrich Weigand  // Multiply logical high.
456a8b04e1cSUlrich Weigand  def VMLHB : BinaryVRRc<"vmlhb", 0xE7A1, null_frag, v128b, v128b, 0>;
457a8b04e1cSUlrich Weigand  def VMLHH : BinaryVRRc<"vmlhh", 0xE7A1, null_frag, v128h, v128h, 1>;
458a8b04e1cSUlrich Weigand  def VMLHF : BinaryVRRc<"vmlhf", 0xE7A1, null_frag, v128f, v128f, 2>;
459a8b04e1cSUlrich Weigand
460a8b04e1cSUlrich Weigand  // Multiply low.
461ce4c1095SUlrich Weigand  def VMLB  : BinaryVRRc<"vmlb",  0xE7A2, mul, v128b, v128b, 0>;
462ce4c1095SUlrich Weigand  def VMLHW : BinaryVRRc<"vmlhw", 0xE7A2, mul, v128h, v128h, 1>;
463ce4c1095SUlrich Weigand  def VMLF  : BinaryVRRc<"vmlf",  0xE7A2, mul, v128f, v128f, 2>;
464a8b04e1cSUlrich Weigand
465a8b04e1cSUlrich Weigand  // Multiply even.
466a8b04e1cSUlrich Weigand  def VMEB : BinaryVRRc<"vmeb", 0xE7A6, null_frag, v128h, v128b, 0>;
467a8b04e1cSUlrich Weigand  def VMEH : BinaryVRRc<"vmeh", 0xE7A6, null_frag, v128f, v128h, 1>;
468a8b04e1cSUlrich Weigand  def VMEF : BinaryVRRc<"vmef", 0xE7A6, null_frag, v128g, v128f, 2>;
469a8b04e1cSUlrich Weigand
470a8b04e1cSUlrich Weigand  // Multiply logical even.
471a8b04e1cSUlrich Weigand  def VMLEB : BinaryVRRc<"vmleb", 0xE7A4, null_frag, v128h, v128b, 0>;
472a8b04e1cSUlrich Weigand  def VMLEH : BinaryVRRc<"vmleh", 0xE7A4, null_frag, v128f, v128h, 1>;
473a8b04e1cSUlrich Weigand  def VMLEF : BinaryVRRc<"vmlef", 0xE7A4, null_frag, v128g, v128f, 2>;
474a8b04e1cSUlrich Weigand
475a8b04e1cSUlrich Weigand  // Multiply odd.
476a8b04e1cSUlrich Weigand  def VMOB : BinaryVRRc<"vmob", 0xE7A7, null_frag, v128h, v128b, 0>;
477a8b04e1cSUlrich Weigand  def VMOH : BinaryVRRc<"vmoh", 0xE7A7, null_frag, v128f, v128h, 1>;
478a8b04e1cSUlrich Weigand  def VMOF : BinaryVRRc<"vmof", 0xE7A7, null_frag, v128g, v128f, 2>;
479a8b04e1cSUlrich Weigand
480a8b04e1cSUlrich Weigand  // Multiply logical odd.
481a8b04e1cSUlrich Weigand  def VMLOB : BinaryVRRc<"vmlob", 0xE7A5, null_frag, v128h, v128b, 0>;
482a8b04e1cSUlrich Weigand  def VMLOH : BinaryVRRc<"vmloh", 0xE7A5, null_frag, v128f, v128h, 1>;
483a8b04e1cSUlrich Weigand  def VMLOF : BinaryVRRc<"vmlof", 0xE7A5, null_frag, v128g, v128f, 2>;
484a8b04e1cSUlrich Weigand
485a8b04e1cSUlrich Weigand  // Nor.
486a8b04e1cSUlrich Weigand  def VNO : BinaryVRRc<"vno", 0xE76B, null_frag, v128any, v128any>;
487a8b04e1cSUlrich Weigand
488a8b04e1cSUlrich Weigand  // Or.
489a8b04e1cSUlrich Weigand  def VO : BinaryVRRc<"vo", 0xE76A, null_frag, v128any, v128any>;
490a8b04e1cSUlrich Weigand
491a8b04e1cSUlrich Weigand  // Population count.
492a8b04e1cSUlrich Weigand  def VPOPCT : BinaryVRRa<"vpopct", 0xE750>;
493ce4c1095SUlrich Weigand  def : Pat<(v16i8 (z_popcnt VR128:$x)), (VPOPCT VR128:$x, 0)>;
494a8b04e1cSUlrich Weigand
495a8b04e1cSUlrich Weigand  // Element rotate left logical (with vector shift amount).
496a8b04e1cSUlrich Weigand  def VERLLVB : BinaryVRRc<"verllvb", 0xE773, null_frag, v128b, v128b, 0>;
497a8b04e1cSUlrich Weigand  def VERLLVH : BinaryVRRc<"verllvh", 0xE773, null_frag, v128h, v128h, 1>;
498a8b04e1cSUlrich Weigand  def VERLLVF : BinaryVRRc<"verllvf", 0xE773, null_frag, v128f, v128f, 2>;
499a8b04e1cSUlrich Weigand  def VERLLVG : BinaryVRRc<"verllvg", 0xE773, null_frag, v128g, v128g, 3>;
500a8b04e1cSUlrich Weigand
501a8b04e1cSUlrich Weigand  // Element rotate left logical (with scalar shift amount).
502a8b04e1cSUlrich Weigand  def VERLLB : BinaryVRSa<"verllb", 0xE733, null_frag, v128b, v128b, 0>;
503a8b04e1cSUlrich Weigand  def VERLLH : BinaryVRSa<"verllh", 0xE733, null_frag, v128h, v128h, 1>;
504a8b04e1cSUlrich Weigand  def VERLLF : BinaryVRSa<"verllf", 0xE733, null_frag, v128f, v128f, 2>;
505a8b04e1cSUlrich Weigand  def VERLLG : BinaryVRSa<"verllg", 0xE733, null_frag, v128g, v128g, 3>;
506a8b04e1cSUlrich Weigand
507a8b04e1cSUlrich Weigand  // Element rotate and insert under mask.
508a8b04e1cSUlrich Weigand  def VERIMB : QuaternaryVRId<"verimb", 0xE772, null_frag, v128b, v128b, 0>;
509a8b04e1cSUlrich Weigand  def VERIMH : QuaternaryVRId<"verimh", 0xE772, null_frag, v128h, v128h, 1>;
510a8b04e1cSUlrich Weigand  def VERIMF : QuaternaryVRId<"verimf", 0xE772, null_frag, v128f, v128f, 2>;
511a8b04e1cSUlrich Weigand  def VERIMG : QuaternaryVRId<"verimg", 0xE772, null_frag, v128g, v128g, 3>;
512a8b04e1cSUlrich Weigand
513a8b04e1cSUlrich Weigand  // Element shift left (with vector shift amount).
514ce4c1095SUlrich Weigand  def VESLVB : BinaryVRRc<"veslvb", 0xE770, z_vshl, v128b, v128b, 0>;
515ce4c1095SUlrich Weigand  def VESLVH : BinaryVRRc<"veslvh", 0xE770, z_vshl, v128h, v128h, 1>;
516ce4c1095SUlrich Weigand  def VESLVF : BinaryVRRc<"veslvf", 0xE770, z_vshl, v128f, v128f, 2>;
517ce4c1095SUlrich Weigand  def VESLVG : BinaryVRRc<"veslvg", 0xE770, z_vshl, v128g, v128g, 3>;
518a8b04e1cSUlrich Weigand
519a8b04e1cSUlrich Weigand  // Element shift left (with scalar shift amount).
520ce4c1095SUlrich Weigand  def VESLB : BinaryVRSa<"veslb", 0xE730, z_vshl_by_scalar, v128b, v128b, 0>;
521ce4c1095SUlrich Weigand  def VESLH : BinaryVRSa<"veslh", 0xE730, z_vshl_by_scalar, v128h, v128h, 1>;
522ce4c1095SUlrich Weigand  def VESLF : BinaryVRSa<"veslf", 0xE730, z_vshl_by_scalar, v128f, v128f, 2>;
523ce4c1095SUlrich Weigand  def VESLG : BinaryVRSa<"veslg", 0xE730, z_vshl_by_scalar, v128g, v128g, 3>;
524a8b04e1cSUlrich Weigand
525a8b04e1cSUlrich Weigand  // Element shift right arithmetic (with vector shift amount).
526ce4c1095SUlrich Weigand  def VESRAVB : BinaryVRRc<"vesravb", 0xE77A, z_vsra, v128b, v128b, 0>;
527ce4c1095SUlrich Weigand  def VESRAVH : BinaryVRRc<"vesravh", 0xE77A, z_vsra, v128h, v128h, 1>;
528ce4c1095SUlrich Weigand  def VESRAVF : BinaryVRRc<"vesravf", 0xE77A, z_vsra, v128f, v128f, 2>;
529ce4c1095SUlrich Weigand  def VESRAVG : BinaryVRRc<"vesravg", 0xE77A, z_vsra, v128g, v128g, 3>;
530a8b04e1cSUlrich Weigand
531a8b04e1cSUlrich Weigand  // Element shift right arithmetic (with scalar shift amount).
532ce4c1095SUlrich Weigand  def VESRAB : BinaryVRSa<"vesrab", 0xE73A, z_vsra_by_scalar, v128b, v128b, 0>;
533ce4c1095SUlrich Weigand  def VESRAH : BinaryVRSa<"vesrah", 0xE73A, z_vsra_by_scalar, v128h, v128h, 1>;
534ce4c1095SUlrich Weigand  def VESRAF : BinaryVRSa<"vesraf", 0xE73A, z_vsra_by_scalar, v128f, v128f, 2>;
535ce4c1095SUlrich Weigand  def VESRAG : BinaryVRSa<"vesrag", 0xE73A, z_vsra_by_scalar, v128g, v128g, 3>;
536a8b04e1cSUlrich Weigand
537a8b04e1cSUlrich Weigand  // Element shift right logical (with vector shift amount).
538ce4c1095SUlrich Weigand  def VESRLVB : BinaryVRRc<"vesrlvb", 0xE778, z_vsrl, v128b, v128b, 0>;
539ce4c1095SUlrich Weigand  def VESRLVH : BinaryVRRc<"vesrlvh", 0xE778, z_vsrl, v128h, v128h, 1>;
540ce4c1095SUlrich Weigand  def VESRLVF : BinaryVRRc<"vesrlvf", 0xE778, z_vsrl, v128f, v128f, 2>;
541ce4c1095SUlrich Weigand  def VESRLVG : BinaryVRRc<"vesrlvg", 0xE778, z_vsrl, v128g, v128g, 3>;
542a8b04e1cSUlrich Weigand
543a8b04e1cSUlrich Weigand  // Element shift right logical (with scalar shift amount).
544ce4c1095SUlrich Weigand  def VESRLB : BinaryVRSa<"vesrlb", 0xE738, z_vsrl_by_scalar, v128b, v128b, 0>;
545ce4c1095SUlrich Weigand  def VESRLH : BinaryVRSa<"vesrlh", 0xE738, z_vsrl_by_scalar, v128h, v128h, 1>;
546ce4c1095SUlrich Weigand  def VESRLF : BinaryVRSa<"vesrlf", 0xE738, z_vsrl_by_scalar, v128f, v128f, 2>;
547ce4c1095SUlrich Weigand  def VESRLG : BinaryVRSa<"vesrlg", 0xE738, z_vsrl_by_scalar, v128g, v128g, 3>;
548a8b04e1cSUlrich Weigand
549a8b04e1cSUlrich Weigand  // Shift left.
550a8b04e1cSUlrich Weigand  def VSL : BinaryVRRc<"vsl", 0xE774, null_frag, v128b, v128b>;
551a8b04e1cSUlrich Weigand
552a8b04e1cSUlrich Weigand  // Shift left by byte.
553a8b04e1cSUlrich Weigand  def VSLB : BinaryVRRc<"vslb", 0xE775, null_frag, v128b, v128b>;
554a8b04e1cSUlrich Weigand
555a8b04e1cSUlrich Weigand  // Shift left double by byte.
556ce4c1095SUlrich Weigand  def VSLDB : TernaryVRId<"vsldb", 0xE777, z_shl_double, v128b, v128b, 0>;
557a8b04e1cSUlrich Weigand
558a8b04e1cSUlrich Weigand  // Shift right arithmetic.
559a8b04e1cSUlrich Weigand  def VSRA : BinaryVRRc<"vsra", 0xE77E, null_frag, v128b, v128b>;
560a8b04e1cSUlrich Weigand
561a8b04e1cSUlrich Weigand  // Shift right arithmetic by byte.
562a8b04e1cSUlrich Weigand  def VSRAB : BinaryVRRc<"vsrab", 0xE77F, null_frag, v128b, v128b>;
563a8b04e1cSUlrich Weigand
564a8b04e1cSUlrich Weigand  // Shift right logical.
565a8b04e1cSUlrich Weigand  def VSRL : BinaryVRRc<"vsrl", 0xE77C, null_frag, v128b, v128b>;
566a8b04e1cSUlrich Weigand
567a8b04e1cSUlrich Weigand  // Shift right logical by byte.
568a8b04e1cSUlrich Weigand  def VSRLB : BinaryVRRc<"vsrlb", 0xE77D, null_frag, v128b, v128b>;
569a8b04e1cSUlrich Weigand
570a8b04e1cSUlrich Weigand  // Subtract.
571ce4c1095SUlrich Weigand  def VSB : BinaryVRRc<"vsb", 0xE7F7, sub, v128b, v128b, 0>;
572ce4c1095SUlrich Weigand  def VSH : BinaryVRRc<"vsh", 0xE7F7, sub, v128h, v128h, 1>;
573ce4c1095SUlrich Weigand  def VSF : BinaryVRRc<"vsf", 0xE7F7, sub, v128f, v128f, 2>;
574ce4c1095SUlrich Weigand  def VSG : BinaryVRRc<"vsg", 0xE7F7, sub, v128g, v128g, 3>;
575a8b04e1cSUlrich Weigand  def VSQ : BinaryVRRc<"vsq", 0xE7F7, null_frag, v128q, v128q, 4>;
576a8b04e1cSUlrich Weigand
577a8b04e1cSUlrich Weigand  // Subtract compute borrow indication.
578a8b04e1cSUlrich Weigand  def VSCBIB : BinaryVRRc<"vscbib", 0xE7F5, null_frag, v128b, v128b, 0>;
579a8b04e1cSUlrich Weigand  def VSCBIH : BinaryVRRc<"vscbih", 0xE7F5, null_frag, v128h, v128h, 1>;
580a8b04e1cSUlrich Weigand  def VSCBIF : BinaryVRRc<"vscbif", 0xE7F5, null_frag, v128f, v128f, 2>;
581a8b04e1cSUlrich Weigand  def VSCBIG : BinaryVRRc<"vscbig", 0xE7F5, null_frag, v128g, v128g, 3>;
582a8b04e1cSUlrich Weigand  def VSCBIQ : BinaryVRRc<"vscbiq", 0xE7F5, null_frag, v128q, v128q, 4>;
583a8b04e1cSUlrich Weigand
584a8b04e1cSUlrich Weigand  // Subtract with borrow indication.
585a8b04e1cSUlrich Weigand  def VSBIQ : TernaryVRRd<"vsbiq", 0xE7BF, null_frag, v128q, v128q, 4>;
586a8b04e1cSUlrich Weigand
587a8b04e1cSUlrich Weigand  // Subtract with borrow compute borrow indication.
588a8b04e1cSUlrich Weigand  def VSBCBIQ : TernaryVRRd<"vsbcbiq", 0xE7BD, null_frag, v128q, v128q, 4>;
589a8b04e1cSUlrich Weigand
590a8b04e1cSUlrich Weigand  // Sum across doubleword.
591ce4c1095SUlrich Weigand  def VSUMGH : BinaryVRRc<"vsumgh", 0xE765, z_vsum, v128g, v128h, 1>;
592ce4c1095SUlrich Weigand  def VSUMGF : BinaryVRRc<"vsumgf", 0xE765, z_vsum, v128g, v128f, 2>;
593a8b04e1cSUlrich Weigand
594a8b04e1cSUlrich Weigand  // Sum across quadword.
595ce4c1095SUlrich Weigand  def VSUMQF : BinaryVRRc<"vsumqf", 0xE767, z_vsum, v128q, v128f, 2>;
596ce4c1095SUlrich Weigand  def VSUMQG : BinaryVRRc<"vsumqg", 0xE767, z_vsum, v128q, v128g, 3>;
597a8b04e1cSUlrich Weigand
598a8b04e1cSUlrich Weigand  // Sum across word.
599ce4c1095SUlrich Weigand  def VSUMB : BinaryVRRc<"vsumb", 0xE764, z_vsum, v128f, v128b, 0>;
600ce4c1095SUlrich Weigand  def VSUMH : BinaryVRRc<"vsumh", 0xE764, z_vsum, v128f, v128h, 1>;
601a8b04e1cSUlrich Weigand}
602a8b04e1cSUlrich Weigand
603ce4c1095SUlrich Weigand// Instantiate the bitwise ops for type TYPE.
604ce4c1095SUlrich Weigandmulticlass BitwiseVectorOps<ValueType type> {
605ce4c1095SUlrich Weigand  let Predicates = [FeatureVector] in {
606ce4c1095SUlrich Weigand    def : Pat<(type (and VR128:$x, VR128:$y)), (VN VR128:$x, VR128:$y)>;
607ce4c1095SUlrich Weigand    def : Pat<(type (and VR128:$x, (z_vnot VR128:$y))),
608ce4c1095SUlrich Weigand              (VNC VR128:$x, VR128:$y)>;
609ce4c1095SUlrich Weigand    def : Pat<(type (or VR128:$x, VR128:$y)), (VO VR128:$x, VR128:$y)>;
610ce4c1095SUlrich Weigand    def : Pat<(type (xor VR128:$x, VR128:$y)), (VX VR128:$x, VR128:$y)>;
611ce4c1095SUlrich Weigand    def : Pat<(type (or (and VR128:$x, VR128:$z),
612ce4c1095SUlrich Weigand                        (and VR128:$y, (z_vnot VR128:$z)))),
613ce4c1095SUlrich Weigand              (VSEL VR128:$x, VR128:$y, VR128:$z)>;
614ce4c1095SUlrich Weigand    def : Pat<(type (z_vnot (or VR128:$x, VR128:$y))),
615ce4c1095SUlrich Weigand              (VNO VR128:$x, VR128:$y)>;
616ce4c1095SUlrich Weigand    def : Pat<(type (z_vnot VR128:$x)), (VNO VR128:$x, VR128:$x)>;
617ce4c1095SUlrich Weigand  }
618ce4c1095SUlrich Weigand}
619ce4c1095SUlrich Weigand
620ce4c1095SUlrich Weiganddefm : BitwiseVectorOps<v16i8>;
621ce4c1095SUlrich Weiganddefm : BitwiseVectorOps<v8i16>;
622ce4c1095SUlrich Weiganddefm : BitwiseVectorOps<v4i32>;
623ce4c1095SUlrich Weiganddefm : BitwiseVectorOps<v2i64>;
624ce4c1095SUlrich Weigand
625ce4c1095SUlrich Weigand// Instantiate additional patterns for absolute-related expressions on
626ce4c1095SUlrich Weigand// type TYPE.  LC is the negate instruction for TYPE and LP is the absolute
627ce4c1095SUlrich Weigand// instruction.
628ce4c1095SUlrich Weigandmulticlass IntegerAbsoluteVectorOps<ValueType type, Instruction lc,
629ce4c1095SUlrich Weigand                                    Instruction lp, int shift> {
630ce4c1095SUlrich Weigand  let Predicates = [FeatureVector] in {
631ce4c1095SUlrich Weigand    def : Pat<(type (vselect (type (z_vicmph_zero VR128:$x)),
632ce4c1095SUlrich Weigand                             (z_vneg VR128:$x), VR128:$x)),
633ce4c1095SUlrich Weigand              (lc (lp VR128:$x))>;
634ce4c1095SUlrich Weigand    def : Pat<(type (vselect (type (z_vnot (z_vicmph_zero VR128:$x))),
635ce4c1095SUlrich Weigand                             VR128:$x, (z_vneg VR128:$x))),
636ce4c1095SUlrich Weigand              (lc (lp VR128:$x))>;
637ce4c1095SUlrich Weigand    def : Pat<(type (vselect (type (z_vicmpl_zero VR128:$x)),
638ce4c1095SUlrich Weigand                             VR128:$x, (z_vneg VR128:$x))),
639ce4c1095SUlrich Weigand              (lc (lp VR128:$x))>;
640ce4c1095SUlrich Weigand    def : Pat<(type (vselect (type (z_vnot (z_vicmpl_zero VR128:$x))),
641ce4c1095SUlrich Weigand                             (z_vneg VR128:$x), VR128:$x)),
642ce4c1095SUlrich Weigand              (lc (lp VR128:$x))>;
643ce4c1095SUlrich Weigand    def : Pat<(type (or (and (z_vsra_by_scalar VR128:$x, (i32 shift)),
644ce4c1095SUlrich Weigand                             (z_vneg VR128:$x)),
645ce4c1095SUlrich Weigand                        (and (z_vnot (z_vsra_by_scalar VR128:$x, (i32 shift))),
646ce4c1095SUlrich Weigand                             VR128:$x))),
647ce4c1095SUlrich Weigand              (lp VR128:$x)>;
648ce4c1095SUlrich Weigand    def : Pat<(type (or (and (z_vsra_by_scalar VR128:$x, (i32 shift)),
649ce4c1095SUlrich Weigand                             VR128:$x),
650ce4c1095SUlrich Weigand                        (and (z_vnot (z_vsra_by_scalar VR128:$x, (i32 shift))),
651ce4c1095SUlrich Weigand                             (z_vneg VR128:$x)))),
652ce4c1095SUlrich Weigand              (lc (lp VR128:$x))>;
653ce4c1095SUlrich Weigand  }
654ce4c1095SUlrich Weigand}
655ce4c1095SUlrich Weigand
656ce4c1095SUlrich Weiganddefm : IntegerAbsoluteVectorOps<v16i8, VLCB, VLPB, 7>;
657ce4c1095SUlrich Weiganddefm : IntegerAbsoluteVectorOps<v8i16, VLCH, VLPH, 15>;
658ce4c1095SUlrich Weiganddefm : IntegerAbsoluteVectorOps<v4i32, VLCF, VLPF, 31>;
659ce4c1095SUlrich Weiganddefm : IntegerAbsoluteVectorOps<v2i64, VLCG, VLPG, 63>;
660ce4c1095SUlrich Weigand
661ce4c1095SUlrich Weigand// Instantiate minimum- and maximum-related patterns for TYPE.  CMPH is the
662ce4c1095SUlrich Weigand// signed or unsigned "set if greater than" comparison instruction and
663ce4c1095SUlrich Weigand// MIN and MAX are the associated minimum and maximum instructions.
664ce4c1095SUlrich Weigandmulticlass IntegerMinMaxVectorOps<ValueType type, SDPatternOperator cmph,
665ce4c1095SUlrich Weigand                                  Instruction min, Instruction max> {
666ce4c1095SUlrich Weigand  let Predicates = [FeatureVector] in {
667ce4c1095SUlrich Weigand    def : Pat<(type (vselect (cmph VR128:$x, VR128:$y), VR128:$x, VR128:$y)),
668ce4c1095SUlrich Weigand              (max VR128:$x, VR128:$y)>;
669ce4c1095SUlrich Weigand    def : Pat<(type (vselect (cmph VR128:$x, VR128:$y), VR128:$y, VR128:$x)),
670ce4c1095SUlrich Weigand              (min VR128:$x, VR128:$y)>;
671ce4c1095SUlrich Weigand    def : Pat<(type (vselect (z_vnot (cmph VR128:$x, VR128:$y)),
672ce4c1095SUlrich Weigand                             VR128:$x, VR128:$y)),
673ce4c1095SUlrich Weigand              (min VR128:$x, VR128:$y)>;
674ce4c1095SUlrich Weigand    def : Pat<(type (vselect (z_vnot (cmph VR128:$x, VR128:$y)),
675ce4c1095SUlrich Weigand                             VR128:$y, VR128:$x)),
676ce4c1095SUlrich Weigand              (max VR128:$x, VR128:$y)>;
677ce4c1095SUlrich Weigand  }
678ce4c1095SUlrich Weigand}
679ce4c1095SUlrich Weigand
680ce4c1095SUlrich Weigand// Signed min/max.
681ce4c1095SUlrich Weiganddefm : IntegerMinMaxVectorOps<v16i8, z_vicmph, VMNB, VMXB>;
682ce4c1095SUlrich Weiganddefm : IntegerMinMaxVectorOps<v8i16, z_vicmph, VMNH, VMXH>;
683ce4c1095SUlrich Weiganddefm : IntegerMinMaxVectorOps<v4i32, z_vicmph, VMNF, VMXF>;
684ce4c1095SUlrich Weiganddefm : IntegerMinMaxVectorOps<v2i64, z_vicmph, VMNG, VMXG>;
685ce4c1095SUlrich Weigand
686ce4c1095SUlrich Weigand// Unsigned min/max.
687ce4c1095SUlrich Weiganddefm : IntegerMinMaxVectorOps<v16i8, z_vicmphl, VMNLB, VMXLB>;
688ce4c1095SUlrich Weiganddefm : IntegerMinMaxVectorOps<v8i16, z_vicmphl, VMNLH, VMXLH>;
689ce4c1095SUlrich Weiganddefm : IntegerMinMaxVectorOps<v4i32, z_vicmphl, VMNLF, VMXLF>;
690ce4c1095SUlrich Weiganddefm : IntegerMinMaxVectorOps<v2i64, z_vicmphl, VMNLG, VMXLG>;
691ce4c1095SUlrich Weigand
692a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
693a8b04e1cSUlrich Weigand// Integer comparison
694a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
695a8b04e1cSUlrich Weigand
696a8b04e1cSUlrich Weigandlet Predicates = [FeatureVector] in {
697a8b04e1cSUlrich Weigand  // Element compare.
698a8b04e1cSUlrich Weigand  let Defs = [CC] in {
699a8b04e1cSUlrich Weigand    def VECB : CompareVRRa<"vecb", 0xE7DB, null_frag, v128b, 0>;
700a8b04e1cSUlrich Weigand    def VECH : CompareVRRa<"vech", 0xE7DB, null_frag, v128h, 1>;
701a8b04e1cSUlrich Weigand    def VECF : CompareVRRa<"vecf", 0xE7DB, null_frag, v128f, 2>;
702a8b04e1cSUlrich Weigand    def VECG : CompareVRRa<"vecg", 0xE7DB, null_frag, v128g, 3>;
703a8b04e1cSUlrich Weigand  }
704a8b04e1cSUlrich Weigand
705a8b04e1cSUlrich Weigand  // Element compare logical.
706a8b04e1cSUlrich Weigand  let Defs = [CC] in {
707a8b04e1cSUlrich Weigand    def VECLB : CompareVRRa<"veclb", 0xE7D9, null_frag, v128b, 0>;
708a8b04e1cSUlrich Weigand    def VECLH : CompareVRRa<"veclh", 0xE7D9, null_frag, v128h, 1>;
709a8b04e1cSUlrich Weigand    def VECLF : CompareVRRa<"veclf", 0xE7D9, null_frag, v128f, 2>;
710a8b04e1cSUlrich Weigand    def VECLG : CompareVRRa<"veclg", 0xE7D9, null_frag, v128g, 3>;
711a8b04e1cSUlrich Weigand  }
712a8b04e1cSUlrich Weigand
713a8b04e1cSUlrich Weigand  // Compare equal.
714ce4c1095SUlrich Weigand  defm VCEQB : BinaryVRRbSPair<"vceqb", 0xE7F8, z_vicmpe, null_frag,
715a8b04e1cSUlrich Weigand                               v128b, v128b, 0>;
716ce4c1095SUlrich Weigand  defm VCEQH : BinaryVRRbSPair<"vceqh", 0xE7F8, z_vicmpe, null_frag,
717a8b04e1cSUlrich Weigand                               v128h, v128h, 1>;
718ce4c1095SUlrich Weigand  defm VCEQF : BinaryVRRbSPair<"vceqf", 0xE7F8, z_vicmpe, null_frag,
719a8b04e1cSUlrich Weigand                               v128f, v128f, 2>;
720ce4c1095SUlrich Weigand  defm VCEQG : BinaryVRRbSPair<"vceqg", 0xE7F8, z_vicmpe, null_frag,
721a8b04e1cSUlrich Weigand                               v128g, v128g, 3>;
722a8b04e1cSUlrich Weigand
723a8b04e1cSUlrich Weigand  // Compare high.
724ce4c1095SUlrich Weigand  defm VCHB : BinaryVRRbSPair<"vchb", 0xE7FB, z_vicmph, null_frag,
725a8b04e1cSUlrich Weigand                              v128b, v128b, 0>;
726ce4c1095SUlrich Weigand  defm VCHH : BinaryVRRbSPair<"vchh", 0xE7FB, z_vicmph, null_frag,
727a8b04e1cSUlrich Weigand                              v128h, v128h, 1>;
728ce4c1095SUlrich Weigand  defm VCHF : BinaryVRRbSPair<"vchf", 0xE7FB, z_vicmph, null_frag,
729a8b04e1cSUlrich Weigand                              v128f, v128f, 2>;
730ce4c1095SUlrich Weigand  defm VCHG : BinaryVRRbSPair<"vchg", 0xE7FB, z_vicmph, null_frag,
731a8b04e1cSUlrich Weigand                              v128g, v128g, 3>;
732a8b04e1cSUlrich Weigand
733a8b04e1cSUlrich Weigand  // Compare high logical.
734ce4c1095SUlrich Weigand  defm VCHLB : BinaryVRRbSPair<"vchlb", 0xE7F9, z_vicmphl, null_frag,
735a8b04e1cSUlrich Weigand                               v128b, v128b, 0>;
736ce4c1095SUlrich Weigand  defm VCHLH : BinaryVRRbSPair<"vchlh", 0xE7F9, z_vicmphl, null_frag,
737a8b04e1cSUlrich Weigand                               v128h, v128h, 1>;
738ce4c1095SUlrich Weigand  defm VCHLF : BinaryVRRbSPair<"vchlf", 0xE7F9, z_vicmphl, null_frag,
739a8b04e1cSUlrich Weigand                               v128f, v128f, 2>;
740ce4c1095SUlrich Weigand  defm VCHLG : BinaryVRRbSPair<"vchlg", 0xE7F9, z_vicmphl, null_frag,
741a8b04e1cSUlrich Weigand                               v128g, v128g, 3>;
742a8b04e1cSUlrich Weigand
743a8b04e1cSUlrich Weigand  // Test under mask.
744a8b04e1cSUlrich Weigand  let Defs = [CC] in
745a8b04e1cSUlrich Weigand    def VTM : CompareVRRa<"vtm", 0xE7D8, null_frag, v128any, 0>;
746a8b04e1cSUlrich Weigand}
747a8b04e1cSUlrich Weigand
748a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
749a8b04e1cSUlrich Weigand// Floating-point arithmetic
750a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
751a8b04e1cSUlrich Weigand
752*cd808237SUlrich Weigand// See comments in SystemZInstrFP.td for the suppression flags and
753*cd808237SUlrich Weigand// rounding modes.
754*cd808237SUlrich Weigandmulticlass VectorRounding<Instruction insn, TypedReg tr> {
755*cd808237SUlrich Weigand  def : FPConversion<insn, frint,      tr, tr, 0, 0>;
756*cd808237SUlrich Weigand  def : FPConversion<insn, fnearbyint, tr, tr, 4, 0>;
757*cd808237SUlrich Weigand  def : FPConversion<insn, ffloor,     tr, tr, 4, 7>;
758*cd808237SUlrich Weigand  def : FPConversion<insn, fceil,      tr, tr, 4, 6>;
759*cd808237SUlrich Weigand  def : FPConversion<insn, ftrunc,     tr, tr, 4, 5>;
760*cd808237SUlrich Weigand  def : FPConversion<insn, frnd,       tr, tr, 4, 1>;
761*cd808237SUlrich Weigand}
762*cd808237SUlrich Weigand
763a8b04e1cSUlrich Weigandlet Predicates = [FeatureVector] in {
764a8b04e1cSUlrich Weigand  // Add.
765*cd808237SUlrich Weigand  def VFADB : BinaryVRRc<"vfadb", 0xE7E3, fadd, v128db, v128db, 3, 0>;
766a8b04e1cSUlrich Weigand  def WFADB : BinaryVRRc<"wfadb", 0xE7E3, null_frag, v64db, v64db, 3, 8>;
767a8b04e1cSUlrich Weigand
768a8b04e1cSUlrich Weigand  // Convert from fixed 64-bit.
769a8b04e1cSUlrich Weigand  def VCDGB : TernaryVRRa<"vcdgb", 0xE7C3, null_frag, v128db, v128g, 3, 0>;
770a8b04e1cSUlrich Weigand  def WCDGB : TernaryVRRa<"wcdgb", 0xE7C3, null_frag, v64db, v64g, 3, 8>;
771*cd808237SUlrich Weigand  def : FPConversion<VCDGB, sint_to_fp, v128db, v128g, 0, 0>;
772a8b04e1cSUlrich Weigand
773a8b04e1cSUlrich Weigand  // Convert from logical 64-bit.
774a8b04e1cSUlrich Weigand  def VCDLGB : TernaryVRRa<"vcdlgb", 0xE7C1, null_frag, v128db, v128g, 3, 0>;
775a8b04e1cSUlrich Weigand  def WCDLGB : TernaryVRRa<"wcdlgb", 0xE7C1, null_frag, v64db, v64g, 3, 8>;
776*cd808237SUlrich Weigand  def : FPConversion<VCDLGB, uint_to_fp, v128db, v128g, 0, 0>;
777a8b04e1cSUlrich Weigand
778a8b04e1cSUlrich Weigand  // Convert to fixed 64-bit.
779a8b04e1cSUlrich Weigand  def VCGDB : TernaryVRRa<"vcgdb", 0xE7C2, null_frag, v128g, v128db, 3, 0>;
780a8b04e1cSUlrich Weigand  def WCGDB : TernaryVRRa<"wcgdb", 0xE7C2, null_frag, v64g, v64db, 3, 8>;
781*cd808237SUlrich Weigand  // Rounding mode should agree with SystemZInstrFP.td.
782*cd808237SUlrich Weigand  def : FPConversion<VCGDB, fp_to_sint, v128g, v128db, 0, 5>;
783a8b04e1cSUlrich Weigand
784a8b04e1cSUlrich Weigand  // Convert to logical 64-bit.
785a8b04e1cSUlrich Weigand  def VCLGDB : TernaryVRRa<"vclgdb", 0xE7C0, null_frag, v128g, v128db, 3, 0>;
786a8b04e1cSUlrich Weigand  def WCLGDB : TernaryVRRa<"wclgdb", 0xE7C0, null_frag, v64g, v64db, 3, 8>;
787*cd808237SUlrich Weigand  // Rounding mode should agree with SystemZInstrFP.td.
788*cd808237SUlrich Weigand  def : FPConversion<VCLGDB, fp_to_uint, v128g, v128db, 0, 5>;
789a8b04e1cSUlrich Weigand
790a8b04e1cSUlrich Weigand  // Divide.
791*cd808237SUlrich Weigand  def VFDDB : BinaryVRRc<"vfddb", 0xE7E5, fdiv, v128db, v128db, 3, 0>;
792a8b04e1cSUlrich Weigand  def WFDDB : BinaryVRRc<"wfddb", 0xE7E5, null_frag, v64db, v64db, 3, 8>;
793a8b04e1cSUlrich Weigand
794a8b04e1cSUlrich Weigand  // Load FP integer.
795a8b04e1cSUlrich Weigand  def VFIDB : TernaryVRRa<"vfidb", 0xE7C7, null_frag, v128db, v128db, 3, 0>;
796a8b04e1cSUlrich Weigand  def WFIDB : TernaryVRRa<"wfidb", 0xE7C7, null_frag, v64db, v64db, 3, 8>;
797*cd808237SUlrich Weigand  defm : VectorRounding<VFIDB, v128db>;
798a8b04e1cSUlrich Weigand
799a8b04e1cSUlrich Weigand  // Load lengthened.
800a8b04e1cSUlrich Weigand  def VLDEB : UnaryVRRa<"vldeb", 0xE7C4, null_frag, v128db, v128eb, 2, 0>;
801a8b04e1cSUlrich Weigand  def WLDEB : UnaryVRRa<"wldeb", 0xE7C4, null_frag, v64db, v32eb, 2, 8>;
802a8b04e1cSUlrich Weigand
803a8b04e1cSUlrich Weigand  // Load rounded,
804a8b04e1cSUlrich Weigand  def VLEDB : TernaryVRRa<"vledb", 0xE7C5, null_frag, v128eb, v128db, 3, 0>;
805a8b04e1cSUlrich Weigand  def WLEDB : TernaryVRRa<"wledb", 0xE7C5, null_frag, v32eb, v64db, 3, 8>;
806a8b04e1cSUlrich Weigand
807a8b04e1cSUlrich Weigand  // Multiply.
808*cd808237SUlrich Weigand  def VFMDB : BinaryVRRc<"vfmdb", 0xE7E7, fmul, v128db, v128db, 3, 0>;
809a8b04e1cSUlrich Weigand  def WFMDB : BinaryVRRc<"wfmdb", 0xE7E7, null_frag, v64db, v64db, 3, 8>;
810a8b04e1cSUlrich Weigand
811a8b04e1cSUlrich Weigand  // Multiply and add.
812*cd808237SUlrich Weigand  def VFMADB : TernaryVRRe<"vfmadb", 0xE78F, fma, v128db, v128db, 0, 3>;
813a8b04e1cSUlrich Weigand  def WFMADB : TernaryVRRe<"wfmadb", 0xE78F, null_frag, v64db, v64db, 8, 3>;
814a8b04e1cSUlrich Weigand
815a8b04e1cSUlrich Weigand  // Multiply and subtract.
816*cd808237SUlrich Weigand  def VFMSDB : TernaryVRRe<"vfmsdb", 0xE78E, fms, v128db, v128db, 0, 3>;
817a8b04e1cSUlrich Weigand  def WFMSDB : TernaryVRRe<"wfmsdb", 0xE78E, null_frag, v64db, v64db, 8, 3>;
818a8b04e1cSUlrich Weigand
819a8b04e1cSUlrich Weigand  // Load complement,
820*cd808237SUlrich Weigand  def VFLCDB : UnaryVRRa<"vflcdb", 0xE7CC, fneg, v128db, v128db, 3, 0, 0>;
821a8b04e1cSUlrich Weigand  def WFLCDB : UnaryVRRa<"wflcdb", 0xE7CC, null_frag, v64db, v64db, 3, 8, 0>;
822a8b04e1cSUlrich Weigand
823a8b04e1cSUlrich Weigand  // Load negative.
824*cd808237SUlrich Weigand  def VFLNDB : UnaryVRRa<"vflndb", 0xE7CC, fnabs, v128db, v128db, 3, 0, 1>;
825a8b04e1cSUlrich Weigand  def WFLNDB : UnaryVRRa<"wflndb", 0xE7CC, null_frag, v64db, v64db, 3, 8, 1>;
826a8b04e1cSUlrich Weigand
827a8b04e1cSUlrich Weigand  // Load positive.
828*cd808237SUlrich Weigand  def VFLPDB : UnaryVRRa<"vflpdb", 0xE7CC, fabs, v128db, v128db, 3, 0, 2>;
829a8b04e1cSUlrich Weigand  def WFLPDB : UnaryVRRa<"wflpdb", 0xE7CC, null_frag, v64db, v64db, 3, 8, 2>;
830a8b04e1cSUlrich Weigand
831a8b04e1cSUlrich Weigand  // Square root.
832*cd808237SUlrich Weigand  def VFSQDB : UnaryVRRa<"vfsqdb", 0xE7CE, fsqrt, v128db, v128db, 3, 0>;
833a8b04e1cSUlrich Weigand  def WFSQDB : UnaryVRRa<"wfsqdb", 0xE7CE, null_frag, v64db, v64db, 3, 8>;
834a8b04e1cSUlrich Weigand
835a8b04e1cSUlrich Weigand  // Subtract.
836*cd808237SUlrich Weigand  def VFSDB : BinaryVRRc<"vfsdb", 0xE7E2, fsub, v128db, v128db, 3, 0>;
837a8b04e1cSUlrich Weigand  def WFSDB : BinaryVRRc<"wfsdb", 0xE7E2, null_frag, v64db, v64db, 3, 8>;
838a8b04e1cSUlrich Weigand
839a8b04e1cSUlrich Weigand  // Test data class immediate.
840a8b04e1cSUlrich Weigand  let Defs = [CC] in {
841a8b04e1cSUlrich Weigand    def VFTCIDB : BinaryVRIe<"vftcidb", 0xE74A, null_frag, v128g, v128db, 3, 0>;
842a8b04e1cSUlrich Weigand    def WFTCIDB : BinaryVRIe<"wftcidb", 0xE74A, null_frag, v64g, v64db, 3, 8>;
843a8b04e1cSUlrich Weigand  }
844a8b04e1cSUlrich Weigand}
845a8b04e1cSUlrich Weigand
846a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
847a8b04e1cSUlrich Weigand// Floating-point comparison
848a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
849a8b04e1cSUlrich Weigand
850a8b04e1cSUlrich Weigandlet Predicates = [FeatureVector] in {
851a8b04e1cSUlrich Weigand  // Compare scalar.
852a8b04e1cSUlrich Weigand  let Defs = [CC] in
853a8b04e1cSUlrich Weigand    def WFCDB : CompareVRRa<"wfcdb", 0xE7CB, null_frag, v64db, 3>;
854a8b04e1cSUlrich Weigand
855a8b04e1cSUlrich Weigand  // Compare and signal scalar.
856a8b04e1cSUlrich Weigand  let Defs = [CC] in
857a8b04e1cSUlrich Weigand    def WFKDB : CompareVRRa<"wfkdb", 0xE7CA, null_frag, v64db, 3>;
858a8b04e1cSUlrich Weigand
859a8b04e1cSUlrich Weigand  // Compare equal.
860*cd808237SUlrich Weigand  defm VFCEDB : BinaryVRRcSPair<"vfcedb", 0xE7E8, z_vfcmpe, null_frag,
861a8b04e1cSUlrich Weigand                                v128g, v128db, 3, 0>;
862a8b04e1cSUlrich Weigand  defm WFCEDB : BinaryVRRcSPair<"wfcedb", 0xE7E8, null_frag, null_frag,
863a8b04e1cSUlrich Weigand                                v64g, v64db, 3, 8>;
864a8b04e1cSUlrich Weigand
865a8b04e1cSUlrich Weigand  // Compare high.
866*cd808237SUlrich Weigand  defm VFCHDB : BinaryVRRcSPair<"vfchdb", 0xE7EB, z_vfcmph, null_frag,
867a8b04e1cSUlrich Weigand                                v128g, v128db, 3, 0>;
868a8b04e1cSUlrich Weigand  defm WFCHDB : BinaryVRRcSPair<"wfchdb", 0xE7EB, null_frag, null_frag,
869a8b04e1cSUlrich Weigand                                v64g, v64db, 3, 8>;
870a8b04e1cSUlrich Weigand
871a8b04e1cSUlrich Weigand  // Compare high or equal.
872*cd808237SUlrich Weigand  defm VFCHEDB : BinaryVRRcSPair<"vfchedb", 0xE7EA, z_vfcmphe, null_frag,
873a8b04e1cSUlrich Weigand                                 v128g, v128db, 3, 0>;
874a8b04e1cSUlrich Weigand  defm WFCHEDB : BinaryVRRcSPair<"wfchedb", 0xE7EA, null_frag, null_frag,
875a8b04e1cSUlrich Weigand                                 v64g, v64db, 3, 8>;
876a8b04e1cSUlrich Weigand}
877a8b04e1cSUlrich Weigand
878a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
879ce4c1095SUlrich Weigand// Conversions
880ce4c1095SUlrich Weigand//===----------------------------------------------------------------------===//
881ce4c1095SUlrich Weigand
882ce4c1095SUlrich Weiganddef : Pat<(v16i8 (bitconvert (v8i16 VR128:$src))), (v16i8 VR128:$src)>;
883ce4c1095SUlrich Weiganddef : Pat<(v16i8 (bitconvert (v4i32 VR128:$src))), (v16i8 VR128:$src)>;
884ce4c1095SUlrich Weiganddef : Pat<(v16i8 (bitconvert (v2i64 VR128:$src))), (v16i8 VR128:$src)>;
885*cd808237SUlrich Weiganddef : Pat<(v16i8 (bitconvert (v2f64 VR128:$src))), (v16i8 VR128:$src)>;
886ce4c1095SUlrich Weigand
887ce4c1095SUlrich Weiganddef : Pat<(v8i16 (bitconvert (v16i8 VR128:$src))), (v8i16 VR128:$src)>;
888ce4c1095SUlrich Weiganddef : Pat<(v8i16 (bitconvert (v4i32 VR128:$src))), (v8i16 VR128:$src)>;
889ce4c1095SUlrich Weiganddef : Pat<(v8i16 (bitconvert (v2i64 VR128:$src))), (v8i16 VR128:$src)>;
890*cd808237SUlrich Weiganddef : Pat<(v8i16 (bitconvert (v2f64 VR128:$src))), (v8i16 VR128:$src)>;
891ce4c1095SUlrich Weigand
892ce4c1095SUlrich Weiganddef : Pat<(v4i32 (bitconvert (v16i8 VR128:$src))), (v4i32 VR128:$src)>;
893ce4c1095SUlrich Weiganddef : Pat<(v4i32 (bitconvert (v8i16 VR128:$src))), (v4i32 VR128:$src)>;
894ce4c1095SUlrich Weiganddef : Pat<(v4i32 (bitconvert (v2i64 VR128:$src))), (v4i32 VR128:$src)>;
895*cd808237SUlrich Weiganddef : Pat<(v4i32 (bitconvert (v2f64 VR128:$src))), (v4i32 VR128:$src)>;
896ce4c1095SUlrich Weigand
897ce4c1095SUlrich Weiganddef : Pat<(v2i64 (bitconvert (v16i8 VR128:$src))), (v2i64 VR128:$src)>;
898ce4c1095SUlrich Weiganddef : Pat<(v2i64 (bitconvert (v8i16 VR128:$src))), (v2i64 VR128:$src)>;
899ce4c1095SUlrich Weiganddef : Pat<(v2i64 (bitconvert (v4i32 VR128:$src))), (v2i64 VR128:$src)>;
900*cd808237SUlrich Weiganddef : Pat<(v2i64 (bitconvert (v2f64 VR128:$src))), (v2i64 VR128:$src)>;
901*cd808237SUlrich Weigand
902*cd808237SUlrich Weiganddef : Pat<(v2f64 (bitconvert (v16i8 VR128:$src))), (v2f64 VR128:$src)>;
903*cd808237SUlrich Weiganddef : Pat<(v2f64 (bitconvert (v8i16 VR128:$src))), (v2f64 VR128:$src)>;
904*cd808237SUlrich Weiganddef : Pat<(v2f64 (bitconvert (v4i32 VR128:$src))), (v2f64 VR128:$src)>;
905*cd808237SUlrich Weiganddef : Pat<(v2f64 (bitconvert (v2i64 VR128:$src))), (v2f64 VR128:$src)>;
906ce4c1095SUlrich Weigand
907ce4c1095SUlrich Weigand//===----------------------------------------------------------------------===//
908ce4c1095SUlrich Weigand// Replicating scalars
909ce4c1095SUlrich Weigand//===----------------------------------------------------------------------===//
910ce4c1095SUlrich Weigand
911ce4c1095SUlrich Weigand// Define patterns for replicating a scalar GR32 into a vector of type TYPE.
912ce4c1095SUlrich Weigand// INDEX is 8 minus the element size in bytes.
913ce4c1095SUlrich Weigandclass VectorReplicateScalar<ValueType type, Instruction insn, bits<16> index>
914ce4c1095SUlrich Weigand  : Pat<(type (z_replicate GR32:$scalar)),
915ce4c1095SUlrich Weigand        (insn (VLVGP32 GR32:$scalar, GR32:$scalar), index)>;
916ce4c1095SUlrich Weigand
917ce4c1095SUlrich Weiganddef : VectorReplicateScalar<v16i8, VREPB, 7>;
918ce4c1095SUlrich Weiganddef : VectorReplicateScalar<v8i16, VREPH, 3>;
919ce4c1095SUlrich Weiganddef : VectorReplicateScalar<v4i32, VREPF, 1>;
920ce4c1095SUlrich Weigand
921ce4c1095SUlrich Weigand// i64 replications are just a single isntruction.
922ce4c1095SUlrich Weiganddef : Pat<(v2i64 (z_replicate GR64:$scalar)),
923ce4c1095SUlrich Weigand          (VLVGP GR64:$scalar, GR64:$scalar)>;
924ce4c1095SUlrich Weigand
925ce4c1095SUlrich Weigand//===----------------------------------------------------------------------===//
926*cd808237SUlrich Weigand// Floating-point insertion and extraction
927*cd808237SUlrich Weigand//===----------------------------------------------------------------------===//
928*cd808237SUlrich Weigand
929*cd808237SUlrich Weigand// Floating-point values are stored in element 0 of the corresponding
930*cd808237SUlrich Weigand// vector register.  Scalar to vector conversion is just a subreg and
931*cd808237SUlrich Weigand// scalar replication can just replicate element 0 of the vector register.
932*cd808237SUlrich Weigandmulticlass ScalarToVectorFP<Instruction vrep, ValueType vt, RegisterOperand cls,
933*cd808237SUlrich Weigand                            SubRegIndex subreg> {
934*cd808237SUlrich Weigand  def : Pat<(vt (scalar_to_vector cls:$scalar)),
935*cd808237SUlrich Weigand            (INSERT_SUBREG (vt (IMPLICIT_DEF)), cls:$scalar, subreg)>;
936*cd808237SUlrich Weigand  def : Pat<(vt (z_replicate cls:$scalar)),
937*cd808237SUlrich Weigand            (vrep (INSERT_SUBREG (vt (IMPLICIT_DEF)), cls:$scalar,
938*cd808237SUlrich Weigand                                 subreg), 0)>;
939*cd808237SUlrich Weigand}
940*cd808237SUlrich Weiganddefm : ScalarToVectorFP<VREPG, v2f64, FP64, subreg_r64>;
941*cd808237SUlrich Weigand
942*cd808237SUlrich Weigand// Match v2f64 insertions.  The AddedComplexity counters the 3 added by
943*cd808237SUlrich Weigand// TableGen for the base register operand in VLVG-based integer insertions
944*cd808237SUlrich Weigand// and ensures that this version is strictly better.
945*cd808237SUlrich Weigandlet AddedComplexity = 4 in {
946*cd808237SUlrich Weigand  def : Pat<(z_vector_insert (v2f64 VR128:$vec), FP64:$elt, 0),
947*cd808237SUlrich Weigand            (VPDI (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FP64:$elt,
948*cd808237SUlrich Weigand                                 subreg_r64), VR128:$vec, 1)>;
949*cd808237SUlrich Weigand  def : Pat<(z_vector_insert (v2f64 VR128:$vec), FP64:$elt, 1),
950*cd808237SUlrich Weigand            (VPDI VR128:$vec, (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FP64:$elt,
951*cd808237SUlrich Weigand                                             subreg_r64), 0)>;
952*cd808237SUlrich Weigand}
953*cd808237SUlrich Weigand
954*cd808237SUlrich Weigand// We extract f64 element X by replicating (for elements other than 0)
955*cd808237SUlrich Weigand// and then taking a high subreg.  The AddedComplexity counters the 3
956*cd808237SUlrich Weigand// added by TableGen for the base register operand in VLGV-based integer
957*cd808237SUlrich Weigand// extractions and ensures that this version is strictly better.
958*cd808237SUlrich Weigandlet AddedComplexity = 4 in {
959*cd808237SUlrich Weigand  def : Pat<(f64 (z_vector_extract (v2f64 VR128:$vec), 0)),
960*cd808237SUlrich Weigand            (EXTRACT_SUBREG VR128:$vec, subreg_r64)>;
961*cd808237SUlrich Weigand  def : Pat<(f64 (z_vector_extract (v2f64 VR128:$vec), imm32zx1:$index)),
962*cd808237SUlrich Weigand            (EXTRACT_SUBREG (VREPG VR128:$vec, imm32zx1:$index), subreg_r64)>;
963*cd808237SUlrich Weigand}
964*cd808237SUlrich Weigand
965*cd808237SUlrich Weigand//===----------------------------------------------------------------------===//
966a8b04e1cSUlrich Weigand// String instructions
967a8b04e1cSUlrich Weigand//===----------------------------------------------------------------------===//
968a8b04e1cSUlrich Weigand
969a8b04e1cSUlrich Weigandlet Predicates = [FeatureVector] in {
970a8b04e1cSUlrich Weigand  defm VFAEB : TernaryVRRbSPair<"vfaeb", 0xE782, null_frag, null_frag,
971a8b04e1cSUlrich Weigand                                v128b, v128b, 0, 0>;
972a8b04e1cSUlrich Weigand  defm VFAEH : TernaryVRRbSPair<"vfaeh", 0xE782, null_frag, null_frag,
973a8b04e1cSUlrich Weigand                                v128h, v128h, 1, 0>;
974a8b04e1cSUlrich Weigand  defm VFAEF : TernaryVRRbSPair<"vfaef", 0xE782, null_frag, null_frag,
975a8b04e1cSUlrich Weigand                                v128f, v128f, 2, 0>;
976a8b04e1cSUlrich Weigand  defm VFAEZB : TernaryVRRbSPair<"vfaezb", 0xE782, null_frag, null_frag,
977a8b04e1cSUlrich Weigand                                 v128b, v128b, 0, 2>;
978a8b04e1cSUlrich Weigand  defm VFAEZH : TernaryVRRbSPair<"vfaezh", 0xE782, null_frag, null_frag,
979a8b04e1cSUlrich Weigand                                 v128h, v128h, 1, 2>;
980a8b04e1cSUlrich Weigand  defm VFAEZF : TernaryVRRbSPair<"vfaezf", 0xE782, null_frag, null_frag,
981a8b04e1cSUlrich Weigand                                 v128f, v128f, 2, 2>;
982a8b04e1cSUlrich Weigand
983a8b04e1cSUlrich Weigand  defm VFEEB : BinaryVRRbSPair<"vfeeb", 0xE780, null_frag, null_frag,
984a8b04e1cSUlrich Weigand                               v128b, v128b, 0, 0, 1>;
985a8b04e1cSUlrich Weigand  defm VFEEH : BinaryVRRbSPair<"vfeeh", 0xE780, null_frag, null_frag,
986a8b04e1cSUlrich Weigand                               v128h, v128h, 1, 0, 1>;
987a8b04e1cSUlrich Weigand  defm VFEEF : BinaryVRRbSPair<"vfeef", 0xE780, null_frag, null_frag,
988a8b04e1cSUlrich Weigand                               v128f, v128f, 2, 0, 1>;
989a8b04e1cSUlrich Weigand  defm VFEEZB : BinaryVRRbSPair<"vfeezb", 0xE780, null_frag, null_frag,
990a8b04e1cSUlrich Weigand                                v128b, v128b, 0, 2, 3>;
991a8b04e1cSUlrich Weigand  defm VFEEZH : BinaryVRRbSPair<"vfeezh", 0xE780, null_frag, null_frag,
992a8b04e1cSUlrich Weigand                                v128h, v128h, 1, 2, 3>;
993a8b04e1cSUlrich Weigand  defm VFEEZF : BinaryVRRbSPair<"vfeezf", 0xE780, null_frag, null_frag,
994a8b04e1cSUlrich Weigand                                v128f, v128f, 2, 2, 3>;
995a8b04e1cSUlrich Weigand
996a8b04e1cSUlrich Weigand  defm VFENEB : BinaryVRRbSPair<"vfeneb", 0xE781, null_frag, null_frag,
997a8b04e1cSUlrich Weigand                                v128b, v128b, 0, 0, 1>;
998a8b04e1cSUlrich Weigand  defm VFENEH : BinaryVRRbSPair<"vfeneh", 0xE781, null_frag, null_frag,
999a8b04e1cSUlrich Weigand                                v128h, v128h, 1, 0, 1>;
1000a8b04e1cSUlrich Weigand  defm VFENEF : BinaryVRRbSPair<"vfenef", 0xE781, null_frag, null_frag,
1001a8b04e1cSUlrich Weigand                                v128f, v128f, 2, 0, 1>;
1002a8b04e1cSUlrich Weigand  defm VFENEZB : BinaryVRRbSPair<"vfenezb", 0xE781, null_frag, null_frag,
1003a8b04e1cSUlrich Weigand                                 v128b, v128b, 0, 2, 3>;
1004a8b04e1cSUlrich Weigand  defm VFENEZH : BinaryVRRbSPair<"vfenezh", 0xE781, null_frag, null_frag,
1005a8b04e1cSUlrich Weigand                                 v128h, v128h, 1, 2, 3>;
1006a8b04e1cSUlrich Weigand  defm VFENEZF : BinaryVRRbSPair<"vfenezf", 0xE781, null_frag, null_frag,
1007a8b04e1cSUlrich Weigand                                 v128f, v128f, 2, 2, 3>;
1008a8b04e1cSUlrich Weigand
1009a8b04e1cSUlrich Weigand  defm VISTRB : UnaryVRRaSPair<"vistrb", 0xE75C, null_frag, null_frag,
1010a8b04e1cSUlrich Weigand                               v128b, v128b, 0>;
1011a8b04e1cSUlrich Weigand  defm VISTRH : UnaryVRRaSPair<"vistrh", 0xE75C, null_frag, null_frag,
1012a8b04e1cSUlrich Weigand                               v128h, v128h, 1>;
1013a8b04e1cSUlrich Weigand  defm VISTRF : UnaryVRRaSPair<"vistrf", 0xE75C, null_frag, null_frag,
1014a8b04e1cSUlrich Weigand                               v128f, v128f, 2>;
1015a8b04e1cSUlrich Weigand
1016a8b04e1cSUlrich Weigand  defm VSTRCB : QuaternaryVRRdSPair<"vstrcb", 0xE78A, null_frag, null_frag,
1017a8b04e1cSUlrich Weigand                                    v128b, v128b, 0, 0>;
1018a8b04e1cSUlrich Weigand  defm VSTRCH : QuaternaryVRRdSPair<"vstrch", 0xE78A, null_frag, null_frag,
1019a8b04e1cSUlrich Weigand                                    v128h, v128h, 1, 0>;
1020a8b04e1cSUlrich Weigand  defm VSTRCF : QuaternaryVRRdSPair<"vstrcf", 0xE78A, null_frag, null_frag,
1021a8b04e1cSUlrich Weigand                                    v128f, v128f, 2, 0>;
1022a8b04e1cSUlrich Weigand  defm VSTRCZB : QuaternaryVRRdSPair<"vstrczb", 0xE78A, null_frag, null_frag,
1023a8b04e1cSUlrich Weigand                                     v128b, v128b, 0, 2>;
1024a8b04e1cSUlrich Weigand  defm VSTRCZH : QuaternaryVRRdSPair<"vstrczh", 0xE78A, null_frag, null_frag,
1025a8b04e1cSUlrich Weigand                                     v128h, v128h, 1, 2>;
1026a8b04e1cSUlrich Weigand  defm VSTRCZF : QuaternaryVRRdSPair<"vstrczf", 0xE78A, null_frag, null_frag,
1027a8b04e1cSUlrich Weigand                                     v128f, v128f, 2, 2>;
1028a8b04e1cSUlrich Weigand}
1029