From 6b1d0a3b366a637c0c96ea5cf7cfd8769469e6f3 Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes Date: Thu, 2 Sep 2010 18:40:13 +0000 Subject: [PATCH] Move x86 specific shuffle mask decoding to its own header, it's also going to be used elsewhere. Also trim trailing whitespaces git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112846 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/AsmPrinter/X86InstComments.cpp | 156 ++---------------- lib/Target/X86/X86ShuffleDecode.h | 145 ++++++++++++++++ 2 files changed, 161 insertions(+), 140 deletions(-) create mode 100644 lib/Target/X86/X86ShuffleDecode.h diff --git a/lib/Target/X86/AsmPrinter/X86InstComments.cpp b/lib/Target/X86/AsmPrinter/X86InstComments.cpp index a7d7c554e62..fa1e50b1533 100644 --- a/lib/Target/X86/AsmPrinter/X86InstComments.cpp +++ b/lib/Target/X86/AsmPrinter/X86InstComments.cpp @@ -16,137 +16,13 @@ #include "X86GenInstrNames.inc" #include "llvm/MC/MCInst.h" #include "llvm/Support/raw_ostream.h" +#include "../X86ShuffleDecode.h" using namespace llvm; -//===----------------------------------------------------------------------===// -// Vector Mask Decoding -//===----------------------------------------------------------------------===// - -enum { - SM_SentinelZero = ~0U -}; - -static void DecodeINSERTPSMask(unsigned Imm, - SmallVectorImpl &ShuffleMask) { - // Defaults the copying the dest value. - ShuffleMask.push_back(0); - ShuffleMask.push_back(1); - ShuffleMask.push_back(2); - ShuffleMask.push_back(3); - - // Decode the immediate. - unsigned ZMask = Imm & 15; - unsigned CountD = (Imm >> 4) & 3; - unsigned CountS = (Imm >> 6) & 3; - - // CountS selects which input element to use. - unsigned InVal = 4+CountS; - // CountD specifies which element of destination to update. - ShuffleMask[CountD] = InVal; - // ZMask zaps values, potentially overriding the CountD elt. - if (ZMask & 1) ShuffleMask[0] = SM_SentinelZero; - if (ZMask & 2) ShuffleMask[1] = SM_SentinelZero; - if (ZMask & 4) ShuffleMask[2] = SM_SentinelZero; - if (ZMask & 8) ShuffleMask[3] = SM_SentinelZero; -} - -static void DecodeMOVHLPSMask(SmallVectorImpl &ShuffleMask) { - ShuffleMask.push_back(3); - ShuffleMask.push_back(1); -} - -static void DecodeMOVLHPSMask(SmallVectorImpl &ShuffleMask) { - ShuffleMask.push_back(0); - ShuffleMask.push_back(2); -} - -static void DecodePSHUFMask(unsigned NElts, unsigned Imm, - SmallVectorImpl &ShuffleMask) { - for (unsigned i = 0; i != NElts; ++i) { - ShuffleMask.push_back(Imm % NElts); - Imm /= NElts; - } -} - -static void DecodePSHUFHWMask(unsigned Imm, - SmallVectorImpl &ShuffleMask) { - ShuffleMask.push_back(0); - ShuffleMask.push_back(1); - ShuffleMask.push_back(2); - ShuffleMask.push_back(3); - for (unsigned i = 0; i != 4; ++i) { - ShuffleMask.push_back(4+(Imm & 3)); - Imm >>= 2; - } -} - -static void DecodePSHUFLWMask(unsigned Imm, - SmallVectorImpl &ShuffleMask) { - for (unsigned i = 0; i != 4; ++i) { - ShuffleMask.push_back((Imm & 3)); - Imm >>= 2; - } - ShuffleMask.push_back(4); - ShuffleMask.push_back(5); - ShuffleMask.push_back(6); - ShuffleMask.push_back(7); -} - -static void DecodePUNPCKLMask(unsigned NElts, - SmallVectorImpl &ShuffleMask) { - for (unsigned i = 0; i != NElts/2; ++i) { - ShuffleMask.push_back(i); - ShuffleMask.push_back(i+NElts); - } -} - -static void DecodePUNPCKHMask(unsigned NElts, - SmallVectorImpl &ShuffleMask) { - for (unsigned i = 0; i != NElts/2; ++i) { - ShuffleMask.push_back(i+NElts/2); - ShuffleMask.push_back(i+NElts+NElts/2); - } -} - -static void DecodeSHUFPSMask(unsigned NElts, unsigned Imm, - SmallVectorImpl &ShuffleMask) { - // Part that reads from dest. - for (unsigned i = 0; i != NElts/2; ++i) { - ShuffleMask.push_back(Imm % NElts); - Imm /= NElts; - } - // Part that reads from src. - for (unsigned i = 0; i != NElts/2; ++i) { - ShuffleMask.push_back(Imm % NElts + NElts); - Imm /= NElts; - } -} - -static void DecodeUNPCKHPMask(unsigned NElts, - SmallVectorImpl &ShuffleMask) { - for (unsigned i = 0; i != NElts/2; ++i) { - ShuffleMask.push_back(i+NElts/2); // Reads from dest - ShuffleMask.push_back(i+NElts+NElts/2); // Reads from src - } -} - - -/// DecodeUNPCKLPMask - This decodes the shuffle masks for unpcklps/unpcklpd -/// etc. NElts indicates the number of elements in the vector allowing it to -/// handle different datatypes and vector widths. -static void DecodeUNPCKLPMask(unsigned NElts, - SmallVectorImpl &ShuffleMask) { - for (unsigned i = 0; i != NElts/2; ++i) { - ShuffleMask.push_back(i); // Reads from dest - ShuffleMask.push_back(i+NElts); // Reads from src - } -} - //===----------------------------------------------------------------------===// // Top Level Entrypoint //===----------------------------------------------------------------------===// - /// EmitAnyX86InstComments - This function decodes x86 instructions and prints /// newline terminated strings to the specified string if desired. This /// information is shown in disassembly dumps when verbose assembly is enabled. @@ -155,26 +31,26 @@ void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS, // If this is a shuffle operation, the switch should fill in this state. SmallVector ShuffleMask; const char *DestName = 0, *Src1Name = 0, *Src2Name = 0; - + switch (MI->getOpcode()) { case X86::INSERTPSrr: Src1Name = getRegName(MI->getOperand(1).getReg()); Src2Name = getRegName(MI->getOperand(2).getReg()); DecodeINSERTPSMask(MI->getOperand(3).getImm(), ShuffleMask); break; - + case X86::MOVLHPSrr: Src2Name = getRegName(MI->getOperand(2).getReg()); Src1Name = getRegName(MI->getOperand(0).getReg()); DecodeMOVLHPSMask(ShuffleMask); break; - + case X86::MOVHLPSrr: Src2Name = getRegName(MI->getOperand(2).getReg()); Src1Name = getRegName(MI->getOperand(0).getReg()); DecodeMOVHLPSMask(ShuffleMask); break; - + case X86::PSHUFDri: Src1Name = getRegName(MI->getOperand(1).getReg()); // FALL THROUGH. @@ -183,7 +59,7 @@ void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS, DecodePSHUFMask(4, MI->getOperand(MI->getNumOperands()-1).getImm(), ShuffleMask); break; - + case X86::PSHUFHWri: Src1Name = getRegName(MI->getOperand(1).getReg()); // FALL THROUGH. @@ -200,7 +76,7 @@ void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS, DecodePSHUFLWMask(MI->getOperand(MI->getNumOperands()-1).getImm(), ShuffleMask); break; - + case X86::PUNPCKHBWrr: Src2Name = getRegName(MI->getOperand(2).getReg()); // FALL THROUGH. @@ -229,7 +105,7 @@ void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS, Src1Name = getRegName(MI->getOperand(0).getReg()); DecodePUNPCKHMask(2, ShuffleMask); break; - + case X86::PUNPCKLBWrr: Src2Name = getRegName(MI->getOperand(2).getReg()); // FALL THROUGH. @@ -258,13 +134,13 @@ void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS, Src1Name = getRegName(MI->getOperand(0).getReg()); DecodePUNPCKLMask(2, ShuffleMask); break; - + case X86::SHUFPDrri: DecodeSHUFPSMask(2, MI->getOperand(3).getImm(), ShuffleMask); Src1Name = getRegName(MI->getOperand(0).getReg()); Src2Name = getRegName(MI->getOperand(2).getReg()); break; - + case X86::SHUFPSrri: Src2Name = getRegName(MI->getOperand(2).getReg()); // FALL THROUGH. @@ -272,7 +148,7 @@ void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS, DecodeSHUFPSMask(4, MI->getOperand(3).getImm(), ShuffleMask); Src1Name = getRegName(MI->getOperand(0).getReg()); break; - + case X86::UNPCKLPDrr: Src2Name = getRegName(MI->getOperand(2).getReg()); // FALL THROUGH. @@ -303,12 +179,12 @@ void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS, break; } - + // If this was a shuffle operation, print the shuffle mask. if (!ShuffleMask.empty()) { if (DestName == 0) DestName = Src1Name; OS << (DestName ? DestName : "mem") << " = "; - + // If the two sources are the same, canonicalize the input elements to be // from the first src so that we get larger element spans. if (Src1Name == Src2Name) { @@ -318,7 +194,7 @@ void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS, ShuffleMask[i] -= e; } } - + // The shuffle mask specifies which elements of the src1/src2 fill in the // destination, with a few sentinel values. Loop through and print them // out. @@ -329,7 +205,7 @@ void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS, OS << "zero"; continue; } - + // Otherwise, it must come from src1 or src2. Print the span of elements // that comes from this src. bool isSrc1 = ShuffleMask[i] < ShuffleMask.size(); @@ -352,5 +228,5 @@ void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS, //MI->print(OS, 0); OS << "\n"; } - + } diff --git a/lib/Target/X86/X86ShuffleDecode.h b/lib/Target/X86/X86ShuffleDecode.h new file mode 100644 index 00000000000..4d24c839f54 --- /dev/null +++ b/lib/Target/X86/X86ShuffleDecode.h @@ -0,0 +1,145 @@ +//===-- X86ShuffleDecode.h - X86 shuffle decode logic ---------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Define several functions to decode x86 specific shuffle semantics into a +// generic vector mask. +// +//===----------------------------------------------------------------------===// + +#ifndef X86_SHUFFLE_DECODE_H +#define X86_SHUFFLE_DECODE_H + +#include "llvm/ADT/SmallVector.h" +using namespace llvm; + +//===----------------------------------------------------------------------===// +// Vector Mask Decoding +//===----------------------------------------------------------------------===// + +enum { + SM_SentinelZero = ~0U +}; + +static void DecodeINSERTPSMask(unsigned Imm, + SmallVectorImpl &ShuffleMask) { + // Defaults the copying the dest value. + ShuffleMask.push_back(0); + ShuffleMask.push_back(1); + ShuffleMask.push_back(2); + ShuffleMask.push_back(3); + + // Decode the immediate. + unsigned ZMask = Imm & 15; + unsigned CountD = (Imm >> 4) & 3; + unsigned CountS = (Imm >> 6) & 3; + + // CountS selects which input element to use. + unsigned InVal = 4+CountS; + // CountD specifies which element of destination to update. + ShuffleMask[CountD] = InVal; + // ZMask zaps values, potentially overriding the CountD elt. + if (ZMask & 1) ShuffleMask[0] = SM_SentinelZero; + if (ZMask & 2) ShuffleMask[1] = SM_SentinelZero; + if (ZMask & 4) ShuffleMask[2] = SM_SentinelZero; + if (ZMask & 8) ShuffleMask[3] = SM_SentinelZero; +} + +static void DecodeMOVHLPSMask(SmallVectorImpl &ShuffleMask) { + ShuffleMask.push_back(3); + ShuffleMask.push_back(1); +} + +static void DecodeMOVLHPSMask(SmallVectorImpl &ShuffleMask) { + ShuffleMask.push_back(0); + ShuffleMask.push_back(2); +} + +static void DecodePSHUFMask(unsigned NElts, unsigned Imm, + SmallVectorImpl &ShuffleMask) { + for (unsigned i = 0; i != NElts; ++i) { + ShuffleMask.push_back(Imm % NElts); + Imm /= NElts; + } +} + +static void DecodePSHUFHWMask(unsigned Imm, + SmallVectorImpl &ShuffleMask) { + ShuffleMask.push_back(0); + ShuffleMask.push_back(1); + ShuffleMask.push_back(2); + ShuffleMask.push_back(3); + for (unsigned i = 0; i != 4; ++i) { + ShuffleMask.push_back(4+(Imm & 3)); + Imm >>= 2; + } +} + +static void DecodePSHUFLWMask(unsigned Imm, + SmallVectorImpl &ShuffleMask) { + for (unsigned i = 0; i != 4; ++i) { + ShuffleMask.push_back((Imm & 3)); + Imm >>= 2; + } + ShuffleMask.push_back(4); + ShuffleMask.push_back(5); + ShuffleMask.push_back(6); + ShuffleMask.push_back(7); +} + +static void DecodePUNPCKLMask(unsigned NElts, + SmallVectorImpl &ShuffleMask) { + for (unsigned i = 0; i != NElts/2; ++i) { + ShuffleMask.push_back(i); + ShuffleMask.push_back(i+NElts); + } +} + +static void DecodePUNPCKHMask(unsigned NElts, + SmallVectorImpl &ShuffleMask) { + for (unsigned i = 0; i != NElts/2; ++i) { + ShuffleMask.push_back(i+NElts/2); + ShuffleMask.push_back(i+NElts+NElts/2); + } +} + +static void DecodeSHUFPSMask(unsigned NElts, unsigned Imm, + SmallVectorImpl &ShuffleMask) { + // Part that reads from dest. + for (unsigned i = 0; i != NElts/2; ++i) { + ShuffleMask.push_back(Imm % NElts); + Imm /= NElts; + } + // Part that reads from src. + for (unsigned i = 0; i != NElts/2; ++i) { + ShuffleMask.push_back(Imm % NElts + NElts); + Imm /= NElts; + } +} + +static void DecodeUNPCKHPMask(unsigned NElts, + SmallVectorImpl &ShuffleMask) { + for (unsigned i = 0; i != NElts/2; ++i) { + ShuffleMask.push_back(i+NElts/2); // Reads from dest + ShuffleMask.push_back(i+NElts+NElts/2); // Reads from src + } +} + + +/// DecodeUNPCKLPMask - This decodes the shuffle masks for unpcklps/unpcklpd +/// etc. NElts indicates the number of elements in the vector allowing it to +/// handle different datatypes and vector widths. +static void DecodeUNPCKLPMask(unsigned NElts, + SmallVectorImpl &ShuffleMask) { + for (unsigned i = 0; i != NElts/2; ++i) { + ShuffleMask.push_back(i); // Reads from dest + ShuffleMask.push_back(i+NElts); // Reads from src + } +} + +#endif