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 | a2a63d28df2a8c53aa3d6bb9357caadf5c0ae814 (patch) | |
| tree | fd230a55c099a8dcc4f8ffe4ab439523ba5a3623 /llvm | |
| parent | 8c6cd93123cfaa1213f88506f0bee13c0b0029bb (diff) | |
| download | bcm5719-llvm-a2a63d28df2a8c53aa3d6bb9357caadf5c0ae814.tar.gz bcm5719-llvm-a2a63d28df2a8c53aa3d6bb9357caadf5c0ae814.zip  | |
[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.
llvm-svn: 187798
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/NVPTX/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | llvm/lib/Target/NVPTX/InstPrinter/NVPTXInstPrinter.cpp | 275 | ||||
| -rw-r--r-- | llvm/lib/Target/NVPTX/InstPrinter/NVPTXInstPrinter.h | 52 | ||||
| -rw-r--r-- | llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp | 17 | ||||
| -rw-r--r-- | llvm/lib/Target/NVPTX/NVPTX.td | 6 | ||||
| -rw-r--r-- | llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp | 402 | ||||
| -rw-r--r-- | llvm/lib/Target/NVPTX/NVPTXAsmPrinter.h | 18 | ||||
| -rw-r--r-- | llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp | 10 | ||||
| -rw-r--r-- | llvm/lib/Target/NVPTX/NVPTXMCExpr.cpp | 46 | ||||
| -rw-r--r-- | llvm/lib/Target/NVPTX/NVPTXMCExpr.h | 83 | ||||
| -rw-r--r-- | llvm/test/CodeGen/NVPTX/fp-literals.ll | 18 | 
11 files changed, 611 insertions, 317 deletions
diff --git a/llvm/lib/Target/NVPTX/CMakeLists.txt b/llvm/lib/Target/NVPTX/CMakeLists.txt index be8d323c384..4f1324c6d5a 100644 --- a/llvm/lib/Target/NVPTX/CMakeLists.txt +++ b/llvm/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/llvm/lib/Target/NVPTX/InstPrinter/NVPTXInstPrinter.cpp b/llvm/lib/Target/NVPTX/InstPrinter/NVPTXInstPrinter.cpp index 10051c76805..1cb8a9a26e4 100644 --- a/llvm/lib/Target/NVPTX/InstPrinter/NVPTXInstPrinter.cpp +++ b/llvm/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/llvm/lib/Target/NVPTX/InstPrinter/NVPTXInstPrinter.h b/llvm/lib/Target/NVPTX/InstPrinter/NVPTXInstPrinter.h new file mode 100644 index 00000000000..e0f44da643b --- /dev/null +++ b/llvm/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/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp b/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp index ccd29705df7..871bac94f84 100644 --- a/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXMCTargetDesc.cpp +++ b/llvm/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/llvm/lib/Target/NVPTX/NVPTX.td b/llvm/lib/Target/NVPTX/NVPTX.td index d78b4e81a3e..6183a755c32 100644 --- a/llvm/lib/Target/NVPTX/NVPTX.td +++ b/llvm/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/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp index 93ba8d5ade6..b417d644b63 100644 --- a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp +++ b/llvm/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/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.h b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.h index c7b7fb0ae0d..27bfa546373 100644 --- a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.h +++ b/llvm/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/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp b/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp index c89c2fc9e60..828242db888 100644 --- a/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp +++ b/llvm/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/llvm/lib/Target/NVPTX/NVPTXMCExpr.cpp b/llvm/lib/Target/NVPTX/NVPTXMCExpr.cpp new file mode 100644 index 00000000000..ca247642048 --- /dev/null +++ b/llvm/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/llvm/lib/Target/NVPTX/NVPTXMCExpr.h b/llvm/lib/Target/NVPTX/NVPTXMCExpr.h new file mode 100644 index 00000000000..0efb231d7d2 --- /dev/null +++ b/llvm/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 diff --git a/llvm/test/CodeGen/NVPTX/fp-literals.ll b/llvm/test/CodeGen/NVPTX/fp-literals.ll new file mode 100644 index 00000000000..0cc2413e009 --- /dev/null +++ b/llvm/test/CodeGen/NVPTX/fp-literals.ll @@ -0,0 +1,18 @@ +; RUN: llc < %s -march=nvptx -mcpu=sm_20 | FileCheck %s + +; Make sure we can properly differentiate between single-precision and +; double-precision FP literals. + +; CHECK: myaddf +; CHECK: add.f32 %f{{[0-9]+}}, %f{{[0-9]+}}, 0f3F800000 +define float @myaddf(float %a) { +  %ret = fadd float %a, 1.0 +  ret float %ret +} + +; CHECK: myaddd +; CHECK: add.f64 %fl{{[0-9]+}}, %fl{{[0-9]+}}, 0d3FF0000000000000 +define double @myaddd(double %a) { +  %ret = fadd double %a, 1.0 +  ret double %ret +}  | 

