diff options
Diffstat (limited to 'contrib/llvm/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp | 137 |
1 files changed, 130 insertions, 7 deletions
diff --git a/contrib/llvm/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp b/contrib/llvm/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp index 303cdf2..99e1377 100644 --- a/contrib/llvm/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp +++ b/contrib/llvm/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp @@ -10,8 +10,8 @@ #include "AMDGPUInstPrinter.h" #include "MCTargetDesc/AMDGPUMCTargetDesc.h" -#include "llvm/MC/MCInst.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" using namespace llvm; @@ -23,6 +23,63 @@ void AMDGPUInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, printAnnotation(OS, Annot); } +void AMDGPUInstPrinter::printRegOperand(unsigned reg, raw_ostream &O) { + switch (reg) { + case AMDGPU::VCC: + O << "vcc"; + return; + case AMDGPU::SCC: + O << "scc"; + return; + case AMDGPU::EXEC: + O << "exec"; + return; + case AMDGPU::M0: + O << "m0"; + return; + default: + break; + } + + // It's seems there's no way to use SIRegisterInfo here, and dealing with the + // giant enum of all the different shifted sets of registers is pretty + // unmanagable, so parse the name and reformat it to be prettier. + StringRef Name(getRegisterName(reg)); + + std::pair<StringRef, StringRef> Split = Name.split('_'); + StringRef SubRegName = Split.first; + StringRef Rest = Split.second; + + if (SubRegName.size() <= 4) { // Must at least be as long as "SGPR"/"VGPR". + O << Name; + return; + } + + unsigned RegIndex; + StringRef RegIndexStr = SubRegName.drop_front(4); + + if (RegIndexStr.getAsInteger(10, RegIndex)) { + O << Name; + return; + } + + if (SubRegName.front() == 'V') + O << 'v'; + else if (SubRegName.front() == 'S') + O << 's'; + else { + O << Name; + return; + } + + if (Rest.empty()) // Only 1 32-bit register + O << RegIndex; + else { + unsigned NumReg = Rest.count('_') + 2; + O << '[' << RegIndex << ':' << (RegIndex + NumReg - 1) << ']'; + } +} + void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) { @@ -30,8 +87,12 @@ void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, if (Op.isReg()) { switch (Op.getReg()) { // This is the default predicate state, so we don't need to print it. - case AMDGPU::PRED_SEL_OFF: break; - default: O << getRegisterName(Op.getReg()); break; + case AMDGPU::PRED_SEL_OFF: + break; + + default: + printRegOperand(Op.getReg(), O); + break; } } else if (Op.isImm()) { O << Op.getImm(); @@ -102,7 +163,7 @@ void AMDGPUInstPrinter::printLiteral(const MCInst *MI, unsigned OpNo, void AMDGPUInstPrinter::printLast(const MCInst *MI, unsigned OpNo, raw_ostream &O) { - printIfSet(MI, OpNo, O.indent(20 - O.GetNumBytesInBuffer()), "*", " "); + printIfSet(MI, OpNo, O.indent(25 - O.GetNumBytesInBuffer()), "*", " "); } void AMDGPUInstPrinter::printNeg(const MCInst *MI, unsigned OpNo, @@ -178,13 +239,13 @@ void AMDGPUInstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo, int BankSwizzle = MI->getOperand(OpNo).getImm(); switch (BankSwizzle) { case 1: - O << "BS:VEC_021"; + O << "BS:VEC_021/SCL_122"; break; case 2: - O << "BS:VEC_120"; + O << "BS:VEC_120/SCL_212"; break; case 3: - O << "BS:VEC_102"; + O << "BS:VEC_102/SCL_221"; break; case 4: O << "BS:VEC_201"; @@ -198,6 +259,51 @@ void AMDGPUInstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo, return; } +void AMDGPUInstPrinter::printRSel(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + unsigned Sel = MI->getOperand(OpNo).getImm(); + switch (Sel) { + case 0: + O << "X"; + break; + case 1: + O << "Y"; + break; + case 2: + O << "Z"; + break; + case 3: + O << "W"; + break; + case 4: + O << "0"; + break; + case 5: + O << "1"; + break; + case 7: + O << "_"; + break; + default: + break; + } +} + +void AMDGPUInstPrinter::printCT(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + unsigned CT = MI->getOperand(OpNo).getImm(); + switch (CT) { + case 0: + O << "U"; + break; + case 1: + O << "N"; + break; + default: + break; + } +} + void AMDGPUInstPrinter::printKCache(const MCInst *MI, unsigned OpNo, raw_ostream &O) { int KCacheMode = MI->getOperand(OpNo).getImm(); @@ -210,4 +316,21 @@ void AMDGPUInstPrinter::printKCache(const MCInst *MI, unsigned OpNo, } } +void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + // Note: Mask values are taken from SIInsertWaits.cpp and not from ISA docs + // SIInsertWaits.cpp bits usage does not match ISA docs description but it + // works so it might be a misprint in docs. + unsigned SImm16 = MI->getOperand(OpNo).getImm(); + unsigned Vmcnt = SImm16 & 0xF; + unsigned Expcnt = (SImm16 >> 4) & 0xF; + unsigned Lgkmcnt = (SImm16 >> 8) & 0xF; + if (Vmcnt != 0xF) + O << "vmcnt(" << Vmcnt << ") "; + if (Expcnt != 0x7) + O << "expcnt(" << Expcnt << ") "; + if (Lgkmcnt != 0x7) + O << "lgkmcnt(" << Lgkmcnt << ")"; +} + #include "AMDGPUGenAsmWriter.inc" |