diff --git a/include/llvm/CallingConv.h b/include/llvm/CallingConv.h index b3ad8428d28..2679cb71396 100644 --- a/include/llvm/CallingConv.h +++ b/include/llvm/CallingConv.h @@ -79,7 +79,15 @@ namespace CallingConv { /// X86_ThisCall - Similar to X86_StdCall. Passes first argument in ECX, /// others via stack. Callee is responsible for stack cleaning. MSVC uses /// this by default for methods in its ABI. - X86_ThisCall = 70 + X86_ThisCall = 70, + + /// PTX_Kernel - Call to a PTX kernel. + /// Passes all arguments in parameter space. + PTX_Kernel = 71, + + /// PTX_Device - Call to a PTX device function. + /// Passes all arguments in register or parameter space. + PTX_Device = 72 }; } // End CallingConv namespace diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index 34595e7a4ee..23ffd9d26b1 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -544,6 +544,8 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(arm_aapcscc); KEYWORD(arm_aapcs_vfpcc); KEYWORD(msp430_intrcc); + KEYWORD(ptx_kernel); + KEYWORD(ptx_device); KEYWORD(cc); KEYWORD(c); diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index f21a065473b..3a9c47c8f51 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -1084,6 +1084,8 @@ bool LLParser::ParseOptionalVisibility(unsigned &Res) { /// ::= 'arm_aapcscc' /// ::= 'arm_aapcs_vfpcc' /// ::= 'msp430_intrcc' +/// ::= 'ptx_kernel' +/// ::= 'ptx_device' /// ::= 'cc' UINT /// bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) { @@ -1099,6 +1101,8 @@ bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) { case lltok::kw_arm_aapcscc: CC = CallingConv::ARM_AAPCS; break; case lltok::kw_arm_aapcs_vfpcc:CC = CallingConv::ARM_AAPCS_VFP; break; case lltok::kw_msp430_intrcc: CC = CallingConv::MSP430_INTR; break; + case lltok::kw_ptx_kernel: CC = CallingConv::PTX_Kernel; break; + case lltok::kw_ptx_device: CC = CallingConv::PTX_Device; break; case lltok::kw_cc: { unsigned ArbitraryCC; Lex.Lex(); diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index 61f93a42749..8a8663e739a 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -72,6 +72,7 @@ namespace lltok { kw_x86_stdcallcc, kw_x86_fastcallcc, kw_x86_thiscallcc, kw_arm_apcscc, kw_arm_aapcscc, kw_arm_aapcs_vfpcc, kw_msp430_intrcc, + kw_ptx_kernel, kw_ptx_device, kw_signext, kw_zeroext, diff --git a/lib/Target/PTX/PTXISelLowering.cpp b/lib/Target/PTX/PTXISelLowering.cpp index 9d7e34434e2..d38abf1a3c9 100644 --- a/lib/Target/PTX/PTXISelLowering.cpp +++ b/lib/Target/PTX/PTXISelLowering.cpp @@ -32,6 +32,7 @@ const char *PTXTargetLowering::getTargetNodeName(unsigned Opcode) const { switch (Opcode) { default: llvm_unreachable("Unknown opcode"); case PTXISD::EXIT: return "PTXISD::EXIT"; + case PTXISD::RET: return "PTXISD::RET"; } } @@ -58,5 +59,25 @@ SDValue PTXTargetLowering:: const SmallVectorImpl &OutVals, DebugLoc dl, SelectionDAG &DAG) const { - return DAG.getNode(PTXISD::EXIT, dl, MVT::Other, Chain); + assert(!isVarArg && "PTX does not support var args."); + + switch (CallConv) { + default: + llvm_unreachable("Unsupported calling convention."); + case CallingConv::PTX_Kernel: + assert(Outs.size() == 0 && "Kernel must return void."); + return DAG.getNode(PTXISD::EXIT, dl, MVT::Other, Chain); + case CallingConv::PTX_Device: + assert(Outs.size() <= 1 && "Can at most return one value."); + break; + } + + // PTX_Device + + if (Outs.size() == 0) + return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain); + + // TODO: allocate return register + SDValue Flag; + return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain, Flag); } diff --git a/lib/Target/PTX/PTXISelLowering.h b/lib/Target/PTX/PTXISelLowering.h index d0978e76a8b..68badf538ce 100644 --- a/lib/Target/PTX/PTXISelLowering.h +++ b/lib/Target/PTX/PTXISelLowering.h @@ -24,7 +24,8 @@ class PTXTargetMachine; namespace PTXISD { enum NodeType { FIRST_NUMBER = ISD::BUILTIN_OP_END, - EXIT + EXIT, + RET }; } // namespace PTXISD diff --git a/lib/Target/PTX/PTXInstrInfo.td b/lib/Target/PTX/PTXInstrInfo.td index 758eff67ba2..3698c9dfc40 100644 --- a/lib/Target/PTX/PTXInstrInfo.td +++ b/lib/Target/PTX/PTXInstrInfo.td @@ -23,6 +23,8 @@ include "PTXInstrFormats.td" def PTXexit : SDNode<"PTXISD::EXIT", SDTNone, [SDNPHasChain]>; +def PTXret + : SDNode<"PTXISD::RET", SDTNone, [SDNPHasChain]>; //===----------------------------------------------------------------------===// // Instructions @@ -30,4 +32,5 @@ def PTXexit let isReturn = 1, isTerminator = 1, isBarrier = 1 in { def EXIT : InstPTX<(outs), (ins), "exit", [(PTXexit)]>; + def RET : InstPTX<(outs), (ins), "ret", [(PTXret)]>; } diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index adba594e287..7a1b7dd4e84 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -1579,6 +1579,8 @@ void AssemblyWriter::printFunction(const Function *F) { case CallingConv::ARM_AAPCS: Out << "arm_aapcscc "; break; case CallingConv::ARM_AAPCS_VFP:Out << "arm_aapcs_vfpcc "; break; case CallingConv::MSP430_INTR: Out << "msp430_intrcc "; break; + case CallingConv::PTX_Kernel: Out << "ptx_kernel"; break; + case CallingConv::PTX_Device: Out << "ptx_device"; break; default: Out << "cc" << F->getCallingConv() << " "; break; } @@ -1847,6 +1849,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { case CallingConv::ARM_AAPCS: Out << " arm_aapcscc "; break; case CallingConv::ARM_AAPCS_VFP:Out << " arm_aapcs_vfpcc "; break; case CallingConv::MSP430_INTR: Out << " msp430_intrcc "; break; + case CallingConv::PTX_Kernel: Out << " ptx_kernel"; break; + case CallingConv::PTX_Device: Out << " ptx_device"; break; default: Out << " cc" << CI->getCallingConv(); break; } @@ -1901,6 +1905,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { case CallingConv::ARM_AAPCS: Out << " arm_aapcscc "; break; case CallingConv::ARM_AAPCS_VFP:Out << " arm_aapcs_vfpcc "; break; case CallingConv::MSP430_INTR: Out << " msp430_intrcc "; break; + case CallingConv::PTX_Kernel: Out << " ptx_kernel"; break; + case CallingConv::PTX_Device: Out << " ptx_device"; break; default: Out << " cc" << II->getCallingConv(); break; } diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index e3ecc979bf1..7216891c827 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -685,6 +685,8 @@ void Verifier::visitFunction(Function &F) { case CallingConv::Cold: case CallingConv::X86_FastCall: case CallingConv::X86_ThisCall: + case CallingConv::PTX_Kernel: + case CallingConv::PTX_Device: Assert1(!F.isVarArg(), "Varargs functions must have C calling conventions!", &F); break; diff --git a/test/CodeGen/PTX/exit.ll b/test/CodeGen/PTX/exit.ll index e2b3857e369..1fb297c7469 100644 --- a/test/CodeGen/PTX/exit.ll +++ b/test/CodeGen/PTX/exit.ll @@ -1,6 +1,6 @@ ; RUN: llc < %s -march=ptx | FileCheck %s -define void @t1() { +define ptx_kernel void @t1() { ;CHECK: exit; ret void } diff --git a/utils/vim/llvm.vim b/utils/vim/llvm.vim index 28ab2e3d7aa..23802f49afa 100644 --- a/utils/vim/llvm.vim +++ b/utils/vim/llvm.vim @@ -49,6 +49,7 @@ syn keyword llvmKeyword hidden protected default syn keyword llvmKeyword except deplibs syn keyword llvmKeyword volatile fastcc coldcc cc ccc syn keyword llvmKeyword x86_stdcallcc x86_fastcallcc +syn keyword llvmKeyword ptx_kernel ptx_device syn keyword llvmKeyword signext zeroext inreg sret nounwind noreturn syn keyword llvmKeyword nocapture byval nest readnone readonly noalias syn keyword llvmKeyword inlinehint noinline alwaysinline optsize ssp sspreq