diff options
author | Justin Holewinski <jholewinski@nvidia.com> | 2013-08-06 14:13:27 +0000 |
---|---|---|
committer | Justin Holewinski <jholewinski@nvidia.com> | 2013-08-06 14:13:27 +0000 |
commit | 82767327c59ede1f8663ec9b9a64a668993d501f (patch) | |
tree | f6e6c75ebb7e82f6d86053b46551572aedb5d621 /lib/Target/NVPTX | |
parent | 8775a51d94b277ca6ebe12a1d20bfc2bc5a53960 (diff) | |
download | external_llvm-82767327c59ede1f8663ec9b9a64a668993d501f.zip external_llvm-82767327c59ede1f8663ec9b9a64a668993d501f.tar.gz external_llvm-82767327c59ede1f8663ec9b9a64a668993d501f.tar.bz2 |
[NVPTX] Start conversion to MC infrastructure
This change converts the NVPTX target to use the MC infrastructure
instead of directly emitting MachineInstr instances. This brings
the target more up-to-date with LLVM TOT, and should fix PR15175
and PR15958 (libNVPTXInstPrinter is empty) as a side-effect.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187798 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/NVPTX')
-rw-r--r-- | lib/Target/NVPTX/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/Target/NVPTX/InstPrinter/NVPTXInstPrinter.cpp | 275 | ||||
-rw-r--r-- | lib/Target/NVPTX/InstPrinter/NVPTXInstPrinter.h | 52 | ||||
-rw-r--r-- | lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp | 17 | ||||
-rw-r--r-- | lib/Target/NVPTX/NVPTX.td | 6 | ||||
-rw-r--r-- | lib/Target/NVPTX/NVPTXAsmPrinter.cpp | 402 | ||||
-rw-r--r-- | lib/Target/NVPTX/NVPTXAsmPrinter.h | 18 | ||||
-rw-r--r-- | lib/Target/NVPTX/NVPTXISelLowering.cpp | 10 | ||||
-rw-r--r-- | lib/Target/NVPTX/NVPTXMCExpr.cpp | 46 | ||||
-rw-r--r-- | lib/Target/NVPTX/NVPTXMCExpr.h | 83 |
10 files changed, 593 insertions, 317 deletions
diff --git a/lib/Target/NVPTX/CMakeLists.txt b/lib/Target/NVPTX/CMakeLists.txt index be8d323..4f1324c 100644 --- a/lib/Target/NVPTX/CMakeLists.txt +++ b/lib/Target/NVPTX/CMakeLists.txt @@ -25,6 +25,7 @@ set(NVPTXCodeGen_sources NVVMReflect.cpp NVPTXGenericToNVVM.cpp NVPTXPrologEpilogPass.cpp + NVPTXMCExpr.cpp ) add_llvm_target(NVPTXCodeGen ${NVPTXCodeGen_sources}) diff --git a/lib/Target/NVPTX/InstPrinter/NVPTXInstPrinter.cpp b/lib/Target/NVPTX/InstPrinter/NVPTXInstPrinter.cpp index 10051c7..1cb8a9a 100644 --- a/lib/Target/NVPTX/InstPrinter/NVPTXInstPrinter.cpp +++ b/lib/Target/NVPTX/InstPrinter/NVPTXInstPrinter.cpp @@ -1 +1,274 @@ -// Placeholder +//===-- NVPTXInstPrinter.cpp - PTX assembly instruction printing ----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Print MCInst instructions to .ptx format. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "asm-printer" +#include "InstPrinter/NVPTXInstPrinter.h" +#include "NVPTX.h" +#include "MCTargetDesc/NVPTXBaseInfo.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FormattedStream.h" +#include <cctype> +using namespace llvm; + +#include "NVPTXGenAsmWriter.inc" + + +NVPTXInstPrinter::NVPTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, + const MCRegisterInfo &MRI, + const MCSubtargetInfo &STI) + : MCInstPrinter(MAI, MII, MRI) { + setAvailableFeatures(STI.getFeatureBits()); +} + +void NVPTXInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { + // Decode the virtual register + // Must be kept in sync with NVPTXAsmPrinter::encodeVirtualRegister + unsigned RCId = (RegNo >> 28); + switch (RCId) { + default: report_fatal_error("Bad virtual register encoding"); + case 0: + OS << "%p"; + break; + case 1: + OS << "%rs"; + break; + case 2: + OS << "%r"; + break; + case 3: + OS << "%rl"; + break; + case 4: + OS << "%f"; + break; + case 5: + OS << "%fl"; + break; + } + + unsigned VReg = RegNo & 0x0FFFFFFF; + OS << VReg; +} + +void NVPTXInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, + StringRef Annot) { + printInstruction(MI, OS); + + // Next always print the annotation. + printAnnotation(OS, Annot); +} + +void NVPTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + const MCOperand &Op = MI->getOperand(OpNo); + if (Op.isReg()) { + unsigned Reg = Op.getReg(); + printRegName(O, Reg); + } else if (Op.isImm()) { + O << markup("<imm:") << formatImm(Op.getImm()) << markup(">"); + } else { + assert(Op.isExpr() && "Unknown operand kind in printOperand"); + O << *Op.getExpr(); + } +} + +void NVPTXInstPrinter::printCvtMode(const MCInst *MI, int OpNum, raw_ostream &O, + const char *Modifier) { + const MCOperand &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 NVPTXInstPrinter::printCmpMode(const MCInst *MI, int OpNum, raw_ostream &O, + const char *Modifier) { + const MCOperand &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 NVPTXInstPrinter::printLdStCode(const MCInst *MI, int OpNum, + raw_ostream &O, const char *Modifier) { + if (Modifier) { + const MCOperand &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: + 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 NVPTXInstPrinter::printMemOperand(const MCInst *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); + } +} diff --git a/lib/Target/NVPTX/InstPrinter/NVPTXInstPrinter.h b/lib/Target/NVPTX/InstPrinter/NVPTXInstPrinter.h new file mode 100644 index 0000000..e0f44da --- /dev/null +++ b/lib/Target/NVPTX/InstPrinter/NVPTXInstPrinter.h @@ -0,0 +1,52 @@ +//= NVPTXInstPrinter.h - Convert NVPTX MCInst to assembly syntax --*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class prints an NVPTX MCInst to .ptx file syntax. +// +//===----------------------------------------------------------------------===// + +#ifndef NVPTX_INST_PRINTER_H +#define NVPTX_INST_PRINTER_H + +#include "llvm/MC/MCInstPrinter.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { + +class MCOperand; +class MCSubtargetInfo; + +class NVPTXInstPrinter : public MCInstPrinter { +public: + NVPTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, + const MCRegisterInfo &MRI, const MCSubtargetInfo &STI); + + virtual void printRegName(raw_ostream &OS, unsigned RegNo) const; + virtual void printInst(const MCInst *MI, raw_ostream &OS, StringRef Annot); + + // Autogenerated by tblgen. + void printInstruction(const MCInst *MI, raw_ostream &O); + static const char *getRegisterName(unsigned RegNo); + // End + + void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printCvtMode(const MCInst *MI, int OpNum, raw_ostream &O, + const char *Modifier = 0); + void printCmpMode(const MCInst *MI, int OpNum, raw_ostream &O, + const char *Modifier = 0); + void printLdStCode(const MCInst *MI, int OpNum, + raw_ostream &O, const char *Modifier = 0); + void printMemOperand(const MCInst *MI, int OpNum, + raw_ostream &O, const char *Modifier = 0); + +}; + +} + +#endif diff --git a/lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp b/lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp index ccd2970..871bac9 100644 --- a/lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp +++ b/lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp @@ -13,6 +13,7 @@ #include "NVPTXMCTargetDesc.h" #include "NVPTXMCAsmInfo.h" +#include "InstPrinter/NVPTXInstPrinter.h" #include "llvm/MC/MCCodeGenInfo.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" @@ -57,6 +58,17 @@ static MCCodeGenInfo *createNVPTXMCCodeGenInfo( return X; } +static MCInstPrinter *createNVPTXMCInstPrinter(const Target &T, + unsigned SyntaxVariant, + const MCAsmInfo &MAI, + const MCInstrInfo &MII, + const MCRegisterInfo &MRI, + const MCSubtargetInfo &STI) { + if (SyntaxVariant == 0) + return new NVPTXInstPrinter(MAI, MII, MRI, STI); + return 0; +} + // Force static initialization. extern "C" void LLVMInitializeNVPTXTargetMC() { // Register the MC asm info. @@ -85,4 +97,9 @@ extern "C" void LLVMInitializeNVPTXTargetMC() { TargetRegistry::RegisterMCSubtargetInfo(TheNVPTXTarget64, createNVPTXMCSubtargetInfo); + // Register the MCInstPrinter. + TargetRegistry::RegisterMCInstPrinter(TheNVPTXTarget32, + createNVPTXMCInstPrinter); + TargetRegistry::RegisterMCInstPrinter(TheNVPTXTarget64, + createNVPTXMCInstPrinter); } diff --git a/lib/Target/NVPTX/NVPTX.td b/lib/Target/NVPTX/NVPTX.td index d78b4e8..6183a75 100644 --- a/lib/Target/NVPTX/NVPTX.td +++ b/lib/Target/NVPTX/NVPTX.td @@ -57,6 +57,12 @@ def : Proc<"sm_35", [SM35]>; def NVPTXInstrInfo : InstrInfo { } +def NVPTXAsmWriter : AsmWriter { + bit isMCAsmWriter = 1; + string AsmWriterClassName = "InstPrinter"; +} + def NVPTX : Target { let InstructionSet = NVPTXInstrInfo; + let AssemblyWriters = [NVPTXAsmWriter]; } 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()) { diff --git a/lib/Target/NVPTX/NVPTXAsmPrinter.h b/lib/Target/NVPTX/NVPTXAsmPrinter.h index c7b7fb0..27bfa54 100644 --- a/lib/Target/NVPTX/NVPTXAsmPrinter.h +++ b/lib/Target/NVPTX/NVPTXAsmPrinter.h @@ -190,18 +190,14 @@ private: void EmitFunctionBodyEnd(); void EmitInstruction(const MachineInstr *); + void lowerToMCInst(const MachineInstr *MI, MCInst &OutMI); + bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp); + MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol); + unsigned encodeVirtualRegister(unsigned Reg); void EmitAlignment(unsigned NumBits, const GlobalValue *GV = 0) const {} void printGlobalVariable(const GlobalVariable *GVar); - void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O, - const char *Modifier = 0); - void printLdStCode(const MachineInstr *MI, int opNum, raw_ostream &O, - const char *Modifier = 0); - void printCvtMode(const MachineInstr *MI, int OpNum, raw_ostream &O, - const char *Modifier = 0); - void printCmpMode(const MachineInstr *MI, int OpNum, raw_ostream &O, - const char *Modifier = 0); void printVecModifiedImmediate(const MachineOperand &MO, const char *Modifier, raw_ostream &O); void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O, @@ -224,12 +220,6 @@ private: void setAndEmitFunctionVirtualRegisters(const MachineFunction &MF); void emitFunctionTempData(const MachineFunction &MF, unsigned &FrameSize); bool isImageType(const Type *Ty); - bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode, - raw_ostream &); - bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode, - raw_ostream &); void printReturnValStr(const Function *, raw_ostream &O); void printReturnValStr(const MachineFunction &MF, raw_ostream &O); diff --git a/lib/Target/NVPTX/NVPTXISelLowering.cpp b/lib/Target/NVPTX/NVPTXISelLowering.cpp index c89c2fc..828242d 100644 --- a/lib/Target/NVPTX/NVPTXISelLowering.cpp +++ b/lib/Target/NVPTX/NVPTXISelLowering.cpp @@ -1316,7 +1316,15 @@ SDValue NVPTXTargetLowering::getExtSymb(SelectionDAG &DAG, const char *inname, SDValue NVPTXTargetLowering::getParamSymbol(SelectionDAG &DAG, int idx, EVT v) const { - return getExtSymb(DAG, ".PARAM", idx, v); + std::string ParamSym; + raw_string_ostream ParamStr(ParamSym); + + ParamStr << DAG.getMachineFunction().getName() << "_param_" << idx; + ParamStr.flush(); + + std::string *SavedStr = + nvTM->getManagedStrPool()->getManagedString(ParamSym.c_str()); + return DAG.getTargetExternalSymbol(SavedStr->c_str(), v); } SDValue NVPTXTargetLowering::getParamHelpSymbol(SelectionDAG &DAG, int idx) { diff --git a/lib/Target/NVPTX/NVPTXMCExpr.cpp b/lib/Target/NVPTX/NVPTXMCExpr.cpp new file mode 100644 index 0000000..ca24764 --- /dev/null +++ b/lib/Target/NVPTX/NVPTXMCExpr.cpp @@ -0,0 +1,46 @@ +//===-- NVPTXMCExpr.cpp - NVPTX specific MC expression classes ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "nvptx-mcexpr" +#include "NVPTXMCExpr.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCContext.h" +using namespace llvm; + +const NVPTXFloatMCExpr* +NVPTXFloatMCExpr::Create(VariantKind Kind, APFloat Flt, MCContext &Ctx) { + return new (Ctx) NVPTXFloatMCExpr(Kind, Flt); +} + +void NVPTXFloatMCExpr::PrintImpl(raw_ostream &OS) const { + bool Ignored; + unsigned NumHex; + APFloat APF = getAPFloat(); + + switch (Kind) { + default: llvm_unreachable("Invalid kind!"); + case VK_NVPTX_SINGLE_PREC_FLOAT: + OS << "0f"; + NumHex = 8; + APF.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven, &Ignored); + break; + case VK_NVPTX_DOUBLE_PREC_FLOAT: + OS << "0d"; + NumHex = 16; + APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &Ignored); + break; + } + + APInt API = APF.bitcastToAPInt(); + std::string HexStr(utohexstr(API.getZExtValue())); + if (HexStr.length() < NumHex) + OS << std::string(NumHex - HexStr.length(), '0'); + OS << utohexstr(API.getZExtValue()); +} diff --git a/lib/Target/NVPTX/NVPTXMCExpr.h b/lib/Target/NVPTX/NVPTXMCExpr.h new file mode 100644 index 0000000..0efb231 --- /dev/null +++ b/lib/Target/NVPTX/NVPTXMCExpr.h @@ -0,0 +1,83 @@ +//===-- NVPTXMCExpr.h - NVPTX specific MC expression classes ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Modeled after ARMMCExpr + +#ifndef NVPTXMCEXPR_H +#define NVPTXMCEXPR_H + +#include "llvm/ADT/APFloat.h" +#include "llvm/MC/MCExpr.h" + +namespace llvm { + +class NVPTXFloatMCExpr : public MCTargetExpr { +public: + enum VariantKind { + VK_NVPTX_None, + VK_NVPTX_SINGLE_PREC_FLOAT, // FP constant in single-precision + VK_NVPTX_DOUBLE_PREC_FLOAT // FP constant in double-precision + }; + +private: + const VariantKind Kind; + const APFloat Flt; + + explicit NVPTXFloatMCExpr(VariantKind _Kind, APFloat _Flt) + : Kind(_Kind), Flt(_Flt) {} + +public: + /// @name Construction + /// @{ + + static const NVPTXFloatMCExpr *Create(VariantKind Kind, APFloat Flt, + MCContext &Ctx); + + static const NVPTXFloatMCExpr *CreateConstantFPSingle(APFloat Flt, + MCContext &Ctx) { + return Create(VK_NVPTX_SINGLE_PREC_FLOAT, Flt, Ctx); + } + + static const NVPTXFloatMCExpr *CreateConstantFPDouble(APFloat Flt, + MCContext &Ctx) { + return Create(VK_NVPTX_DOUBLE_PREC_FLOAT, Flt, Ctx); + } + + /// @} + /// @name Accessors + /// @{ + + /// getOpcode - Get the kind of this expression. + VariantKind getKind() const { return Kind; } + + /// getSubExpr - Get the child of this expression. + APFloat getAPFloat() const { return Flt; } + +/// @} + + void PrintImpl(raw_ostream &OS) const; + bool EvaluateAsRelocatableImpl(MCValue &Res, + const MCAsmLayout *Layout) const { + return false; + } + void AddValueSymbols(MCAssembler *) const {}; + const MCSection *FindAssociatedSection() const { + return NULL; + } + + // There are no TLS NVPTXMCExprs at the moment. + void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {} + + static bool classof(const MCExpr *E) { + return E->getKind() == MCExpr::Target; + } +}; +} // end namespace llvm + +#endif |