1 //===-- X86ShuffleDecode.cpp - X86 shuffle decode logic -------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Define several functions to decode x86 specific shuffle semantics into a
11 // generic vector mask.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "X86ShuffleDecode.h"
16 #include "llvm/ADT/ArrayRef.h"
17 #include "llvm/CodeGen/MachineValueType.h"
18 
19 //===----------------------------------------------------------------------===//
20 //  Vector Mask Decoding
21 //===----------------------------------------------------------------------===//
22 
23 namespace llvm {
24 
25 void DecodeINSERTPSMask(unsigned Imm, SmallVectorImpl<int> &ShuffleMask) {
26   // Defaults the copying the dest value.
27   ShuffleMask.push_back(0);
28   ShuffleMask.push_back(1);
29   ShuffleMask.push_back(2);
30   ShuffleMask.push_back(3);
31 
32   // Decode the immediate.
33   unsigned ZMask = Imm & 15;
34   unsigned CountD = (Imm >> 4) & 3;
35   unsigned CountS = (Imm >> 6) & 3;
36 
37   // CountS selects which input element to use.
38   unsigned InVal = 4 + CountS;
39   // CountD specifies which element of destination to update.
40   ShuffleMask[CountD] = InVal;
41   // ZMask zaps values, potentially overriding the CountD elt.
42   if (ZMask & 1) ShuffleMask[0] = SM_SentinelZero;
43   if (ZMask & 2) ShuffleMask[1] = SM_SentinelZero;
44   if (ZMask & 4) ShuffleMask[2] = SM_SentinelZero;
45   if (ZMask & 8) ShuffleMask[3] = SM_SentinelZero;
46 }
47 
48 void DecodeInsertElementMask(MVT VT, unsigned Idx, unsigned Len,
49                              SmallVectorImpl<int> &ShuffleMask) {
50   unsigned NumElts = VT.getVectorNumElements();
51   assert((Idx + Len) <= NumElts && "Insertion out of range");
52 
53   for (unsigned i = 0; i != NumElts; ++i)
54     ShuffleMask.push_back(i);
55   for (unsigned i = 0; i != Len; ++i)
56     ShuffleMask[Idx + i] = NumElts + i;
57 }
58 
59 // <3,1> or <6,7,2,3>
60 void DecodeMOVHLPSMask(unsigned NElts, SmallVectorImpl<int> &ShuffleMask) {
61   for (unsigned i = NElts / 2; i != NElts; ++i)
62     ShuffleMask.push_back(NElts + i);
63 
64   for (unsigned i = NElts / 2; i != NElts; ++i)
65     ShuffleMask.push_back(i);
66 }
67 
68 // <0,2> or <0,1,4,5>
69 void DecodeMOVLHPSMask(unsigned NElts, SmallVectorImpl<int> &ShuffleMask) {
70   for (unsigned i = 0; i != NElts / 2; ++i)
71     ShuffleMask.push_back(i);
72 
73   for (unsigned i = 0; i != NElts / 2; ++i)
74     ShuffleMask.push_back(NElts + i);
75 }
76 
77 void DecodeMOVSLDUPMask(MVT VT, SmallVectorImpl<int> &ShuffleMask) {
78   unsigned NumElts = VT.getVectorNumElements();
79   for (int i = 0, e = NumElts / 2; i < e; ++i) {
80     ShuffleMask.push_back(2 * i);
81     ShuffleMask.push_back(2 * i);
82   }
83 }
84 
85 void DecodeMOVSHDUPMask(MVT VT, SmallVectorImpl<int> &ShuffleMask) {
86   unsigned NumElts = VT.getVectorNumElements();
87   for (int i = 0, e = NumElts / 2; i < e; ++i) {
88     ShuffleMask.push_back(2 * i + 1);
89     ShuffleMask.push_back(2 * i + 1);
90   }
91 }
92 
93 void DecodeMOVDDUPMask(MVT VT, SmallVectorImpl<int> &ShuffleMask) {
94   unsigned VectorSizeInBits = VT.getSizeInBits();
95   unsigned ScalarSizeInBits = VT.getScalarSizeInBits();
96   unsigned NumElts = VT.getVectorNumElements();
97   unsigned NumLanes = VectorSizeInBits / 128;
98   unsigned NumLaneElts = NumElts / NumLanes;
99   unsigned NumLaneSubElts = 64 / ScalarSizeInBits;
100 
101   for (unsigned l = 0; l < NumElts; l += NumLaneElts)
102     for (unsigned i = 0; i < NumLaneElts; i += NumLaneSubElts)
103       for (unsigned s = 0; s != NumLaneSubElts; s++)
104         ShuffleMask.push_back(l + s);
105 }
106 
107 void DecodePSLLDQMask(MVT VT, unsigned Imm, SmallVectorImpl<int> &ShuffleMask) {
108   unsigned VectorSizeInBits = VT.getSizeInBits();
109   unsigned NumElts = VectorSizeInBits / 8;
110   unsigned NumLanes = VectorSizeInBits / 128;
111   unsigned NumLaneElts = NumElts / NumLanes;
112 
113   for (unsigned l = 0; l < NumElts; l += NumLaneElts)
114     for (unsigned i = 0; i < NumLaneElts; ++i) {
115       int M = SM_SentinelZero;
116       if (i >= Imm) M = i - Imm + l;
117       ShuffleMask.push_back(M);
118     }
119 }
120 
121 void DecodePSRLDQMask(MVT VT, unsigned Imm, SmallVectorImpl<int> &ShuffleMask) {
122   unsigned VectorSizeInBits = VT.getSizeInBits();
123   unsigned NumElts = VectorSizeInBits / 8;
124   unsigned NumLanes = VectorSizeInBits / 128;
125   unsigned NumLaneElts = NumElts / NumLanes;
126 
127   for (unsigned l = 0; l < NumElts; l += NumLaneElts)
128     for (unsigned i = 0; i < NumLaneElts; ++i) {
129       unsigned Base = i + Imm;
130       int M = Base + l;
131       if (Base >= NumLaneElts) M = SM_SentinelZero;
132       ShuffleMask.push_back(M);
133     }
134 }
135 
136 void DecodePALIGNRMask(MVT VT, unsigned Imm,
137                        SmallVectorImpl<int> &ShuffleMask) {
138   unsigned NumElts = VT.getVectorNumElements();
139   unsigned Offset = Imm * (VT.getScalarSizeInBits() / 8);
140 
141   unsigned NumLanes = VT.getSizeInBits() / 128;
142   unsigned NumLaneElts = NumElts / NumLanes;
143 
144   for (unsigned l = 0; l != NumElts; l += NumLaneElts) {
145     for (unsigned i = 0; i != NumLaneElts; ++i) {
146       unsigned Base = i + Offset;
147       // if i+offset is out of this lane then we actually need the other source
148       if (Base >= NumLaneElts) Base += NumElts - NumLaneElts;
149       ShuffleMask.push_back(Base + l);
150     }
151   }
152 }
153 
154 void DecodeVALIGNMask(MVT VT, unsigned Imm,
155                       SmallVectorImpl<int> &ShuffleMask) {
156   int NumElts = VT.getVectorNumElements();
157   // Not all bits of the immediate are used so mask it.
158   assert(isPowerOf2_32(NumElts) && "NumElts should be power of 2");
159   Imm = Imm & (NumElts - 1);
160   for (int i = 0; i != NumElts; ++i)
161     ShuffleMask.push_back(i + Imm);
162 }
163 
164 /// DecodePSHUFMask - This decodes the shuffle masks for pshufw, pshufd, and vpermilp*.
165 /// VT indicates the type of the vector allowing it to handle different
166 /// datatypes and vector widths.
167 void DecodePSHUFMask(MVT VT, unsigned Imm, SmallVectorImpl<int> &ShuffleMask) {
168   unsigned NumElts = VT.getVectorNumElements();
169 
170   unsigned NumLanes = VT.getSizeInBits() / 128;
171   if (NumLanes == 0) NumLanes = 1;  // Handle MMX
172   unsigned NumLaneElts = NumElts / NumLanes;
173 
174   unsigned NewImm = Imm;
175   for (unsigned l = 0; l != NumElts; l += NumLaneElts) {
176     for (unsigned i = 0; i != NumLaneElts; ++i) {
177       ShuffleMask.push_back(NewImm % NumLaneElts + l);
178       NewImm /= NumLaneElts;
179     }
180     if (NumLaneElts == 4) NewImm = Imm; // reload imm
181   }
182 }
183 
184 void DecodePSHUFHWMask(MVT VT, unsigned Imm,
185                        SmallVectorImpl<int> &ShuffleMask) {
186   unsigned NumElts = VT.getVectorNumElements();
187 
188   for (unsigned l = 0; l != NumElts; l += 8) {
189     unsigned NewImm = Imm;
190     for (unsigned i = 0, e = 4; i != e; ++i) {
191       ShuffleMask.push_back(l + i);
192     }
193     for (unsigned i = 4, e = 8; i != e; ++i) {
194       ShuffleMask.push_back(l + 4 + (NewImm & 3));
195       NewImm >>= 2;
196     }
197   }
198 }
199 
200 void DecodePSHUFLWMask(MVT VT, unsigned Imm,
201                        SmallVectorImpl<int> &ShuffleMask) {
202   unsigned NumElts = VT.getVectorNumElements();
203 
204   for (unsigned l = 0; l != NumElts; l += 8) {
205     unsigned NewImm = Imm;
206     for (unsigned i = 0, e = 4; i != e; ++i) {
207       ShuffleMask.push_back(l + (NewImm & 3));
208       NewImm >>= 2;
209     }
210     for (unsigned i = 4, e = 8; i != e; ++i) {
211       ShuffleMask.push_back(l + i);
212     }
213   }
214 }
215 
216 void DecodePSWAPMask(MVT VT, SmallVectorImpl<int> &ShuffleMask) {
217   unsigned NumElts = VT.getVectorNumElements();
218   unsigned NumHalfElts = NumElts / 2;
219 
220   for (unsigned l = 0; l != NumHalfElts; ++l)
221     ShuffleMask.push_back(l + NumHalfElts);
222   for (unsigned h = 0; h != NumHalfElts; ++h)
223     ShuffleMask.push_back(h);
224 }
225 
226 /// DecodeSHUFPMask - This decodes the shuffle masks for shufp*. VT indicates
227 /// the type of the vector allowing it to handle different datatypes and vector
228 /// widths.
229 void DecodeSHUFPMask(MVT VT, unsigned Imm, SmallVectorImpl<int> &ShuffleMask) {
230   unsigned NumElts = VT.getVectorNumElements();
231 
232   unsigned NumLanes = VT.getSizeInBits() / 128;
233   unsigned NumLaneElts = NumElts / NumLanes;
234 
235   unsigned NewImm = Imm;
236   for (unsigned l = 0; l != NumElts; l += NumLaneElts) {
237     // each half of a lane comes from different source
238     for (unsigned s = 0; s != NumElts * 2; s += NumElts) {
239       for (unsigned i = 0; i != NumLaneElts / 2; ++i) {
240         ShuffleMask.push_back(NewImm % NumLaneElts + s + l);
241         NewImm /= NumLaneElts;
242       }
243     }
244     if (NumLaneElts == 4) NewImm = Imm; // reload imm
245   }
246 }
247 
248 /// DecodeUNPCKHMask - This decodes the shuffle masks for unpckhps/unpckhpd
249 /// and punpckh*. VT indicates the type of the vector allowing it to handle
250 /// different datatypes and vector widths.
251 void DecodeUNPCKHMask(MVT VT, SmallVectorImpl<int> &ShuffleMask) {
252   unsigned NumElts = VT.getVectorNumElements();
253 
254   // Handle 128 and 256-bit vector lengths. AVX defines UNPCK* to operate
255   // independently on 128-bit lanes.
256   unsigned NumLanes = VT.getSizeInBits() / 128;
257   if (NumLanes == 0) NumLanes = 1;  // Handle MMX
258   unsigned NumLaneElts = NumElts / NumLanes;
259 
260   for (unsigned l = 0; l != NumElts; l += NumLaneElts) {
261     for (unsigned i = l + NumLaneElts / 2, e = l + NumLaneElts; i != e; ++i) {
262       ShuffleMask.push_back(i);           // Reads from dest/src1
263       ShuffleMask.push_back(i + NumElts); // Reads from src/src2
264     }
265   }
266 }
267 
268 /// DecodeUNPCKLMask - This decodes the shuffle masks for unpcklps/unpcklpd
269 /// and punpckl*. VT indicates the type of the vector allowing it to handle
270 /// different datatypes and vector widths.
271 void DecodeUNPCKLMask(MVT VT, SmallVectorImpl<int> &ShuffleMask) {
272   unsigned NumElts = VT.getVectorNumElements();
273 
274   // Handle 128 and 256-bit vector lengths. AVX defines UNPCK* to operate
275   // independently on 128-bit lanes.
276   unsigned NumLanes = VT.getSizeInBits() / 128;
277   if (NumLanes == 0 ) NumLanes = 1;  // Handle MMX
278   unsigned NumLaneElts = NumElts / NumLanes;
279 
280   for (unsigned l = 0; l != NumElts; l += NumLaneElts) {
281     for (unsigned i = l, e = l + NumLaneElts / 2; i != e; ++i) {
282       ShuffleMask.push_back(i);           // Reads from dest/src1
283       ShuffleMask.push_back(i + NumElts); // Reads from src/src2
284     }
285   }
286 }
287 
288 /// Decodes a broadcast of the first element of a vector.
289 void DecodeVectorBroadcast(MVT DstVT, SmallVectorImpl<int> &ShuffleMask) {
290   unsigned NumElts = DstVT.getVectorNumElements();
291   ShuffleMask.append(NumElts, 0);
292 }
293 
294 /// Decodes a broadcast of a subvector to a larger vector type.
295 void DecodeSubVectorBroadcast(MVT DstVT, MVT SrcVT,
296                               SmallVectorImpl<int> &ShuffleMask) {
297   assert(SrcVT.getScalarType() == DstVT.getScalarType() &&
298          "Non matching vector element types");
299   unsigned NumElts = SrcVT.getVectorNumElements();
300   unsigned Scale = DstVT.getSizeInBits() / SrcVT.getSizeInBits();
301 
302   for (unsigned i = 0; i != Scale; ++i)
303     for (unsigned j = 0; j != NumElts; ++j)
304       ShuffleMask.push_back(j);
305 }
306 
307 /// \brief Decode a shuffle packed values at 128-bit granularity
308 /// (SHUFF32x4/SHUFF64x2/SHUFI32x4/SHUFI64x2)
309 /// immediate mask into a shuffle mask.
310 void decodeVSHUF64x2FamilyMask(MVT VT, unsigned Imm,
311                         SmallVectorImpl<int> &ShuffleMask) {
312   unsigned NumLanes = VT.getSizeInBits() / 128;
313   unsigned NumElementsInLane = 128 / VT.getScalarSizeInBits();
314   unsigned ControlBitsMask = NumLanes - 1;
315   unsigned NumControlBits  = NumLanes / 2;
316 
317   for (unsigned l = 0; l != NumLanes; ++l) {
318     unsigned LaneMask = (Imm >> (l * NumControlBits)) & ControlBitsMask;
319     // We actually need the other source.
320     if (l >= NumLanes / 2)
321       LaneMask += NumLanes;
322     for (unsigned i = 0; i != NumElementsInLane; ++i)
323       ShuffleMask.push_back(LaneMask * NumElementsInLane + i);
324   }
325 }
326 
327 void DecodeVPERM2X128Mask(MVT VT, unsigned Imm,
328                           SmallVectorImpl<int> &ShuffleMask) {
329   unsigned HalfSize = VT.getVectorNumElements() / 2;
330 
331   for (unsigned l = 0; l != 2; ++l) {
332     unsigned HalfMask = Imm >> (l * 4);
333     unsigned HalfBegin = (HalfMask & 0x3) * HalfSize;
334     for (unsigned i = HalfBegin, e = HalfBegin + HalfSize; i != e; ++i)
335       ShuffleMask.push_back(HalfMask & 8 ? SM_SentinelZero : (int)i);
336   }
337 }
338 
339 void DecodePSHUFBMask(ArrayRef<uint64_t> RawMask,
340                       SmallVectorImpl<int> &ShuffleMask) {
341   for (int i = 0, e = RawMask.size(); i < e; ++i) {
342     uint64_t M = RawMask[i];
343     if (M == (uint64_t)SM_SentinelUndef) {
344       ShuffleMask.push_back(M);
345       continue;
346     }
347     // For 256/512-bit vectors the base of the shuffle is the 128-bit
348     // subvector we're inside.
349     int Base = (i / 16) * 16;
350     // If the high bit (7) of the byte is set, the element is zeroed.
351     if (M & (1 << 7))
352       ShuffleMask.push_back(SM_SentinelZero);
353     else {
354       // Only the least significant 4 bits of the byte are used.
355       int Index = Base + (M & 0xf);
356       ShuffleMask.push_back(Index);
357     }
358   }
359 }
360 
361 void DecodeBLENDMask(MVT VT, unsigned Imm, SmallVectorImpl<int> &ShuffleMask) {
362   int ElementBits = VT.getScalarSizeInBits();
363   int NumElements = VT.getVectorNumElements();
364   for (int i = 0; i < NumElements; ++i) {
365     // If there are more than 8 elements in the vector, then any immediate blend
366     // mask applies to each 128-bit lane. There can never be more than
367     // 8 elements in a 128-bit lane with an immediate blend.
368     int Bit = NumElements > 8 ? i % (128 / ElementBits) : i;
369     assert(Bit < 8 &&
370            "Immediate blends only operate over 8 elements at a time!");
371     ShuffleMask.push_back(((Imm >> Bit) & 1) ? NumElements + i : i);
372   }
373 }
374 
375 void DecodeVPPERMMask(ArrayRef<uint64_t> RawMask,
376                       SmallVectorImpl<int> &ShuffleMask) {
377   assert(RawMask.size() == 16 && "Illegal VPPERM shuffle mask size");
378 
379   // VPPERM Operation
380   // Bits[4:0] - Byte Index (0 - 31)
381   // Bits[7:5] - Permute Operation
382   //
383   // Permute Operation:
384   // 0 - Source byte (no logical operation).
385   // 1 - Invert source byte.
386   // 2 - Bit reverse of source byte.
387   // 3 - Bit reverse of inverted source byte.
388   // 4 - 00h (zero - fill).
389   // 5 - FFh (ones - fill).
390   // 6 - Most significant bit of source byte replicated in all bit positions.
391   // 7 - Invert most significant bit of source byte and replicate in all bit positions.
392   for (int i = 0, e = RawMask.size(); i < e; ++i) {
393     uint64_t M = RawMask[i];
394     if (M == (uint64_t)SM_SentinelUndef) {
395       ShuffleMask.push_back(M);
396       continue;
397     }
398 
399     uint64_t PermuteOp = (M >> 5) & 0x7;
400     if (PermuteOp == 4) {
401       ShuffleMask.push_back(SM_SentinelZero);
402       continue;
403     }
404     if (PermuteOp != 0) {
405       ShuffleMask.clear();
406       return;
407     }
408 
409     uint64_t Index = M & 0x1F;
410     ShuffleMask.push_back((int)Index);
411   }
412 }
413 
414 /// DecodeVPERMMask - this decodes the shuffle masks for VPERMQ/VPERMPD.
415 void DecodeVPERMMask(MVT VT, unsigned Imm, SmallVectorImpl<int> &ShuffleMask) {
416   assert((VT.is256BitVector() || VT.is512BitVector()) &&
417          (VT.getScalarSizeInBits() == 64) && "Unexpected vector value type");
418   unsigned NumElts = VT.getVectorNumElements();
419   for (unsigned l = 0; l != NumElts; l += 4)
420     for (unsigned i = 0; i != 4; ++i)
421       ShuffleMask.push_back(l + ((Imm >> (2 * i)) & 3));
422 }
423 
424 void DecodeZeroExtendMask(MVT SrcScalarVT, MVT DstVT, SmallVectorImpl<int> &Mask) {
425   unsigned NumDstElts = DstVT.getVectorNumElements();
426   unsigned SrcScalarBits = SrcScalarVT.getSizeInBits();
427   unsigned DstScalarBits = DstVT.getScalarSizeInBits();
428   unsigned Scale = DstScalarBits / SrcScalarBits;
429   assert(SrcScalarBits < DstScalarBits &&
430          "Expected zero extension mask to increase scalar size");
431 
432   for (unsigned i = 0; i != NumDstElts; i++) {
433     Mask.push_back(i);
434     for (unsigned j = 1; j != Scale; j++)
435       Mask.push_back(SM_SentinelZero);
436   }
437 }
438 
439 void DecodeZeroMoveLowMask(MVT VT, SmallVectorImpl<int> &ShuffleMask) {
440   unsigned NumElts = VT.getVectorNumElements();
441   ShuffleMask.push_back(0);
442   for (unsigned i = 1; i < NumElts; i++)
443     ShuffleMask.push_back(SM_SentinelZero);
444 }
445 
446 void DecodeScalarMoveMask(MVT VT, bool IsLoad, SmallVectorImpl<int> &Mask) {
447   // First element comes from the first element of second source.
448   // Remaining elements: Load zero extends / Move copies from first source.
449   unsigned NumElts = VT.getVectorNumElements();
450   Mask.push_back(NumElts);
451   for (unsigned i = 1; i < NumElts; i++)
452     Mask.push_back(IsLoad ? static_cast<int>(SM_SentinelZero) : i);
453 }
454 
455 void DecodeEXTRQIMask(MVT VT, int Len, int Idx,
456                       SmallVectorImpl<int> &ShuffleMask) {
457   assert(VT.is128BitVector() && "Expected 128-bit vector");
458   unsigned NumElts = VT.getVectorNumElements();
459   unsigned EltSize = VT.getScalarSizeInBits();
460   unsigned HalfElts = NumElts / 2;
461 
462   // Only the bottom 6 bits are valid for each immediate.
463   Len &= 0x3F;
464   Idx &= 0x3F;
465 
466   // We can only decode this bit extraction instruction as a shuffle if both the
467   // length and index work with whole elements.
468   if (0 != (Len % EltSize) || 0 != (Idx % EltSize))
469     return;
470 
471   // A length of zero is equivalent to a bit length of 64.
472   if (Len == 0)
473     Len = 64;
474 
475   // If the length + index exceeds the bottom 64 bits the result is undefined.
476   if ((Len + Idx) > 64) {
477     ShuffleMask.append(NumElts, SM_SentinelUndef);
478     return;
479   }
480 
481   // Convert index and index to work with elements.
482   Len /= EltSize;
483   Idx /= EltSize;
484 
485   // EXTRQ: Extract Len elements starting from Idx. Zero pad the remaining
486   // elements of the lower 64-bits. The upper 64-bits are undefined.
487   for (int i = 0; i != Len; ++i)
488     ShuffleMask.push_back(i + Idx);
489   for (int i = Len; i != (int)HalfElts; ++i)
490     ShuffleMask.push_back(SM_SentinelZero);
491   for (int i = HalfElts; i != (int)NumElts; ++i)
492     ShuffleMask.push_back(SM_SentinelUndef);
493 }
494 
495 void DecodeINSERTQIMask(MVT VT, int Len, int Idx,
496                         SmallVectorImpl<int> &ShuffleMask) {
497   assert(VT.is128BitVector() && "Expected 128-bit vector");
498   unsigned NumElts = VT.getVectorNumElements();
499   unsigned EltSize = VT.getScalarSizeInBits();
500   unsigned HalfElts = NumElts / 2;
501 
502   // Only the bottom 6 bits are valid for each immediate.
503   Len &= 0x3F;
504   Idx &= 0x3F;
505 
506   // We can only decode this bit insertion instruction as a shuffle if both the
507   // length and index work with whole elements.
508   if (0 != (Len % EltSize) || 0 != (Idx % EltSize))
509     return;
510 
511   // A length of zero is equivalent to a bit length of 64.
512   if (Len == 0)
513     Len = 64;
514 
515   // If the length + index exceeds the bottom 64 bits the result is undefined.
516   if ((Len + Idx) > 64) {
517     ShuffleMask.append(NumElts, SM_SentinelUndef);
518     return;
519   }
520 
521   // Convert index and index to work with elements.
522   Len /= EltSize;
523   Idx /= EltSize;
524 
525   // INSERTQ: Extract lowest Len elements from lower half of second source and
526   // insert over first source starting at Idx element. The upper 64-bits are
527   // undefined.
528   for (int i = 0; i != Idx; ++i)
529     ShuffleMask.push_back(i);
530   for (int i = 0; i != Len; ++i)
531     ShuffleMask.push_back(i + NumElts);
532   for (int i = Idx + Len; i != (int)HalfElts; ++i)
533     ShuffleMask.push_back(i);
534   for (int i = HalfElts; i != (int)NumElts; ++i)
535     ShuffleMask.push_back(SM_SentinelUndef);
536 }
537 
538 void DecodeVPERMILPMask(MVT VT, ArrayRef<uint64_t> RawMask,
539                         SmallVectorImpl<int> &ShuffleMask) {
540   unsigned VecSize = VT.getSizeInBits();
541   unsigned EltSize = VT.getScalarSizeInBits();
542   unsigned NumLanes = VecSize / 128;
543   unsigned NumEltsPerLane = VT.getVectorNumElements() / NumLanes;
544   assert((VecSize == 128 || VecSize == 256 || VecSize == 512) &&
545          "Unexpected vector size");
546   assert((EltSize == 32 || EltSize == 64) && "Unexpected element size");
547 
548   for (unsigned i = 0, e = RawMask.size(); i < e; ++i) {
549     uint64_t M = RawMask[i];
550     M = (EltSize == 64 ? ((M >> 1) & 0x1) : (M & 0x3));
551     unsigned LaneOffset = i & ~(NumEltsPerLane - 1);
552     ShuffleMask.push_back((int)(LaneOffset + M));
553   }
554 }
555 
556 void DecodeVPERMIL2PMask(MVT VT, unsigned M2Z, ArrayRef<uint64_t> RawMask,
557                          SmallVectorImpl<int> &ShuffleMask) {
558   unsigned VecSize = VT.getSizeInBits();
559   unsigned EltSize = VT.getScalarSizeInBits();
560   unsigned NumLanes = VecSize / 128;
561   unsigned NumElts = VT.getVectorNumElements();
562   unsigned NumEltsPerLane = NumElts / NumLanes;
563   assert((VecSize == 128 || VecSize == 256) && "Unexpected vector size");
564   assert((EltSize == 32 || EltSize == 64) && "Unexpected element size");
565   assert((NumElts == RawMask.size()) && "Unexpected mask size");
566 
567   for (unsigned i = 0, e = RawMask.size(); i < e; ++i) {
568     // VPERMIL2 Operation.
569     // Bits[3] - Match Bit.
570     // Bits[2:1] - (Per Lane) PD Shuffle Mask.
571     // Bits[2:0] - (Per Lane) PS Shuffle Mask.
572     uint64_t Selector = RawMask[i];
573     unsigned MatchBit = (Selector >> 3) & 0x1;
574 
575     // M2Z[0:1]     MatchBit
576     //   0Xb           X        Source selected by Selector index.
577     //   10b           0        Source selected by Selector index.
578     //   10b           1        Zero.
579     //   11b           0        Zero.
580     //   11b           1        Source selected by Selector index.
581     if ((M2Z & 0x2) != 0 && MatchBit != (M2Z & 0x1)) {
582       ShuffleMask.push_back(SM_SentinelZero);
583       continue;
584     }
585 
586     int Index = i & ~(NumEltsPerLane - 1);
587     if (EltSize == 64)
588       Index += (Selector >> 1) & 0x1;
589     else
590       Index += Selector & 0x3;
591 
592     int Src = (Selector >> 2) & 0x1;
593     Index += Src * NumElts;
594     ShuffleMask.push_back(Index);
595   }
596 }
597 
598 void DecodeVPERMVMask(ArrayRef<uint64_t> RawMask,
599                       SmallVectorImpl<int> &ShuffleMask) {
600   uint64_t EltMaskSize = RawMask.size() - 1;
601   for (auto M : RawMask) {
602     M &= EltMaskSize;
603     ShuffleMask.push_back((int)M);
604   }
605 }
606 
607 void DecodeVPERMV3Mask(ArrayRef<uint64_t> RawMask,
608                       SmallVectorImpl<int> &ShuffleMask) {
609   uint64_t EltMaskSize = (RawMask.size() * 2) - 1;
610   for (auto M : RawMask) {
611     M &= EltMaskSize;
612     ShuffleMask.push_back((int)M);
613   }
614 }
615 
616 } // llvm namespace
617