diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2014-07-25 23:47:11 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2014-07-25 23:47:11 +0000 |
commit | 185cc18d4265b2822956c91ba65622d8256fdcec (patch) | |
tree | fb0f34f27b604f601514b502da4167c25a0f98ad /llvm/lib/Target/X86/X86MCInstLower.cpp | |
parent | c824458e81db8fdd0d0ca11f906d68ff406b6f9c (diff) | |
download | bcm5719-llvm-185cc18d4265b2822956c91ba65622d8256fdcec.tar.gz bcm5719-llvm-185cc18d4265b2822956c91ba65622d8256fdcec.zip |
[x86] Teach the X86 backend to print shuffle comments for PSHUFB
instructions which happen to have a constant mask.
Currently, this only handles a very narrow set of cases, but those
happen to be the cases that I care about for testing shuffles sanely.
This is a bit trickier than other shuffle instructions because we're
decoding constants out of the constant pool. The current MC layer makes
it completely impossible to inspect a constant pool entry, so we have to
do it at the MI level and attach the comment to the streamer on its way
out. So no joy for disassembling, but it does make test cases and asm
dumps *much* nicer.
Sorry for no test cases, but it didn't really seem that valuable to go
trolling through existing old test cases and updating them. I'll have
lots of testing of this in the upcoming patch for SSSE3 emission in the
new vector shuffle lowering code paths.
llvm-svn: 213986
Diffstat (limited to 'llvm/lib/Target/X86/X86MCInstLower.cpp')
-rw-r--r-- | llvm/lib/Target/X86/X86MCInstLower.cpp | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp index 96ab70a29a3..9fa171ce4d5 100644 --- a/llvm/lib/Target/X86/X86MCInstLower.cpp +++ b/llvm/lib/Target/X86/X86MCInstLower.cpp @@ -16,8 +16,11 @@ #include "X86RegisterInfo.h" #include "InstPrinter/X86ATTInstPrinter.h" #include "MCTargetDesc/X86BaseInfo.h" +#include "Utils/X86ShuffleDecode.h" #include "llvm/ADT/SmallString.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineModuleInfoImpls.h" #include "llvm/CodeGen/StackMaps.h" #include "llvm/IR/DataLayout.h" @@ -963,6 +966,83 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) { case X86::SEH_EndPrologue: OutStreamer.EmitWinCFIEndProlog(); return; + + case X86::PSHUFBrm: + // Lower PSHUFB normally but add a comment if we can find a constant + // shuffle mask. We won't be able to do this at the MC layer because the + // mask isn't an immediate. + std::string Comment; + raw_string_ostream CS(Comment); + SmallVector<int, 16> Mask; + + assert(MI->getNumOperands() == 7 && + "Wrong number of operansd for PSHUFBrm"); + const MachineOperand &DstOp = MI->getOperand(0); + const MachineOperand &SrcOp = MI->getOperand(1); + const MachineOperand &MaskOp = MI->getOperand(5); + + // Compute the name for a register. This is really goofy because we have + // multiple instruction printers that could (in theory) use different + // names. Fortunately most people use the ATT style (outside of Windows) + // and they actually agree on register naming here. Ultimately, this is + // a comment, and so its OK if it isn't perfect. + auto GetRegisterName = [](unsigned RegNum) -> StringRef { + return X86ATTInstPrinter::getRegisterName(RegNum); + }; + + StringRef DstName = DstOp.isReg() ? GetRegisterName(DstOp.getReg()) : "mem"; + StringRef SrcName = SrcOp.isReg() ? GetRegisterName(SrcOp.getReg()) : "mem"; + CS << DstName << " = "; + + if (MaskOp.isCPI()) { + ArrayRef<MachineConstantPoolEntry> Constants = + MI->getParent()->getParent()->getConstantPool()->getConstants(); + const MachineConstantPoolEntry &MaskConstantEntry = + Constants[MI->getOperand(5).getIndex()]; + Type *MaskTy = MaskConstantEntry.getType(); + if (!MaskConstantEntry.isMachineConstantPoolEntry()) + if (auto *C = dyn_cast<ConstantDataSequential>( + MaskConstantEntry.Val.ConstVal)) { + assert(MaskTy == C->getType() && + "Expected a constant of the same type!"); + + DecodePSHUFBMask(C, Mask); + assert(Mask.size() == MaskTy->getVectorNumElements() && + "Shuffle mask has a different size than its type!"); + } + } + + if (!Mask.empty()) { + bool NeedComma = false; + bool InSrc = false; + for (int M : Mask) { + // Wrap up any prior entry... + if (M == SM_SentinelZero && InSrc) { + InSrc = false; + CS << "]"; + } + if (NeedComma) + CS << ","; + else + NeedComma = true; + + // Print this shuffle... + if (M == SM_SentinelZero) { + CS << "zero"; + } else { + if (!InSrc) { + InSrc = true; + CS << SrcName << "["; + } + CS << M; + } + } + if (InSrc) + CS << "]"; + + OutStreamer.AddComment(CS.str()); + } + break; } MCInst TmpInst; |