OSDN Git Service

Add simple arithmetics and %type directive for PTX
authorChe-Liang Chiou <clchiou@gmail.com>
Wed, 17 Nov 2010 08:08:49 +0000 (08:08 +0000)
committerChe-Liang Chiou <clchiou@gmail.com>
Wed, 17 Nov 2010 08:08:49 +0000 (08:08 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119485 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PTX/PTXAsmPrinter.cpp
lib/Target/PTX/PTXInstrInfo.td
test/CodeGen/PTX/add.ll [new file with mode: 0644]
test/CodeGen/PTX/exit.ll
test/CodeGen/PTX/mov.ll
test/CodeGen/PTX/ret.ll
test/CodeGen/PTX/sub.ll [new file with mode: 0644]

index b861807..175b3c4 100644 (file)
@@ -64,14 +64,26 @@ static const char PARAM_PREFIX[] = "__param_";
 static const char *getRegisterTypeName(unsigned RegNo){
 #define TEST_REGCLS(cls, clsstr) \
   if (PTX::cls ## RegisterClass->contains(RegNo)) return # clsstr;
-  TEST_REGCLS(RRegs32, .s32);
-  TEST_REGCLS(Preds, .pred);
+  TEST_REGCLS(RRegs32, s32);
+  TEST_REGCLS(Preds, pred);
 #undef TEST_REGCLS
 
   llvm_unreachable("Not in any register class!");
   return NULL;
 }
 
+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)
+      return getRegisterTypeName(MO.getReg());
+  }
+
+  llvm_unreachable("No reg operand found in instruction!");
+  return NULL;
+}
+
 bool PTXAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   SetupMachineFunction(MF);
   EmitFunctionDeclaration();
@@ -89,7 +101,7 @@ void PTXAsmPrinter::EmitFunctionBodyStart() {
        i = MFI->localVarRegBegin(), e = MFI->localVarRegEnd(); i != e; ++ i) {
     unsigned reg = *i;
 
-    std::string def = "\t.reg ";
+    std::string def = "\t.reg .";
     def += getRegisterTypeName(reg);
     def += ' ';
     def += getRegisterName(reg);
@@ -99,11 +111,21 @@ void PTXAsmPrinter::EmitFunctionBodyStart() {
 }
 
 void PTXAsmPrinter::EmitInstruction(const MachineInstr *MI) {
-  SmallString<128> str;
-  raw_svector_ostream OS(str);
+  SmallString<128> sstr;
+  raw_svector_ostream OS(sstr);
   printInstruction(MI, OS);
   OS << ';';
-  OutStreamer.EmitRawText(OS.str());
+
+  // Replace "%type" if found
+  StringRef strref = OS.str();
+  size_t pos;
+  if ((pos = strref.find("%type")) == StringRef::npos) {
+    OutStreamer.EmitRawText(strref);
+    return;
+  }
+  std::string str = strref;
+  str.replace(pos, /*strlen("%type")==*/5, getInstructionTypeName(MI));
+  OutStreamer.EmitRawText(StringRef(str));
 }
 
 void PTXAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
@@ -141,7 +163,7 @@ void PTXAsmPrinter::EmitFunctionDeclaration() {
   // Print return register
   reg = MFI->retReg();
   if (!isKernel && reg != PTX::NoRegister) {
-    decl += " (.reg "; // FIXME: could it return in .param space?
+    decl += " (.reg ."; // FIXME: could it return in .param space?
     decl += getRegisterTypeName(reg);
     decl += " ";
     decl += getRegisterName(reg);
@@ -170,7 +192,7 @@ void PTXAsmPrinter::EmitFunctionDeclaration() {
         assert(reg != PTX::NoRegister && "Not a valid register!");
         if (i != b)
           decl += ", ";
-        decl += ".reg ";
+        decl += ".reg .";
         decl += getRegisterTypeName(reg);
         decl += " ";
         decl += getRegisterName(reg);
index e5dd334..71d9016 100644 (file)
@@ -27,9 +27,29 @@ def PTXret
   : SDNode<"PTXISD::RET",  SDTNone, [SDNPHasChain]>;
 
 //===----------------------------------------------------------------------===//
+// Instruction Class Templates
+//===----------------------------------------------------------------------===//
+
+multiclass INT3<string opcstr, SDNode opnode> {
+  def rr : InstPTX<(outs RRegs32:$d),
+                   (ins RRegs32:$a, RRegs32:$b),
+                   !strconcat(opcstr, ".%type\t$d, $a, $b"),
+                   [(set RRegs32:$d, (opnode RRegs32:$a, RRegs32:$b))]>;
+  def ri : InstPTX<(outs RRegs32:$d),
+                   (ins RRegs32:$a, i32imm:$b),
+                   !strconcat(opcstr, ".%type\t$d, $a, $b"),
+                   [(set RRegs32:$d, (opnode RRegs32:$a, imm:$b))]>;
+}
+
+//===----------------------------------------------------------------------===//
 // Instructions
 //===----------------------------------------------------------------------===//
 
+///===- Integer Arithmetic Instructions -----------------------------------===//
+
+defm ADD : INT3<"add", add>;
+defm SUB : INT3<"sub", sub>;
+
 ///===- Data Movement and Conversion Instructions -------------------------===//
 
 let neverHasSideEffects = 1 in {
@@ -37,7 +57,7 @@ let neverHasSideEffects = 1 in {
   def MOVpp
     : InstPTX<(outs Preds:$d), (ins Preds:$a), "mov.pred\t$d, $a", []>;
   def MOVrr
-    : InstPTX<(outs RRegs32:$d), (ins RRegs32:$a), "mov.s32\t$d, $a", []>;
+    : InstPTX<(outs RRegs32:$d), (ins RRegs32:$a), "mov.%type\t$d, $a", []>;
 }
 
 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
diff --git a/test/CodeGen/PTX/add.ll b/test/CodeGen/PTX/add.ll
new file mode 100644 (file)
index 0000000..1259d03
--- /dev/null
@@ -0,0 +1,15 @@
+; RUN: llc < %s -march=ptx | FileCheck %s
+
+define ptx_device i32 @t1(i32 %x, i32 %y) {
+; CHECK: add.s32 r0, r1, r2;
+       %z = add i32 %x, %y
+; CHECK: ret;
+       ret i32 %z
+}
+
+define ptx_device i32 @t2(i32 %x) {
+; CHECK: add.s32 r0, r1, 1;
+       %z = add i32 %x, 1
+; CHECK: ret;
+       ret i32 %z
+}
index 1fb297c..396898b 100644 (file)
@@ -1,6 +1,7 @@
 ; RUN: llc < %s -march=ptx | FileCheck %s
 
 define ptx_kernel void @t1() {
-;CHECK: exit;
+; CHECK: exit;
+; CHECK-NOT: ret;
        ret void
 }
index 287b846..c365e9b 100644 (file)
@@ -1,13 +1,13 @@
 ; RUN: llc < %s -march=ptx | FileCheck %s
 
 define ptx_device i32 @t1() {
-;CHECK: mov.s32 r0, 0;
-;CHECK: ret;
+; CHECK: mov.s32 r0, 0;
+; CHECK: ret;
        ret i32 0
 }
 
 define ptx_device i32 @t2(i32 %x) {
-;CHECK: mov.s32 r0, r1;
-;CHECK: ret;
+; CHECK: mov.s32 r0, r1;
+; CHECK: ret;
        ret i32 %x
 }
index c129ffe..d5037f2 100644 (file)
@@ -1,6 +1,7 @@
 ; RUN: llc < %s -march=ptx | FileCheck %s
 
 define ptx_device void @t1() {
-;CHECK: ret;
+; CHECK: ret;
+; CHECK-NOT: exit;
        ret void
 }
diff --git a/test/CodeGen/PTX/sub.ll b/test/CodeGen/PTX/sub.ll
new file mode 100644 (file)
index 0000000..aab3fda
--- /dev/null
@@ -0,0 +1,15 @@
+; RUN: llc < %s -march=ptx | FileCheck %s
+
+define ptx_device i32 @t1(i32 %x, i32 %y) {
+;CHECK: sub.s32 r0, r1, r2;
+       %z = sub i32 %x, %y
+;CHECK: ret;
+       ret i32 %z
+}
+
+define ptx_device i32 @t2(i32 %x) {
+;CHECK: add.s32 r0, r1, -1;
+       %z = sub i32 %x, 1
+;CHECK: ret;
+       ret i32 %z
+}