diff options
Diffstat (limited to 'lib/Target/NVPTX/NVPTXAsmPrinter.cpp')
-rw-r--r-- | lib/Target/NVPTX/NVPTXAsmPrinter.cpp | 402 |
1 files changed, 101 insertions, 301 deletions
diff --git a/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/lib/Target/NVPTX/NVPTXAsmPrinter.cpp index 93ba8d5..b417d64 100644 --- a/lib/Target/NVPTX/NVPTXAsmPrinter.cpp +++ b/lib/Target/NVPTX/NVPTXAsmPrinter.cpp @@ -16,6 +16,7 @@ #include "MCTargetDesc/NVPTXMCAsmInfo.h" #include "NVPTX.h" #include "NVPTXInstrInfo.h" +#include "NVPTXMCExpr.h" #include "NVPTXRegisterInfo.h" #include "NVPTXTargetMachine.h" #include "NVPTXUtilities.h" @@ -46,8 +47,6 @@ #include <sstream> using namespace llvm; -#include "NVPTXGenAsmWriter.inc" - bool RegAllocNilUsed = true; #define DEPOTNAME "__local_depot" @@ -309,8 +308,106 @@ void NVPTXAsmPrinter::EmitInstruction(const MachineInstr *MI) { raw_svector_ostream OS(Str); if (nvptxSubtarget.getDrvInterface() == NVPTX::CUDA) emitLineNumberAsDotLoc(*MI); - printInstruction(MI, OS); - OutStreamer.EmitRawText(OS.str()); + + MCInst Inst; + lowerToMCInst(MI, Inst); + OutStreamer.EmitInstruction(Inst); +} + +void NVPTXAsmPrinter::lowerToMCInst(const MachineInstr *MI, MCInst &OutMI) { + OutMI.setOpcode(MI->getOpcode()); + + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + + MCOperand MCOp; + if (lowerOperand(MO, MCOp)) + OutMI.addOperand(MCOp); + } +} + +bool NVPTXAsmPrinter::lowerOperand(const MachineOperand &MO, + MCOperand &MCOp) { + switch (MO.getType()) { + default: llvm_unreachable("unknown operand type"); + case MachineOperand::MO_Register: + MCOp = MCOperand::CreateReg(encodeVirtualRegister(MO.getReg())); + break; + case MachineOperand::MO_Immediate: + MCOp = MCOperand::CreateImm(MO.getImm()); + break; + case MachineOperand::MO_MachineBasicBlock: + MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( + MO.getMBB()->getSymbol(), OutContext)); + break; + case MachineOperand::MO_ExternalSymbol: + MCOp = GetSymbolRef(MO, GetExternalSymbolSymbol(MO.getSymbolName())); + break; + case MachineOperand::MO_GlobalAddress: + MCOp = GetSymbolRef(MO, Mang->getSymbol(MO.getGlobal())); + break; + case MachineOperand::MO_FPImmediate: { + const ConstantFP *Cnt = MO.getFPImm(); + APFloat Val = Cnt->getValueAPF(); + + switch (Cnt->getType()->getTypeID()) { + default: report_fatal_error("Unsupported FP type"); break; + case Type::FloatTyID: + MCOp = MCOperand::CreateExpr( + NVPTXFloatMCExpr::CreateConstantFPSingle(Val, OutContext)); + break; + case Type::DoubleTyID: + MCOp = MCOperand::CreateExpr( + NVPTXFloatMCExpr::CreateConstantFPDouble(Val, OutContext)); + break; + } + break; + } + } + return true; +} + +unsigned NVPTXAsmPrinter::encodeVirtualRegister(unsigned Reg) { + const TargetRegisterClass *RC = MRI->getRegClass(Reg); + + DenseMap<unsigned, unsigned> &RegMap = VRegMapping[RC]; + unsigned RegNum = RegMap[Reg]; + + // Encode the register class in the upper 4 bits + // Must be kept in sync with NVPTXInstPrinter::printRegName + unsigned Ret = 0; + if (RC == &NVPTX::Int1RegsRegClass) { + Ret = 0; + } else if (RC == &NVPTX::Int16RegsRegClass) { + Ret = (1 << 28); + } else if (RC == &NVPTX::Int32RegsRegClass) { + Ret = (2 << 28); + } else if (RC == &NVPTX::Int64RegsRegClass) { + Ret = (3 << 28); + } else if (RC == &NVPTX::Float32RegsRegClass) { + Ret = (4 << 28); + } else if (RC == &NVPTX::Float64RegsRegClass) { + Ret = (5 << 28); + } else { + report_fatal_error("Bad register class"); + } + + // Insert the vreg number + Ret |= (RegNum & 0x0FFFFFFF); + return Ret; +} + +MCOperand NVPTXAsmPrinter::GetSymbolRef(const MachineOperand &MO, + const MCSymbol *Symbol) { + const MCExpr *Expr; + switch (MO.getTargetFlags()) { + default: { + Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, + OutContext); + break; + } + } + return MCOperand::CreateExpr(Expr); } void NVPTXAsmPrinter::printReturnValStr(const Function *F, raw_ostream &O) { @@ -552,268 +649,6 @@ void NVPTXAsmPrinter::printVecModifiedImmediate( llvm_unreachable("Unknown Modifier on immediate operand"); } -void NVPTXAsmPrinter::printOperand(const MachineInstr *MI, int opNum, - raw_ostream &O, const char *Modifier) { - const MachineOperand &MO = MI->getOperand(opNum); - switch (MO.getType()) { - case MachineOperand::MO_Register: - if (TargetRegisterInfo::isPhysicalRegister(MO.getReg())) { - if (MO.getReg() == NVPTX::VRDepot) - O << DEPOTNAME << getFunctionNumber(); - else - O << getRegisterName(MO.getReg()); - } else { - if (!Modifier) - emitVirtualRegister(MO.getReg(), false, O); - else { - if (strcmp(Modifier, "vecfull") == 0) - emitVirtualRegister(MO.getReg(), true, O); - else - llvm_unreachable( - "Don't know how to handle the modifier on virtual register."); - } - } - return; - - case MachineOperand::MO_Immediate: - if (!Modifier) - O << MO.getImm(); - else if (strstr(Modifier, "vec") == Modifier) - printVecModifiedImmediate(MO, Modifier, O); - else - llvm_unreachable( - "Don't know how to handle modifier on immediate operand"); - return; - - case MachineOperand::MO_FPImmediate: - printFPConstant(MO.getFPImm(), O); - break; - - case MachineOperand::MO_GlobalAddress: - O << *Mang->getSymbol(MO.getGlobal()); - break; - - case MachineOperand::MO_ExternalSymbol: { - const char *symbname = MO.getSymbolName(); - if (strstr(symbname, ".PARAM") == symbname) { - unsigned index; - sscanf(symbname + 6, "%u[];", &index); - printParamName(index, O); - } else if (strstr(symbname, ".HLPPARAM") == symbname) { - unsigned index; - sscanf(symbname + 9, "%u[];", &index); - O << *CurrentFnSym << "_param_" << index << "_offset"; - } else - O << symbname; - break; - } - - case MachineOperand::MO_MachineBasicBlock: - O << *MO.getMBB()->getSymbol(); - return; - - default: - llvm_unreachable("Operand type not supported."); - } -} - -void NVPTXAsmPrinter::printImplicitDef(const MachineInstr *MI, - raw_ostream &O) const { -#ifndef __OPTIMIZE__ - O << "\t// Implicit def :"; - //printOperand(MI, 0); - O << "\n"; -#endif -} - -void NVPTXAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum, - raw_ostream &O, const char *Modifier) { - printOperand(MI, opNum, O); - - if (Modifier && !strcmp(Modifier, "add")) { - O << ", "; - printOperand(MI, opNum + 1, O); - } else { - if (MI->getOperand(opNum + 1).isImm() && - MI->getOperand(opNum + 1).getImm() == 0) - return; // don't print ',0' or '+0' - O << "+"; - printOperand(MI, opNum + 1, O); - } -} - -void NVPTXAsmPrinter::printLdStCode(const MachineInstr *MI, int opNum, - raw_ostream &O, const char *Modifier) { - if (Modifier) { - const MachineOperand &MO = MI->getOperand(opNum); - int Imm = (int) MO.getImm(); - if (!strcmp(Modifier, "volatile")) { - if (Imm) - O << ".volatile"; - } else if (!strcmp(Modifier, "addsp")) { - switch (Imm) { - case NVPTX::PTXLdStInstCode::GLOBAL: - O << ".global"; - break; - case NVPTX::PTXLdStInstCode::SHARED: - O << ".shared"; - break; - case NVPTX::PTXLdStInstCode::LOCAL: - O << ".local"; - break; - case NVPTX::PTXLdStInstCode::PARAM: - O << ".param"; - break; - case NVPTX::PTXLdStInstCode::CONSTANT: - O << ".const"; - break; - case NVPTX::PTXLdStInstCode::GENERIC: - if (!nvptxSubtarget.hasGenericLdSt()) - O << ".global"; - break; - default: - llvm_unreachable("Wrong Address Space"); - } - } else if (!strcmp(Modifier, "sign")) { - if (Imm == NVPTX::PTXLdStInstCode::Signed) - O << "s"; - else if (Imm == NVPTX::PTXLdStInstCode::Unsigned) - O << "u"; - else - O << "f"; - } else if (!strcmp(Modifier, "vec")) { - if (Imm == NVPTX::PTXLdStInstCode::V2) - O << ".v2"; - else if (Imm == NVPTX::PTXLdStInstCode::V4) - O << ".v4"; - } else - llvm_unreachable("Unknown Modifier"); - } else - llvm_unreachable("Empty Modifier"); -} - -void NVPTXAsmPrinter::printCvtMode(const MachineInstr *MI, int OpNum, - raw_ostream &O, const char *Modifier) { - const MachineOperand &MO = MI->getOperand(OpNum); - int64_t Imm = MO.getImm(); - - if (strcmp(Modifier, "ftz") == 0) { - // FTZ flag - if (Imm & NVPTX::PTXCvtMode::FTZ_FLAG) - O << ".ftz"; - } else if (strcmp(Modifier, "sat") == 0) { - // SAT flag - if (Imm & NVPTX::PTXCvtMode::SAT_FLAG) - O << ".sat"; - } else if (strcmp(Modifier, "base") == 0) { - // Default operand - switch (Imm & NVPTX::PTXCvtMode::BASE_MASK) { - default: - return; - case NVPTX::PTXCvtMode::NONE: - break; - case NVPTX::PTXCvtMode::RNI: - O << ".rni"; - break; - case NVPTX::PTXCvtMode::RZI: - O << ".rzi"; - break; - case NVPTX::PTXCvtMode::RMI: - O << ".rmi"; - break; - case NVPTX::PTXCvtMode::RPI: - O << ".rpi"; - break; - case NVPTX::PTXCvtMode::RN: - O << ".rn"; - break; - case NVPTX::PTXCvtMode::RZ: - O << ".rz"; - break; - case NVPTX::PTXCvtMode::RM: - O << ".rm"; - break; - case NVPTX::PTXCvtMode::RP: - O << ".rp"; - break; - } - } else { - llvm_unreachable("Invalid conversion modifier"); - } -} - -void NVPTXAsmPrinter::printCmpMode(const MachineInstr *MI, int OpNum, - raw_ostream &O, const char *Modifier) { - const MachineOperand &MO = MI->getOperand(OpNum); - int64_t Imm = MO.getImm(); - - if (strcmp(Modifier, "ftz") == 0) { - // FTZ flag - if (Imm & NVPTX::PTXCmpMode::FTZ_FLAG) - O << ".ftz"; - } else if (strcmp(Modifier, "base") == 0) { - switch (Imm & NVPTX::PTXCmpMode::BASE_MASK) { - default: - return; - case NVPTX::PTXCmpMode::EQ: - O << ".eq"; - break; - case NVPTX::PTXCmpMode::NE: - O << ".ne"; - break; - case NVPTX::PTXCmpMode::LT: - O << ".lt"; - break; - case NVPTX::PTXCmpMode::LE: - O << ".le"; - break; - case NVPTX::PTXCmpMode::GT: - O << ".gt"; - break; - case NVPTX::PTXCmpMode::GE: - O << ".ge"; - break; - case NVPTX::PTXCmpMode::LO: - O << ".lo"; - break; - case NVPTX::PTXCmpMode::LS: - O << ".ls"; - break; - case NVPTX::PTXCmpMode::HI: - O << ".hi"; - break; - case NVPTX::PTXCmpMode::HS: - O << ".hs"; - break; - case NVPTX::PTXCmpMode::EQU: - O << ".equ"; - break; - case NVPTX::PTXCmpMode::NEU: - O << ".neu"; - break; - case NVPTX::PTXCmpMode::LTU: - O << ".ltu"; - break; - case NVPTX::PTXCmpMode::LEU: - O << ".leu"; - break; - case NVPTX::PTXCmpMode::GTU: - O << ".gtu"; - break; - case NVPTX::PTXCmpMode::GEU: - O << ".geu"; - break; - case NVPTX::PTXCmpMode::NUM: - O << ".num"; - break; - case NVPTX::PTXCmpMode::NotANumber: - O << ".nan"; - break; - } - } else { - llvm_unreachable("Empty Modifier"); - } -} void NVPTXAsmPrinter::emitDeclaration(const Function *F, raw_ostream &O) { @@ -2100,41 +1935,6 @@ bool NVPTXAsmPrinter::isImageType(const Type *Ty) { return false; } -/// PrintAsmOperand - Print out an operand for an inline asm expression. -/// -bool NVPTXAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, - const char *ExtraCode, raw_ostream &O) { - if (ExtraCode && ExtraCode[0]) { - if (ExtraCode[1] != 0) - return true; // Unknown modifier. - - switch (ExtraCode[0]) { - default: - // See if this is a generic print operand - return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O); - case 'r': - break; - } - } - - printOperand(MI, OpNo, O); - - return false; -} - -bool NVPTXAsmPrinter::PrintAsmMemoryOperand( - const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, - const char *ExtraCode, raw_ostream &O) { - if (ExtraCode && ExtraCode[0]) - return true; // Unknown modifier - - O << '['; - printMemOperand(MI, OpNo, O); - O << ']'; - - return false; -} bool NVPTXAsmPrinter::ignoreLoc(const MachineInstr &MI) { switch (MI.getOpcode()) { |