From 3f409f7fefea4d4191a914b528afe16fd7d0b4d9 Mon Sep 17 00:00:00 2001 From: Che-Liang Chiou Date: Wed, 17 Nov 2010 08:08:49 +0000 Subject: [PATCH] Add simple arithmetics and %type directive for PTX git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119485 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PTX/PTXAsmPrinter.cpp | 38 +++++++++++++++++++++++++------- lib/Target/PTX/PTXInstrInfo.td | 22 +++++++++++++++++- test/CodeGen/PTX/add.ll | 15 +++++++++++++ test/CodeGen/PTX/exit.ll | 3 ++- test/CodeGen/PTX/mov.ll | 8 +++---- test/CodeGen/PTX/ret.ll | 3 ++- test/CodeGen/PTX/sub.ll | 15 +++++++++++++ 7 files changed, 89 insertions(+), 15 deletions(-) create mode 100644 test/CodeGen/PTX/add.ll create mode 100644 test/CodeGen/PTX/sub.ll diff --git a/lib/Target/PTX/PTXAsmPrinter.cpp b/lib/Target/PTX/PTXAsmPrinter.cpp index b861807b633..175b3c47505 100644 --- a/lib/Target/PTX/PTXAsmPrinter.cpp +++ b/lib/Target/PTX/PTXAsmPrinter.cpp @@ -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); diff --git a/lib/Target/PTX/PTXInstrInfo.td b/lib/Target/PTX/PTXInstrInfo.td index e5dd3341753..71d9016cd76 100644 --- a/lib/Target/PTX/PTXInstrInfo.td +++ b/lib/Target/PTX/PTXInstrInfo.td @@ -26,10 +26,30 @@ def PTXexit def PTXret : SDNode<"PTXISD::RET", SDTNone, [SDNPHasChain]>; +//===----------------------------------------------------------------------===// +// Instruction Class Templates +//===----------------------------------------------------------------------===// + +multiclass INT3 { + 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 index 00000000000..1259d03e96c --- /dev/null +++ b/test/CodeGen/PTX/add.ll @@ -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 +} diff --git a/test/CodeGen/PTX/exit.ll b/test/CodeGen/PTX/exit.ll index 1fb297c7469..396898b623c 100644 --- a/test/CodeGen/PTX/exit.ll +++ b/test/CodeGen/PTX/exit.ll @@ -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 } diff --git a/test/CodeGen/PTX/mov.ll b/test/CodeGen/PTX/mov.ll index 287b846da73..c365e9beb89 100644 --- a/test/CodeGen/PTX/mov.ll +++ b/test/CodeGen/PTX/mov.ll @@ -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 } diff --git a/test/CodeGen/PTX/ret.ll b/test/CodeGen/PTX/ret.ll index c129ffe6ffa..d5037f25fd3 100644 --- a/test/CodeGen/PTX/ret.ll +++ b/test/CodeGen/PTX/ret.ll @@ -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 index 00000000000..aab3fdadad1 --- /dev/null +++ b/test/CodeGen/PTX/sub.ll @@ -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 +}