ptx: add ld instruction
authorChe-Liang Chiou <clchiou@gmail.com>
Tue, 30 Nov 2010 07:34:44 +0000 (07:34 +0000)
committerChe-Liang Chiou <clchiou@gmail.com>
Tue, 30 Nov 2010 07:34:44 +0000 (07:34 +0000)
support register and register-immediate addressing mode

todo: immediate and register-register addressing mode

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120407 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PTX/PTXAsmPrinter.cpp
lib/Target/PTX/PTXISelDAGToDAG.cpp
lib/Target/PTX/PTXInstrInfo.td

index 175b3c4750506a53fc9a676209cae622206b111d..03f177b2fa8aab23348041af51dba0bdfc6dc1f5 100644 (file)
@@ -49,6 +49,8 @@ public:
   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);
 
   // autogen'd.
   void printInstruction(const MachineInstr *MI, raw_ostream &OS);
@@ -61,7 +63,7 @@ private:
 
 static const char PARAM_PREFIX[] = "__param_";
 
-static const char *getRegisterTypeName(unsigned RegNo){
+static const char *getRegisterTypeName(unsigned RegNo) {
 #define TEST_REGCLS(cls, clsstr) \
   if (PTX::cls ## RegisterClass->contains(RegNo)) return # clsstr;
   TEST_REGCLS(RRegs32, s32);
@@ -72,8 +74,7 @@ static const char *getRegisterTypeName(unsigned RegNo){
   return NULL;
 }
 
-static const char *getInstructionTypeName(const MachineInstr *MI)
-{
+static const char *getInstructionTypeName(const MachineInstr *MI) {
   for (int i = 0, e = MI->getNumOperands(); i != e; ++i) {
     const MachineOperand &MO = MI->getOperand(i);
     if (MO.getType() == MachineOperand::MO_Register)
@@ -119,13 +120,13 @@ void PTXAsmPrinter::EmitInstruction(const MachineInstr *MI) {
   // Replace "%type" if found
   StringRef strref = OS.str();
   size_t pos;
-  if ((pos = strref.find("%type")) == StringRef::npos) {
-    OutStreamer.EmitRawText(strref);
-    return;
+  if ((pos = strref.find("%type")) != StringRef::npos) {
+    std::string str = strref;
+    str.replace(pos, /*strlen("%type")==*/5, getInstructionTypeName(MI));
+    strref = StringRef(str);
   }
-  std::string str = strref;
-  str.replace(pos, /*strlen("%type")==*/5, getInstructionTypeName(MI));
-  OutStreamer.EmitRawText(StringRef(str));
+
+  OutStreamer.EmitRawText(strref);
 }
 
 void PTXAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
@@ -145,6 +146,17 @@ void PTXAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
   }
 }
 
+void PTXAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum,
+                                    raw_ostream &OS, const char *Modifier) {
+  printOperand(MI, opNum, OS);
+
+  if (MI->getOperand(opNum+1).isImm() && MI->getOperand(opNum+1).getImm() == 0)
+    return; // don't print "+0"
+
+  OS << "+";
+  printOperand(MI, opNum+1, OS);
+}
+
 void PTXAsmPrinter::EmitFunctionDeclaration() {
   // The function label could have already been emitted if two symbols end up
   // conflicting due to asm renaming.  Detect this and emit an error.
index da9136511dbf175bef53b242988cd3711956e30d..1107236332d14cfff34ce7c3dd1fffd9a60d9f38 100644 (file)
@@ -14,6 +14,7 @@
 #include "PTX.h"
 #include "PTXTargetMachine.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/DerivedTypes.h"
 
 using namespace llvm;
 
@@ -30,9 +31,16 @@ class PTXDAGToDAGISel : public SelectionDAGISel {
 
     SDNode *Select(SDNode *Node);
 
+    // Complex Pattern Selectors.
+    bool SelectADDRri(SDValue &Addr, SDValue &Base, SDValue &Offset);
+    bool SelectADDRii(SDValue &Addr, SDValue &Base, SDValue &Offset);
+
     // Include the pieces auto'gened from the target description
 #include "PTXGenDAGISel.inc"
 
+  private:
+    bool isImm (const SDValue &operand);
+    bool SelectImm (const SDValue &operand, SDValue &imm);
 }; // class PTXDAGToDAGISel
 } // namespace
 
@@ -51,3 +59,54 @@ SDNode *PTXDAGToDAGISel::Select(SDNode *Node) {
   // SelectCode() is auto'gened
   return SelectCode(Node);
 }
+
+// Match memory operand of the form [reg+reg] and [reg+imm]
+bool PTXDAGToDAGISel::SelectADDRri(SDValue &Addr, SDValue &Base,
+                                   SDValue &Offset) {
+  if (Addr.getNumOperands() >= 2 &&
+      isImm(Addr.getOperand(0)) && isImm(Addr.getOperand(1)))
+    return false; // let SelectADDRii handle the [imm+imm] case
+
+  // try [reg+imm] and [imm+reg]
+  if (Addr.getOpcode() == ISD::ADD)
+    for (int i = 0; i < 2; i ++)
+      if (SelectImm(Addr.getOperand(1-i), Offset)) {
+        Base = Addr.getOperand(i);
+        return true;
+      }
+
+  // okay, it's [reg+reg]
+  Base = Addr;
+  Offset = CurDAG->getTargetConstant(0, MVT::i32);
+  return true;
+}
+
+// Match memory operand of the form [imm+imm] and [imm]
+bool PTXDAGToDAGISel::SelectADDRii(SDValue &Addr, SDValue &Base,
+                                   SDValue &Offset) {
+  if (Addr.getOpcode() == ISD::ADD) {
+    return SelectImm(Addr.getOperand(0), Base) &&
+           SelectImm(Addr.getOperand(1), Offset);
+  }
+
+  if (SelectImm(Addr, Base)) {
+    Offset = CurDAG->getTargetConstant(0, MVT::i32);
+    return true;
+  }
+
+  return false;
+}
+
+bool PTXDAGToDAGISel::isImm(const SDValue &operand) {
+  return ConstantSDNode::classof(operand.getNode());
+}
+
+bool PTXDAGToDAGISel::SelectImm(const SDValue &operand, SDValue &imm) {
+  SDNode *node = operand.getNode();
+  if (!ConstantSDNode::classof(node))
+    return false;
+
+  ConstantSDNode *CN = cast<ConstantSDNode>(node);
+  imm = CurDAG->getTargetConstant(*CN->getConstantIntValue(), MVT::i32);
+  return true;
+}
index 71d9016cd7626165dab035b08c8839d059dd81a4..01e0f2a2b412169cd0bcace41cd6a8e314af8713 100644 (file)
 
 include "PTXInstrFormats.td"
 
+//===----------------------------------------------------------------------===//
+// Instruction Pattern Stuff
+//===----------------------------------------------------------------------===//
+
+def load_global : PatFrag<(ops node:$ptr), (load node:$ptr), [{
+  if (const Value *Src = cast<LoadSDNode>(N)->getSrcValue())
+    if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
+      return PT->getAddressSpace() <= 255;
+  return false;
+}]>;
+
+// Addressing modes.
+def ADDRri : ComplexPattern<i32, 2, "SelectADDRri", [], []>;
+def ADDRii : ComplexPattern<i32, 2, "SelectADDRii", [], []>;
+
+// Address operands
+def MEMri : Operand<i32> {
+  let PrintMethod = "printMemOperand";
+  let MIOperandInfo = (ops RRegs32, i32imm);
+}
+def MEMii : Operand<i32> {
+  let PrintMethod = "printMemOperand";
+  let MIOperandInfo = (ops i32imm, i32imm);
+}
+
 //===----------------------------------------------------------------------===//
 // PTX Specific Node Definitions
 //===----------------------------------------------------------------------===//
@@ -41,6 +66,17 @@ multiclass INT3<string opcstr, SDNode opnode> {
                    [(set RRegs32:$d, (opnode RRegs32:$a, imm:$b))]>;
 }
 
+multiclass PTX_LD<string opstr, RegisterClass RC, PatFrag pat_load> {
+  def ri : InstPTX<(outs RC:$d),
+                   (ins MEMri:$a),
+                   !strconcat(opstr, ".%type\t$d, [$a]"),
+                   [(set RC:$d, (pat_load ADDRri:$a))]>;
+  def ii : InstPTX<(outs RC:$d),
+                   (ins MEMii:$a),
+                   !strconcat(opstr, ".%type\t$d, [$a]"),
+                   [(set RC:$d, (pat_load ADDRii:$a))]>;
+}
+
 //===----------------------------------------------------------------------===//
 // Instructions
 //===----------------------------------------------------------------------===//
@@ -69,6 +105,8 @@ let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
               [(set RRegs32:$d, imm:$a)]>;
 }
 
+defm LDg : PTX_LD<"ld.global", RRegs32, load_global>;
+
 ///===- Control Flow Instructions -----------------------------------------===//
 
 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {