From d8e4ed2686cfcc1857d1ea15d2797d6c92c09f6c Mon Sep 17 00:00:00 2001 From: Justin Holewinski Date: Wed, 28 Sep 2011 14:32:04 +0000 Subject: [PATCH] PTX: MC-ize the PTX back-end (patch 1 of N) Lay some groundwork for converting to MC-based asm printer. This is the first of probably many patches to bring the back-end back up-to-date with all of the recent MC changes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140697 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PTX/CMakeLists.txt | 3 + lib/Target/PTX/InstPrinter/CMakeLists.txt | 13 ++ lib/Target/PTX/InstPrinter/Makefile | 16 ++ lib/Target/PTX/InstPrinter/PTXInstPrinter.cpp | 149 ++++++++++++++++++ lib/Target/PTX/InstPrinter/PTXInstPrinter.h | 46 ++++++ lib/Target/PTX/MCTargetDesc/CMakeLists.txt | 1 + .../PTX/MCTargetDesc/PTXMCTargetDesc.cpp | 14 ++ lib/Target/PTX/Makefile | 2 +- lib/Target/PTX/PTX.h | 9 +- lib/Target/PTX/PTX.td | 11 ++ lib/Target/PTX/PTXAsmPrinter.cpp | 105 ++++++------ lib/Target/PTX/PTXAsmPrinter.h | 73 +++++++++ lib/Target/PTX/PTXISelDAGToDAG.cpp | 4 +- lib/Target/PTX/PTXISelLowering.cpp | 12 +- lib/Target/PTX/PTXInstrFormats.td | 4 +- lib/Target/PTX/PTXInstrInfo.cpp | 12 +- lib/Target/PTX/PTXMCAsmStreamer.cpp | 2 +- lib/Target/PTX/PTXMCInstLower.cpp | 33 ++++ lib/Target/PTX/PTXMachineFunctionInfo.h | 4 +- test/CodeGen/PTX/add.ll | 2 +- test/CodeGen/PTX/mov.ll | 2 +- test/CodeGen/PTX/mul.ll | 2 +- test/CodeGen/PTX/sub.ll | 2 +- 23 files changed, 453 insertions(+), 68 deletions(-) create mode 100644 lib/Target/PTX/InstPrinter/CMakeLists.txt create mode 100644 lib/Target/PTX/InstPrinter/Makefile create mode 100644 lib/Target/PTX/InstPrinter/PTXInstPrinter.cpp create mode 100644 lib/Target/PTX/InstPrinter/PTXInstPrinter.h create mode 100644 lib/Target/PTX/PTXAsmPrinter.h create mode 100644 lib/Target/PTX/PTXMCInstLower.cpp diff --git a/lib/Target/PTX/CMakeLists.txt b/lib/Target/PTX/CMakeLists.txt index f711af93a46..ca24e0d5087 100644 --- a/lib/Target/PTX/CMakeLists.txt +++ b/lib/Target/PTX/CMakeLists.txt @@ -14,6 +14,7 @@ add_llvm_target(PTXCodeGen PTXInstrInfo.cpp PTXFrameLowering.cpp PTXMCAsmStreamer.cpp + PTXMCInstLower.cpp PTXMFInfoExtract.cpp PTXParamManager.cpp PTXRegAlloc.cpp @@ -37,4 +38,6 @@ add_llvm_library_dependencies(LLVMPTXCodeGen ) add_subdirectory(TargetInfo) +add_subdirectory(InstPrinter) add_subdirectory(MCTargetDesc) + diff --git a/lib/Target/PTX/InstPrinter/CMakeLists.txt b/lib/Target/PTX/InstPrinter/CMakeLists.txt new file mode 100644 index 00000000000..029d06031dd --- /dev/null +++ b/lib/Target/PTX/InstPrinter/CMakeLists.txt @@ -0,0 +1,13 @@ +include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. ) + +add_llvm_library(LLVMPTXAsmPrinter + PTXInstPrinter.cpp + ) + +add_dependencies(LLVMPTXAsmPrinter PTXCommonTableGen) + +add_llvm_library_dependencies(LLVMPTXAsmPrinter + LLVMMC + LLVMSupport + ) + diff --git a/lib/Target/PTX/InstPrinter/Makefile b/lib/Target/PTX/InstPrinter/Makefile new file mode 100644 index 00000000000..0ccfe440789 --- /dev/null +++ b/lib/Target/PTX/InstPrinter/Makefile @@ -0,0 +1,16 @@ +##===- lib/Target/PTX/AsmPrinter/Makefile ------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +LEVEL = ../../../.. +LIBRARYNAME = LLVMPTXAsmPrinter + +# Hack: we need to include 'main' ptx target directory to grab private headers +CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. + +include $(LEVEL)/Makefile.common + diff --git a/lib/Target/PTX/InstPrinter/PTXInstPrinter.cpp b/lib/Target/PTX/InstPrinter/PTXInstPrinter.cpp new file mode 100644 index 00000000000..9c2b9a0449c --- /dev/null +++ b/lib/Target/PTX/InstPrinter/PTXInstPrinter.cpp @@ -0,0 +1,149 @@ +//===-- PTXInstPrinter.cpp - Convert PTX MCInst to assembly syntax --------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class prints a PTX MCInst to a .ptx file. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "asm-printer" +#include "PTXInstPrinter.h" +#include "PTXMachineFunctionInfo.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +#define GET_INSTRUCTION_NAME +#include "PTXGenAsmWriter.inc" + +PTXInstPrinter::PTXInstPrinter(const MCAsmInfo &MAI, + const MCSubtargetInfo &STI) : + MCInstPrinter(MAI) { + // Initialize the set of available features. + setAvailableFeatures(STI.getFeatureBits()); +} + +StringRef PTXInstPrinter::getOpcodeName(unsigned Opcode) const { + return getInstructionName(Opcode); +} + +void PTXInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { + OS << getRegisterName(RegNo); +} + +void PTXInstPrinter::printInst(const MCInst *MI, raw_ostream &O, + StringRef Annot) { + printPredicate(MI, O); + switch (MI->getOpcode()) { + default: + printInstruction(MI, O); + break; + case PTX::CALL: + printCall(MI, O); + } + O << ";"; + printAnnotation(O, Annot); +} + +void PTXInstPrinter::printPredicate(const MCInst *MI, raw_ostream &O) { + // The last two operands are the predicate operands + int RegIndex; + int OpIndex; + + if (MI->getOpcode() == PTX::CALL) { + RegIndex = 0; + OpIndex = 1; + } else { + RegIndex = MI->getNumOperands()-2; + OpIndex = MI->getNumOperands()-1; + } + + int PredOp = MI->getOperand(OpIndex).getImm(); + if (PredOp != PTX::PRED_NONE) { + if (PredOp == PTX::PRED_NEGATE) { + O << '!'; + } else { + O << '@'; + } + printOperand(MI, RegIndex, O); + } +} + +void PTXInstPrinter::printCall(const MCInst *MI, raw_ostream &O) { + O << "\tcall.uni\t"; + // The first two operands are the predicate slot + unsigned Index = 2; + unsigned NumRets = MI->getOperand(Index++).getImm(); + for (unsigned i = 0; i < NumRets; ++i) { + if (i == 0) { + O << "("; + } else { + O << ", "; + } + printOperand(MI, Index++, O); + } + + if (NumRets > 0) { + O << "), "; + } + + O << *(MI->getOperand(Index++).getExpr()) << ", ("; + + unsigned NumArgs = MI->getOperand(Index++).getImm(); + for (unsigned i = 0; i < NumArgs; ++i) { + printOperand(MI, Index++, O); + if (i < NumArgs-1) { + O << ", "; + } + } + + O << ")"; +} + +void PTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + const MCOperand &Op = MI->getOperand(OpNo); + if (Op.isImm()) { + O << Op.getImm(); + } else if (Op.isFPImm()) { + double Imm = Op.getFPImm(); + APFloat FPImm(Imm); + APInt FPIntImm = FPImm.bitcastToAPInt(); + O << "0D"; + // PTX requires us to output the full 64 bits, even if the number is zero + if (FPIntImm.getZExtValue() > 0) { + O << FPIntImm.toString(16, false); + } else { + O << "0000000000000000"; + } + } else { + assert(Op.isExpr() && "unknown operand kind in printOperand"); + const MCExpr *Expr = Op.getExpr(); + if (const MCSymbolRefExpr *SymRefExpr = dyn_cast(Expr)) { + const MCSymbol &Sym = SymRefExpr->getSymbol(); + O << Sym.getName(); + } else { + O << *Op.getExpr(); + } + } +} + +void PTXInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + printOperand(MI, OpNo, O); + if (MI->getOperand(OpNo+1).isImm() && MI->getOperand(OpNo+1).getImm() == 0) + return; // don't print "+0" + O << "+"; + printOperand(MI, OpNo+1, O); +} + + diff --git a/lib/Target/PTX/InstPrinter/PTXInstPrinter.h b/lib/Target/PTX/InstPrinter/PTXInstPrinter.h new file mode 100644 index 00000000000..73a7977a658 --- /dev/null +++ b/lib/Target/PTX/InstPrinter/PTXInstPrinter.h @@ -0,0 +1,46 @@ +//===-- PTXInstPrinter.h - Convert PTX MCInst to assembly syntax ----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class prints n PTX MCInst to a .ptx file. +// +//===----------------------------------------------------------------------===// + +#ifndef PTXINSTPRINTER_H +#define PTXINSTPRINTER_H + +#include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCSubtargetInfo.h" + +namespace llvm { + +class MCOperand; + +class PTXInstPrinter : public MCInstPrinter { +public: + PTXInstPrinter(const MCAsmInfo &MAI, const MCSubtargetInfo &STI); + + virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot); + virtual StringRef getOpcodeName(unsigned Opcode) const; + virtual void printRegName(raw_ostream &OS, unsigned RegNo) const; + + static const char *getInstructionName(unsigned Opcode); + + // Autogenerated by tblgen. + void printInstruction(const MCInst *MI, raw_ostream &O); + static const char *getRegisterName(unsigned RegNo); + + void printPredicate(const MCInst *MI, raw_ostream &O); + void printCall(const MCInst *MI, raw_ostream &O); + void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printMemOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); +}; +} + +#endif + diff --git a/lib/Target/PTX/MCTargetDesc/CMakeLists.txt b/lib/Target/PTX/MCTargetDesc/CMakeLists.txt index ddf08259031..811ef4bd1fc 100644 --- a/lib/Target/PTX/MCTargetDesc/CMakeLists.txt +++ b/lib/Target/PTX/MCTargetDesc/CMakeLists.txt @@ -6,6 +6,7 @@ add_llvm_library(LLVMPTXDesc add_llvm_library_dependencies(LLVMPTXDesc LLVMMC LLVMPTXInfo + LLVMPTXAsmPrinter LLVMSupport ) diff --git a/lib/Target/PTX/MCTargetDesc/PTXMCTargetDesc.cpp b/lib/Target/PTX/MCTargetDesc/PTXMCTargetDesc.cpp index ee7df18029c..9d6eba52c8e 100644 --- a/lib/Target/PTX/MCTargetDesc/PTXMCTargetDesc.cpp +++ b/lib/Target/PTX/MCTargetDesc/PTXMCTargetDesc.cpp @@ -13,6 +13,7 @@ #include "PTXMCTargetDesc.h" #include "PTXMCAsmInfo.h" +#include "InstPrinter/PTXInstPrinter.h" #include "llvm/MC/MCCodeGenInfo.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" @@ -57,6 +58,15 @@ static MCCodeGenInfo *createPTXMCCodeGenInfo(StringRef TT, Reloc::Model RM, return X; } +static MCInstPrinter *createPTXMCInstPrinter(const Target &T, + unsigned SyntaxVariant, + const MCAsmInfo &MAI, + const MCSubtargetInfo &STI) { + if (SyntaxVariant == 0) + return new PTXInstPrinter(MAI, STI); + return 0; +} + extern "C" void LLVMInitializePTXTargetMC() { // Register the MC asm info. RegisterMCAsmInfo X(ThePTX32Target); @@ -79,4 +89,8 @@ extern "C" void LLVMInitializePTXTargetMC() { createPTXMCSubtargetInfo); TargetRegistry::RegisterMCSubtargetInfo(ThePTX64Target, createPTXMCSubtargetInfo); + + // Register the MCInstPrinter. + TargetRegistry::RegisterMCInstPrinter(ThePTX32Target, createPTXMCInstPrinter); + TargetRegistry::RegisterMCInstPrinter(ThePTX64Target, createPTXMCInstPrinter); } diff --git a/lib/Target/PTX/Makefile b/lib/Target/PTX/Makefile index c9079caa513..fa09634965a 100644 --- a/lib/Target/PTX/Makefile +++ b/lib/Target/PTX/Makefile @@ -18,6 +18,6 @@ BUILT_SOURCES = PTXGenAsmWriter.inc \ PTXGenRegisterInfo.inc \ PTXGenSubtargetInfo.inc -DIRS = TargetInfo MCTargetDesc +DIRS = InstPrinter TargetInfo MCTargetDesc include $(LEVEL)/Makefile.common diff --git a/lib/Target/PTX/PTX.h b/lib/Target/PTX/PTX.h index ddd9e241260..cbcfa5144b1 100644 --- a/lib/Target/PTX/PTX.h +++ b/lib/Target/PTX/PTX.h @@ -19,6 +19,9 @@ #include "llvm/Target/TargetMachine.h" namespace llvm { + class MachineInstr; + class MCInst; + class PTXAsmPrinter; class PTXTargetMachine; class FunctionPass; @@ -33,7 +36,8 @@ namespace llvm { enum Predicate { PRED_NORMAL = 0, - PRED_NEGATE = 1 + PRED_NEGATE = 1, + PRED_NONE = 2 }; } // namespace PTX @@ -45,6 +49,9 @@ namespace llvm { FunctionPass *createPTXRegisterAllocator(); + void LowerPTXMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, + PTXAsmPrinter &AP); + } // namespace llvm; #endif // PTX_H diff --git a/lib/Target/PTX/PTX.td b/lib/Target/PTX/PTX.td index 7d0be8bfe54..693bb9c4834 100644 --- a/lib/Target/PTX/PTX.td +++ b/lib/Target/PTX/PTX.td @@ -121,10 +121,21 @@ include "PTXInstrInfo.td" def PTXInstrInfo : InstrInfo; +//===----------------------------------------------------------------------===// +// Assembly printer +//===----------------------------------------------------------------------===// +// PTX uses the MC printer for asm output, so make sure the TableGen +// AsmWriter bits get associated with the correct class. +def PTXAsmWriter : AsmWriter { + string AsmWriterClassName = "InstPrinter"; + bit isMCAsmWriter = 1; +} + //===----------------------------------------------------------------------===// // Target Declaration //===----------------------------------------------------------------------===// def PTX : Target { let InstructionSet = PTXInstrInfo; + let AssemblyWriters = [PTXAsmWriter]; } diff --git a/lib/Target/PTX/PTXAsmPrinter.cpp b/lib/Target/PTX/PTXAsmPrinter.cpp index c1a002c2441..719567b99b3 100644 --- a/lib/Target/PTX/PTXAsmPrinter.cpp +++ b/lib/Target/PTX/PTXAsmPrinter.cpp @@ -15,6 +15,7 @@ #define DEBUG_TYPE "ptx-asm-printer" #include "PTX.h" +#include "PTXAsmPrinter.h" #include "PTXMachineFunctionInfo.h" #include "PTXParamManager.h" #include "PTXRegisterInfo.h" @@ -30,6 +31,8 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Target/Mangler.h" @@ -44,49 +47,6 @@ using namespace llvm; -namespace { -class PTXAsmPrinter : public AsmPrinter { -public: - explicit PTXAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) - : AsmPrinter(TM, Streamer) {} - - const char *getPassName() const { return "PTX Assembly Printer"; } - - bool doFinalization(Module &M); - - virtual void EmitStartOfAsmFile(Module &M); - - virtual bool runOnMachineFunction(MachineFunction &MF); - - virtual void EmitFunctionBodyStart(); - virtual void EmitFunctionBodyEnd() { OutStreamer.EmitRawText(Twine("}")); } - - virtual void EmitInstruction(const MachineInstr *MI); - - void printOperand(const MachineInstr *MI, int opNum, raw_ostream &OS); - void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &OS, - const char *Modifier = 0); - void printReturnOperand(const MachineInstr *MI, int opNum, raw_ostream &OS, - const char *Modifier = 0); - void printPredicateOperand(const MachineInstr *MI, raw_ostream &O); - - void printCall(const MachineInstr *MI, raw_ostream &O); - - unsigned GetOrCreateSourceID(StringRef FileName, - StringRef DirName); - - // autogen'd. - void printInstruction(const MachineInstr *MI, raw_ostream &OS); - static const char *getRegisterName(unsigned RegNo); - -private: - void EmitVariableDeclaration(const GlobalVariable *gv); - void EmitFunctionDeclaration(); - - StringMap SourceIdMap; -}; // class PTXAsmPrinter -} // namespace - static const char PARAM_PREFIX[] = "__param_"; static const char RETURN_PREFIX[] = "__ret_"; @@ -320,7 +280,12 @@ void PTXAsmPrinter::EmitFunctionBodyStart() { //} } +void PTXAsmPrinter::EmitFunctionBodyEnd() { + OutStreamer.EmitRawText(Twine("}")); +} + void PTXAsmPrinter::EmitInstruction(const MachineInstr *MI) { +#if 0 std::string str; str.reserve(64); @@ -388,6 +353,11 @@ void PTXAsmPrinter::EmitInstruction(const MachineInstr *MI) { StringRef strref = StringRef(str); OutStreamer.EmitRawText(strref); +#endif + + MCInst TmpInst; + LowerPTXMachineInstrToMCInst(MI, TmpInst, *this); + OutStreamer.EmitInstruction(TmpInst); } void PTXAsmPrinter::printOperand(const MachineInstr *MI, int opNum, @@ -737,10 +707,57 @@ unsigned PTXAsmPrinter::GetOrCreateSourceID(StringRef FileName, return SrcId; } -#include "PTXGenAsmWriter.inc" +MCOperand PTXAsmPrinter::GetSymbolRef(const MachineOperand &MO, + const MCSymbol *Symbol) { + const MCExpr *Expr; + Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, OutContext); + return MCOperand::CreateExpr(Expr); +} + +bool PTXAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) { + const PTXMachineFunctionInfo *MFI = MF->getInfo(); + const MCExpr *Expr; + const char *RegSymbolName; + switch (MO.getType()) { + default: + llvm_unreachable("Unknown operand type"); + case MachineOperand::MO_Register: + // We create register operands as symbols, since the PTXInstPrinter class + // has no way to map virtual registers back to a name without some ugly + // hacks. + // FIXME: Figure out a better way to handle virtual register naming. + RegSymbolName = MFI->getRegisterName(MO.getReg()); + Expr = MCSymbolRefExpr::Create(RegSymbolName, MCSymbolRefExpr::VK_None, + OutContext); + MCOp = MCOperand::CreateExpr(Expr); + 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_GlobalAddress: + MCOp = GetSymbolRef(MO, Mang->getSymbol(MO.getGlobal())); + break; + case MachineOperand::MO_ExternalSymbol: + MCOp = GetSymbolRef(MO, GetExternalSymbolSymbol(MO.getSymbolName())); + break; + case MachineOperand::MO_FPImmediate: + APFloat Val = MO.getFPImm()->getValueAPF(); + bool ignored; + Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored); + MCOp = MCOperand::CreateFPImm(Val.convertToDouble()); + break; + } + + return true; +} // Force static initialization. extern "C" void LLVMInitializePTXAsmPrinter() { RegisterAsmPrinter X(ThePTX32Target); RegisterAsmPrinter Y(ThePTX64Target); } + diff --git a/lib/Target/PTX/PTXAsmPrinter.h b/lib/Target/PTX/PTXAsmPrinter.h new file mode 100644 index 00000000000..85de57d90ac --- /dev/null +++ b/lib/Target/PTX/PTXAsmPrinter.h @@ -0,0 +1,73 @@ +//===-- PTXAsmPrinter.h - Print machine code to a PTX file ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// PTX Assembly printer class. +// +//===----------------------------------------------------------------------===// + +#ifndef PTXASMPRINTER_H +#define PTXASMPRINTER_H + +#include "PTX.h" +#include "PTXTargetMachine.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/Support/Compiler.h" + +namespace llvm { + +class MCOperand; + +class LLVM_LIBRARY_VISIBILITY PTXAsmPrinter : public AsmPrinter { +public: + explicit PTXAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) + : AsmPrinter(TM, Streamer) {} + + const char *getPassName() const { return "PTX Assembly Printer"; } + + bool doFinalization(Module &M); + + virtual void EmitStartOfAsmFile(Module &M); + + virtual bool runOnMachineFunction(MachineFunction &MF); + + virtual void EmitFunctionBodyStart(); + virtual void EmitFunctionBodyEnd(); + + virtual void EmitInstruction(const MachineInstr *MI); + + void printOperand(const MachineInstr *MI, int opNum, raw_ostream &OS); + void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &OS, + const char *Modifier = 0); + void printReturnOperand(const MachineInstr *MI, int opNum, raw_ostream &OS, + const char *Modifier = 0); + void printPredicateOperand(const MachineInstr *MI, raw_ostream &O); + + void printCall(const MachineInstr *MI, raw_ostream &O); + + unsigned GetOrCreateSourceID(StringRef FileName, + StringRef DirName); + + MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol); + bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp); + + // autogen'd. + void printInstruction(const MachineInstr *MI, raw_ostream &OS); + static const char *getRegisterName(unsigned RegNo); + +private: + void EmitVariableDeclaration(const GlobalVariable *gv); + void EmitFunctionDeclaration(); + + StringMap SourceIdMap; +}; // class PTXAsmPrinter +} // namespace llvm + +#endif + diff --git a/lib/Target/PTX/PTXISelDAGToDAG.cpp b/lib/Target/PTX/PTXISelDAGToDAG.cpp index c722e8acb08..589e20b3cc9 100644 --- a/lib/Target/PTX/PTXISelDAGToDAG.cpp +++ b/lib/Target/PTX/PTXISelDAGToDAG.cpp @@ -129,7 +129,7 @@ SDNode *PTXDAGToDAGISel::SelectREADPARAM(SDNode *Node) { OpCode = PTX::READPARAMF64; SDValue Pred = CurDAG->getRegister(PTX::NoRegister, MVT::i1); - SDValue PredOp = CurDAG->getTargetConstant(PTX::PRED_NORMAL, MVT::i32); + SDValue PredOp = CurDAG->getTargetConstant(PTX::PRED_NONE, MVT::i32); DebugLoc dl = Node->getDebugLoc(); SDValue Ops[] = { Index, Pred, PredOp, Chain }; @@ -167,7 +167,7 @@ SDNode *PTXDAGToDAGISel::SelectWRITEPARAM(SDNode *Node) { llvm_unreachable("Invalid type in SelectWRITEPARAM"); SDValue Pred = CurDAG->getRegister(PTX::NoRegister, MVT::i1); - SDValue PredOp = CurDAG->getTargetConstant(PTX::PRED_NORMAL, MVT::i32); + SDValue PredOp = CurDAG->getTargetConstant(PTX::PRED_NONE, MVT::i32); DebugLoc dl = Node->getDebugLoc(); SDValue Ops[] = { Value, Pred, PredOp, Chain }; diff --git a/lib/Target/PTX/PTXISelLowering.cpp b/lib/Target/PTX/PTXISelLowering.cpp index c439d4c1731..ce8cd7cdbe6 100644 --- a/lib/Target/PTX/PTXISelLowering.cpp +++ b/lib/Target/PTX/PTXISelLowering.cpp @@ -393,8 +393,8 @@ PTXTargetLowering::LowerCall(SDValue Chain, SDValue Callee, "Calls are not handled for the target device"); std::vector Ops; - // The layout of the ops will be [Chain, Ins, Callee, Outs] - Ops.resize(Outs.size() + Ins.size() + 2); + // The layout of the ops will be [Chain, #Ins, Ins, Callee, #Outs, Outs] + Ops.resize(Outs.size() + Ins.size() + 4); Ops[0] = Chain; @@ -403,11 +403,12 @@ PTXTargetLowering::LowerCall(SDValue Chain, SDValue Callee, assert(cast(GV)->getCallingConv() == CallingConv::PTX_Device && "PTX function calls must be to PTX device functions"); Callee = DAG.getTargetGlobalAddress(GV, dl, getPointerTy()); - Ops[Ins.size()+1] = Callee; + Ops[Ins.size()+2] = Callee; // Generate STORE_PARAM nodes for each function argument. In PTX, function // arguments are explicitly stored into .param variables and passed as // arguments. There is no register/stack-based calling convention in PTX. + Ops[Ins.size()+3] = DAG.getTargetConstant(OutVals.size(), MVT::i32); for (unsigned i = 0; i != OutVals.size(); ++i) { unsigned Size = OutVals[i].getValueType().getSizeInBits(); unsigned Param = PM.addLocalParam(Size); @@ -416,19 +417,20 @@ PTXTargetLowering::LowerCall(SDValue Chain, SDValue Callee, MVT::Other); Chain = DAG.getNode(PTXISD::STORE_PARAM, dl, MVT::Other, Chain, ParamValue, OutVals[i]); - Ops[i+Ins.size()+2] = ParamValue; + Ops[i+Ins.size()+4] = ParamValue; } std::vector InParams; // Generate list of .param variables to hold the return value(s). + Ops[1] = DAG.getTargetConstant(Ins.size(), MVT::i32); for (unsigned i = 0; i < Ins.size(); ++i) { unsigned Size = Ins[i].VT.getStoreSizeInBits(); unsigned Param = PM.addLocalParam(Size); const std::string &ParamName = PM.getParamName(Param); SDValue ParamValue = DAG.getTargetExternalSymbol(ParamName.c_str(), MVT::Other); - Ops[i+1] = ParamValue; + Ops[i+2] = ParamValue; InParams.push_back(ParamValue); } diff --git a/lib/Target/PTX/PTXInstrFormats.td b/lib/Target/PTX/PTXInstrFormats.td index 8cee351ee0d..6632bbfbc5d 100644 --- a/lib/Target/PTX/PTXInstrFormats.td +++ b/lib/Target/PTX/PTXInstrFormats.td @@ -7,10 +7,10 @@ // //===----------------------------------------------------------------------===// -// PTX Predicate operand, default to (0, 0) = (zero-reg, always). +// PTX Predicate operand, default to (0, 0) = (zero-reg, none). // Leave PrintMethod empty; predicate printing is defined elsewhere. def pred : PredicateOperand; + (ops (i1 zero_reg), (i32 2))>; let Namespace = "PTX" in { class InstPTX pattern> diff --git a/lib/Target/PTX/PTXInstrInfo.cpp b/lib/Target/PTX/PTXInstrInfo.cpp index ece74e21592..8ec6c56a0ef 100644 --- a/lib/Target/PTX/PTXInstrInfo.cpp +++ b/lib/Target/PTX/PTXInstrInfo.cpp @@ -167,7 +167,7 @@ DefinesPredicate(MachineInstr *MI, return false; Pred.push_back(MO); - Pred.push_back(MachineOperand::CreateImm(PTX::PRED_NORMAL)); + Pred.push_back(MachineOperand::CreateImm(PTX::PRED_NONE)); return true; } @@ -283,7 +283,7 @@ InsertBranch(MachineBasicBlock &MBB, BuildMI(&MBB, DL, get(PTX::BRAdp)) .addMBB(TBB).addReg(Cond[0].getReg()).addImm(Cond[1].getImm()); BuildMI(&MBB, DL, get(PTX::BRAd)) - .addMBB(FBB).addReg(PTX::NoRegister).addImm(PTX::PRED_NORMAL); + .addMBB(FBB).addReg(PTX::NoRegister).addImm(PTX::PRED_NONE); return 2; } else if (Cond.size()) { BuildMI(&MBB, DL, get(PTX::BRAdp)) @@ -291,7 +291,7 @@ InsertBranch(MachineBasicBlock &MBB, return 1; } else { BuildMI(&MBB, DL, get(PTX::BRAd)) - .addMBB(TBB).addReg(PTX::NoRegister).addImm(PTX::PRED_NORMAL); + .addMBB(TBB).addReg(PTX::NoRegister).addImm(PTX::PRED_NONE); return 1; } } @@ -319,7 +319,7 @@ MachineSDNode *PTXInstrInfo:: GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode, DebugLoc dl, EVT VT, SDValue Op1) { SDValue predReg = DAG->getRegister(PTX::NoRegister, MVT::i1); - SDValue predOp = DAG->getTargetConstant(PTX::PRED_NORMAL, MVT::i32); + SDValue predOp = DAG->getTargetConstant(PTX::PRED_NONE, MVT::i32); SDValue ops[] = { Op1, predReg, predOp }; return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops)); } @@ -328,7 +328,7 @@ MachineSDNode *PTXInstrInfo:: GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode, DebugLoc dl, EVT VT, SDValue Op1, SDValue Op2) { SDValue predReg = DAG->getRegister(PTX::NoRegister, MVT::i1); - SDValue predOp = DAG->getTargetConstant(PTX::PRED_NORMAL, MVT::i32); + SDValue predOp = DAG->getTargetConstant(PTX::PRED_NONE, MVT::i32); SDValue ops[] = { Op1, Op2, predReg, predOp }; return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops)); } @@ -336,7 +336,7 @@ GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode, void PTXInstrInfo::AddDefaultPredicate(MachineInstr *MI) { if (MI->findFirstPredOperandIdx() == -1) { MI->addOperand(MachineOperand::CreateReg(PTX::NoRegister, /*IsDef=*/false)); - MI->addOperand(MachineOperand::CreateImm(PTX::PRED_NORMAL)); + MI->addOperand(MachineOperand::CreateImm(PTX::PRED_NONE)); } } diff --git a/lib/Target/PTX/PTXMCAsmStreamer.cpp b/lib/Target/PTX/PTXMCAsmStreamer.cpp index 4925cbfcb91..2e8a12d378c 100644 --- a/lib/Target/PTX/PTXMCAsmStreamer.cpp +++ b/lib/Target/PTX/PTXMCAsmStreamer.cpp @@ -499,7 +499,7 @@ bool PTXMCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, void PTXMCAsmStreamer::AddEncodingComment(const MCInst &Inst) {} void PTXMCAsmStreamer::EmitInstruction(const MCInst &Inst) { - assert(getCurrentSection() && "Cannot emit contents before setting section!"); +//assert(getCurrentSection() && "Cannot emit contents before setting section!"); // Show the encoding in a comment if we have a code emitter. if (Emitter) diff --git a/lib/Target/PTX/PTXMCInstLower.cpp b/lib/Target/PTX/PTXMCInstLower.cpp new file mode 100644 index 00000000000..cc820803c9c --- /dev/null +++ b/lib/Target/PTX/PTXMCInstLower.cpp @@ -0,0 +1,33 @@ +//===-- PTXMCInstLower.cpp - Convert PTX MachineInstr to an MCInst --------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains code to lower PTX MachineInstrs to their corresponding +// MCInst records. +// +//===----------------------------------------------------------------------===// + +#include "PTX.h" +#include "PTXAsmPrinter.h" +#include "llvm/Constants.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/Target/Mangler.h" + +void llvm::LowerPTXMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, + PTXAsmPrinter &AP) { + OutMI.setOpcode(MI->getOpcode()); + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + MCOperand MCOp; + if (AP.lowerOperand(MO, MCOp)) + OutMI.addOperand(MCOp); + } +} + diff --git a/lib/Target/PTX/PTXMachineFunctionInfo.h b/lib/Target/PTX/PTXMachineFunctionInfo.h index f40d8ca5011..3b985f7dd6b 100644 --- a/lib/Target/PTX/PTXMachineFunctionInfo.h +++ b/lib/Target/PTX/PTXMachineFunctionInfo.h @@ -128,9 +128,9 @@ public: /// getRegisterName - Returns the name of the specified virtual register. This /// name is used during PTX emission. - std::string getRegisterName(unsigned Reg) const { + const char *getRegisterName(unsigned Reg) const { if (RegNames.count(Reg)) - return RegNames.lookup(Reg); + return RegNames.find(Reg)->second.c_str(); else if (Reg == PTX::NoRegister) return "%noreg"; else diff --git a/test/CodeGen/PTX/add.ll b/test/CodeGen/PTX/add.ll index e20bcff9dd6..8b10d11cba7 100644 --- a/test/CodeGen/PTX/add.ll +++ b/test/CodeGen/PTX/add.ll @@ -57,7 +57,7 @@ define ptx_device i64 @t2_u64(i64 %x) { } define ptx_device float @t2_f32(float %x) { -; CHECK: add.rn.f32 %ret{{[0-9]+}}, %f{{[0-9]+}}, 0F3F800000; +; CHECK: add.rn.f32 %ret{{[0-9]+}}, %f{{[0-9]+}}, 0D3FF0000000000000; ; CHECK: ret; %z = fadd float %x, 1.0 ret float %z diff --git a/test/CodeGen/PTX/mov.ll b/test/CodeGen/PTX/mov.ll index 176f8b12f15..75555a7c5e9 100644 --- a/test/CodeGen/PTX/mov.ll +++ b/test/CodeGen/PTX/mov.ll @@ -19,7 +19,7 @@ define ptx_device i64 @t1_u64() { } define ptx_device float @t1_f32() { -; CHECK: mov.f32 %ret{{[0-9]+}}, 0F00000000; +; CHECK: mov.f32 %ret{{[0-9]+}}, 0D0000000000000000; ; CHECK: ret; ret float 0.0 } diff --git a/test/CodeGen/PTX/mul.ll b/test/CodeGen/PTX/mul.ll index c05b61a62d3..91949db73c3 100644 --- a/test/CodeGen/PTX/mul.ll +++ b/test/CodeGen/PTX/mul.ll @@ -25,7 +25,7 @@ define ptx_device double @t1_f64(double %x, double %y) { } define ptx_device float @t2_f32(float %x) { -; CHECK: mul.rn.f32 %ret{{[0-9]+}}, %f{{[0-9]+}}, 0F40A00000; +; CHECK: mul.rn.f32 %ret{{[0-9]+}}, %f{{[0-9]+}}, 0D4014000000000000; ; CHECK: ret; %z = fmul float %x, 5.0 ret float %z diff --git a/test/CodeGen/PTX/sub.ll b/test/CodeGen/PTX/sub.ll index f3e2770306f..7ac886ad645 100644 --- a/test/CodeGen/PTX/sub.ll +++ b/test/CodeGen/PTX/sub.ll @@ -57,7 +57,7 @@ define ptx_device i64 @t2_u64(i64 %x) { } define ptx_device float @t2_f32(float %x) { -; CHECK: add.rn.f32 %ret{{[0-9]+}}, %f{{[0-9]+}}, 0FBF800000; +; CHECK: add.rn.f32 %ret{{[0-9]+}}, %f{{[0-9]+}}, 0DBFF0000000000000; ; CHECK: ret; %z = fsub float %x, 1.0 ret float %z