blob: 818f7ca74b67908b1dd668495db9debeafb3b94a [file] [log] [blame]
Bruno Cardoso Lopes6b1d0a32010-09-02 18:40:13 +00001//===-- X86ShuffleDecode.h - 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#ifndef X86_SHUFFLE_DECODE_H
16#define X86_SHUFFLE_DECODE_H
17
18#include "llvm/ADT/SmallVector.h"
19using namespace llvm;
20
21//===----------------------------------------------------------------------===//
22// Vector Mask Decoding
23//===----------------------------------------------------------------------===//
24
25enum {
26 SM_SentinelZero = ~0U
27};
28
Bruno Cardoso Lopes55945602010-09-02 21:51:11 +000029// <3,1> or <6,7,2,3>
30static void DecodeMOVHLPSMask(unsigned NElts,
31 SmallVectorImpl<unsigned> &ShuffleMask) {
32 for (unsigned i = NElts/2; i != NElts; ++i)
33 ShuffleMask.push_back(NElts+i);
Bruno Cardoso Lopes6b1d0a32010-09-02 18:40:13 +000034
Bruno Cardoso Lopes55945602010-09-02 21:51:11 +000035 for (unsigned i = NElts/2; i != NElts; ++i)
36 ShuffleMask.push_back(i);
Bruno Cardoso Lopes6b1d0a32010-09-02 18:40:13 +000037}
38
Bruno Cardoso Lopes55945602010-09-02 21:51:11 +000039// <0,2> or <0,1,4,5>
40static void DecodeMOVLHPSMask(unsigned NElts,
41 SmallVectorImpl<unsigned> &ShuffleMask) {
42 for (unsigned i = 0; i != NElts/2; ++i)
43 ShuffleMask.push_back(i);
Bruno Cardoso Lopes6b1d0a32010-09-02 18:40:13 +000044
Bruno Cardoso Lopes55945602010-09-02 21:51:11 +000045 for (unsigned i = 0; i != NElts/2; ++i)
46 ShuffleMask.push_back(NElts+i);
Bruno Cardoso Lopes6b1d0a32010-09-02 18:40:13 +000047}
48
49static void DecodePSHUFMask(unsigned NElts, unsigned Imm,
50 SmallVectorImpl<unsigned> &ShuffleMask) {
51 for (unsigned i = 0; i != NElts; ++i) {
52 ShuffleMask.push_back(Imm % NElts);
53 Imm /= NElts;
54 }
55}
56
57static void DecodePSHUFHWMask(unsigned Imm,
58 SmallVectorImpl<unsigned> &ShuffleMask) {
59 ShuffleMask.push_back(0);
60 ShuffleMask.push_back(1);
61 ShuffleMask.push_back(2);
62 ShuffleMask.push_back(3);
63 for (unsigned i = 0; i != 4; ++i) {
64 ShuffleMask.push_back(4+(Imm & 3));
65 Imm >>= 2;
66 }
67}
68
69static void DecodePSHUFLWMask(unsigned Imm,
70 SmallVectorImpl<unsigned> &ShuffleMask) {
71 for (unsigned i = 0; i != 4; ++i) {
72 ShuffleMask.push_back((Imm & 3));
73 Imm >>= 2;
74 }
75 ShuffleMask.push_back(4);
76 ShuffleMask.push_back(5);
77 ShuffleMask.push_back(6);
78 ShuffleMask.push_back(7);
79}
80
81static void DecodePUNPCKLMask(unsigned NElts,
82 SmallVectorImpl<unsigned> &ShuffleMask) {
83 for (unsigned i = 0; i != NElts/2; ++i) {
84 ShuffleMask.push_back(i);
85 ShuffleMask.push_back(i+NElts);
86 }
87}
88
89static void DecodePUNPCKHMask(unsigned NElts,
90 SmallVectorImpl<unsigned> &ShuffleMask) {
91 for (unsigned i = 0; i != NElts/2; ++i) {
92 ShuffleMask.push_back(i+NElts/2);
93 ShuffleMask.push_back(i+NElts+NElts/2);
94 }
95}
96
97static void DecodeSHUFPSMask(unsigned NElts, unsigned Imm,
98 SmallVectorImpl<unsigned> &ShuffleMask) {
99 // Part that reads from dest.
100 for (unsigned i = 0; i != NElts/2; ++i) {
101 ShuffleMask.push_back(Imm % NElts);
102 Imm /= NElts;
103 }
104 // Part that reads from src.
105 for (unsigned i = 0; i != NElts/2; ++i) {
106 ShuffleMask.push_back(Imm % NElts + NElts);
107 Imm /= NElts;
108 }
109}
110
111static void DecodeUNPCKHPMask(unsigned NElts,
112 SmallVectorImpl<unsigned> &ShuffleMask) {
113 for (unsigned i = 0; i != NElts/2; ++i) {
114 ShuffleMask.push_back(i+NElts/2); // Reads from dest
115 ShuffleMask.push_back(i+NElts+NElts/2); // Reads from src
116 }
117}
118
119
120/// DecodeUNPCKLPMask - This decodes the shuffle masks for unpcklps/unpcklpd
121/// etc. NElts indicates the number of elements in the vector allowing it to
122/// handle different datatypes and vector widths.
123static void DecodeUNPCKLPMask(unsigned NElts,
124 SmallVectorImpl<unsigned> &ShuffleMask) {
125 for (unsigned i = 0; i != NElts/2; ++i) {
126 ShuffleMask.push_back(i); // Reads from dest
127 ShuffleMask.push_back(i+NElts); // Reads from src
128 }
129}
130
131#endif