X86ShuffleDecode.cpp revision 218893
1//===-- 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#include "X86ShuffleDecode.h" 16 17//===----------------------------------------------------------------------===// 18// Vector Mask Decoding 19//===----------------------------------------------------------------------===// 20 21namespace llvm { 22 23void DecodeINSERTPSMask(unsigned Imm, SmallVectorImpl<unsigned> &ShuffleMask) { 24 // Defaults the copying the dest value. 25 ShuffleMask.push_back(0); 26 ShuffleMask.push_back(1); 27 ShuffleMask.push_back(2); 28 ShuffleMask.push_back(3); 29 30 // Decode the immediate. 31 unsigned ZMask = Imm & 15; 32 unsigned CountD = (Imm >> 4) & 3; 33 unsigned CountS = (Imm >> 6) & 3; 34 35 // CountS selects which input element to use. 36 unsigned InVal = 4+CountS; 37 // CountD specifies which element of destination to update. 38 ShuffleMask[CountD] = InVal; 39 // ZMask zaps values, potentially overriding the CountD elt. 40 if (ZMask & 1) ShuffleMask[0] = SM_SentinelZero; 41 if (ZMask & 2) ShuffleMask[1] = SM_SentinelZero; 42 if (ZMask & 4) ShuffleMask[2] = SM_SentinelZero; 43 if (ZMask & 8) ShuffleMask[3] = SM_SentinelZero; 44} 45 46// <3,1> or <6,7,2,3> 47void DecodeMOVHLPSMask(unsigned NElts, 48 SmallVectorImpl<unsigned> &ShuffleMask) { 49 for (unsigned i = NElts/2; i != NElts; ++i) 50 ShuffleMask.push_back(NElts+i); 51 52 for (unsigned i = NElts/2; i != NElts; ++i) 53 ShuffleMask.push_back(i); 54} 55 56// <0,2> or <0,1,4,5> 57void DecodeMOVLHPSMask(unsigned NElts, 58 SmallVectorImpl<unsigned> &ShuffleMask) { 59 for (unsigned i = 0; i != NElts/2; ++i) 60 ShuffleMask.push_back(i); 61 62 for (unsigned i = 0; i != NElts/2; ++i) 63 ShuffleMask.push_back(NElts+i); 64} 65 66void DecodePSHUFMask(unsigned NElts, unsigned Imm, 67 SmallVectorImpl<unsigned> &ShuffleMask) { 68 for (unsigned i = 0; i != NElts; ++i) { 69 ShuffleMask.push_back(Imm % NElts); 70 Imm /= NElts; 71 } 72} 73 74void DecodePSHUFHWMask(unsigned Imm, 75 SmallVectorImpl<unsigned> &ShuffleMask) { 76 ShuffleMask.push_back(0); 77 ShuffleMask.push_back(1); 78 ShuffleMask.push_back(2); 79 ShuffleMask.push_back(3); 80 for (unsigned i = 0; i != 4; ++i) { 81 ShuffleMask.push_back(4+(Imm & 3)); 82 Imm >>= 2; 83 } 84} 85 86void DecodePSHUFLWMask(unsigned Imm, 87 SmallVectorImpl<unsigned> &ShuffleMask) { 88 for (unsigned i = 0; i != 4; ++i) { 89 ShuffleMask.push_back((Imm & 3)); 90 Imm >>= 2; 91 } 92 ShuffleMask.push_back(4); 93 ShuffleMask.push_back(5); 94 ShuffleMask.push_back(6); 95 ShuffleMask.push_back(7); 96} 97 98void DecodePUNPCKLMask(unsigned NElts, 99 SmallVectorImpl<unsigned> &ShuffleMask) { 100 for (unsigned i = 0; i != NElts/2; ++i) { 101 ShuffleMask.push_back(i); 102 ShuffleMask.push_back(i+NElts); 103 } 104} 105 106void DecodePUNPCKHMask(unsigned NElts, 107 SmallVectorImpl<unsigned> &ShuffleMask) { 108 for (unsigned i = 0; i != NElts/2; ++i) { 109 ShuffleMask.push_back(i+NElts/2); 110 ShuffleMask.push_back(i+NElts+NElts/2); 111 } 112} 113 114void DecodeSHUFPSMask(unsigned NElts, unsigned Imm, 115 SmallVectorImpl<unsigned> &ShuffleMask) { 116 // Part that reads from dest. 117 for (unsigned i = 0; i != NElts/2; ++i) { 118 ShuffleMask.push_back(Imm % NElts); 119 Imm /= NElts; 120 } 121 // Part that reads from src. 122 for (unsigned i = 0; i != NElts/2; ++i) { 123 ShuffleMask.push_back(Imm % NElts + NElts); 124 Imm /= NElts; 125 } 126} 127 128void DecodeUNPCKHPMask(unsigned NElts, 129 SmallVectorImpl<unsigned> &ShuffleMask) { 130 for (unsigned i = 0; i != NElts/2; ++i) { 131 ShuffleMask.push_back(i+NElts/2); // Reads from dest 132 ShuffleMask.push_back(i+NElts+NElts/2); // Reads from src 133 } 134} 135 136 137/// DecodeUNPCKLPMask - This decodes the shuffle masks for unpcklps/unpcklpd 138/// etc. NElts indicates the number of elements in the vector allowing it to 139/// handle different datatypes and vector widths. 140void DecodeUNPCKLPMask(unsigned NElts, 141 SmallVectorImpl<unsigned> &ShuffleMask) { 142 for (unsigned i = 0; i != NElts/2; ++i) { 143 ShuffleMask.push_back(i); // Reads from dest 144 ShuffleMask.push_back(i+NElts); // Reads from src 145 } 146} 147 148} // llvm namespace 149