1 //===-- X86ShuffleDecode.h - X86 shuffle decode logic ---------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Define several functions to decode x86 specific shuffle semantics into a
11 // generic vector mask.
13 //===----------------------------------------------------------------------===//
15 #ifndef X86_SHUFFLE_DECODE_H
16 #define X86_SHUFFLE_DECODE_H
18 #include "llvm/ADT/SmallVector.h"
21 //===----------------------------------------------------------------------===//
22 // Vector Mask Decoding
23 //===----------------------------------------------------------------------===//
30 void DecodeINSERTPSMask(unsigned Imm
, SmallVectorImpl
<unsigned> &ShuffleMask
) {
31 // Defaults the copying the dest value.
32 ShuffleMask
.push_back(0);
33 ShuffleMask
.push_back(1);
34 ShuffleMask
.push_back(2);
35 ShuffleMask
.push_back(3);
37 // Decode the immediate.
38 unsigned ZMask
= Imm
& 15;
39 unsigned CountD
= (Imm
>> 4) & 3;
40 unsigned CountS
= (Imm
>> 6) & 3;
42 // CountS selects which input element to use.
43 unsigned InVal
= 4+CountS
;
44 // CountD specifies which element of destination to update.
45 ShuffleMask
[CountD
] = InVal
;
46 // ZMask zaps values, potentially overriding the CountD elt.
47 if (ZMask
& 1) ShuffleMask
[0] = SM_SentinelZero
;
48 if (ZMask
& 2) ShuffleMask
[1] = SM_SentinelZero
;
49 if (ZMask
& 4) ShuffleMask
[2] = SM_SentinelZero
;
50 if (ZMask
& 8) ShuffleMask
[3] = SM_SentinelZero
;
54 static void DecodeMOVHLPSMask(unsigned NElts
,
55 SmallVectorImpl
<unsigned> &ShuffleMask
) {
56 for (unsigned i
= NElts
/2; i
!= NElts
; ++i
)
57 ShuffleMask
.push_back(NElts
+i
);
59 for (unsigned i
= NElts
/2; i
!= NElts
; ++i
)
60 ShuffleMask
.push_back(i
);
64 static void DecodeMOVLHPSMask(unsigned NElts
,
65 SmallVectorImpl
<unsigned> &ShuffleMask
) {
66 for (unsigned i
= 0; i
!= NElts
/2; ++i
)
67 ShuffleMask
.push_back(i
);
69 for (unsigned i
= 0; i
!= NElts
/2; ++i
)
70 ShuffleMask
.push_back(NElts
+i
);
73 static void DecodePSHUFMask(unsigned NElts
, unsigned Imm
,
74 SmallVectorImpl
<unsigned> &ShuffleMask
) {
75 for (unsigned i
= 0; i
!= NElts
; ++i
) {
76 ShuffleMask
.push_back(Imm
% NElts
);
81 static void DecodePSHUFHWMask(unsigned Imm
,
82 SmallVectorImpl
<unsigned> &ShuffleMask
) {
83 ShuffleMask
.push_back(0);
84 ShuffleMask
.push_back(1);
85 ShuffleMask
.push_back(2);
86 ShuffleMask
.push_back(3);
87 for (unsigned i
= 0; i
!= 4; ++i
) {
88 ShuffleMask
.push_back(4+(Imm
& 3));
93 static void DecodePSHUFLWMask(unsigned Imm
,
94 SmallVectorImpl
<unsigned> &ShuffleMask
) {
95 for (unsigned i
= 0; i
!= 4; ++i
) {
96 ShuffleMask
.push_back((Imm
& 3));
99 ShuffleMask
.push_back(4);
100 ShuffleMask
.push_back(5);
101 ShuffleMask
.push_back(6);
102 ShuffleMask
.push_back(7);
105 static void DecodePUNPCKLMask(unsigned NElts
,
106 SmallVectorImpl
<unsigned> &ShuffleMask
) {
107 for (unsigned i
= 0; i
!= NElts
/2; ++i
) {
108 ShuffleMask
.push_back(i
);
109 ShuffleMask
.push_back(i
+NElts
);
113 static void DecodePUNPCKHMask(unsigned NElts
,
114 SmallVectorImpl
<unsigned> &ShuffleMask
) {
115 for (unsigned i
= 0; i
!= NElts
/2; ++i
) {
116 ShuffleMask
.push_back(i
+NElts
/2);
117 ShuffleMask
.push_back(i
+NElts
+NElts
/2);
121 static void DecodeSHUFPSMask(unsigned NElts
, unsigned Imm
,
122 SmallVectorImpl
<unsigned> &ShuffleMask
) {
123 // Part that reads from dest.
124 for (unsigned i
= 0; i
!= NElts
/2; ++i
) {
125 ShuffleMask
.push_back(Imm
% NElts
);
128 // Part that reads from src.
129 for (unsigned i
= 0; i
!= NElts
/2; ++i
) {
130 ShuffleMask
.push_back(Imm
% NElts
+ NElts
);
135 static void DecodeUNPCKHPMask(unsigned NElts
,
136 SmallVectorImpl
<unsigned> &ShuffleMask
) {
137 for (unsigned i
= 0; i
!= NElts
/2; ++i
) {
138 ShuffleMask
.push_back(i
+NElts
/2); // Reads from dest
139 ShuffleMask
.push_back(i
+NElts
+NElts
/2); // Reads from src
144 /// DecodeUNPCKLPMask - This decodes the shuffle masks for unpcklps/unpcklpd
145 /// etc. NElts indicates the number of elements in the vector allowing it to
146 /// handle different datatypes and vector widths.
147 static void DecodeUNPCKLPMask(unsigned NElts
,
148 SmallVectorImpl
<unsigned> &ShuffleMask
) {
149 for (unsigned i
= 0; i
!= NElts
/2; ++i
) {
150 ShuffleMask
.push_back(i
); // Reads from dest
151 ShuffleMask
.push_back(i
+NElts
); // Reads from src