Author: baldrick Date: Fri Jul 27 07:58:54 2007 New Revision: 40549 URL: http://llvm.org/viewvc/llvm-project?rev=40549&view=rev Log: Support for trampolines, except for X86 codegen which is still under discussion.
Modified: llvm/trunk/docs/LangRef.html llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h llvm/trunk/include/llvm/Intrinsics.td llvm/trunk/include/llvm/ParameterAttributes.h llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/lib/AsmParser/Lexer.l llvm/trunk/lib/AsmParser/llvmAsmParser.y llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp llvm/trunk/lib/Target/IA64/IA64ISelLowering.cpp llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp llvm/trunk/lib/Target/TargetCallingConv.td llvm/trunk/lib/VMCore/Function.cpp llvm/trunk/lib/VMCore/Verifier.cpp Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=40549&r1=40548&r2=40549&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Fri Jul 27 07:58:54 2007 @@ -200,6 +200,12 @@ <li><a href="#int_memory_barrier">'<tt>llvm.memory.barrier</tt>' Intrinsic</a></li> </ol> </li> + <li><a href="#int_trampoline">Trampoline Intrinsics</a> + <ol> + <li><a href="#int_it">'<tt>llvm.init.trampoline</tt>' Intrinsic</a></li> + <li><a href="#int_at">'<tt>llvm.adjust.trampoline</tt>' Intrinsic</a></li> + </ol> + </li> <li><a href="#int_general">General intrinsics</a> <ol> <li><a href="#int_var_annotation"> @@ -5123,6 +5129,105 @@ <!-- ======================================================================= --> <div class="doc_subsection"> + <a name="int_trampoline">Trampoline Intrinsics</a> +</div> + +<div class="doc_text"> +<p> + These intrinsics make it possible to excise one parameter, marked with + the <tt>nest</tt> attribute, from a function. The result is a callable + function pointer lacking the nest parameter - the caller does not need + to provide a value for it. Instead, the value to use is stored in + advance in a "trampoline", a block of memory usually allocated + on the stack, which also contains code to splice the nest value into the + argument list. This is used to implement the GCC nested function address + extension. +</p> +<p> + For example, if the function is + <tt>i32 f(i8* nest %c, i32 %x, i32 %y)</tt> then the resulting function + pointer has signature <tt>i32 (i32, i32)*</tt>. It can be created as follows: +<pre> + %tramp1 = alloca [10 x i8], align 4 ; size and alignment only correct for X86 + %tramp = getelementptr [10 x i8]* %tramp1, i32 0, i32 0 + call void @llvm.init.trampoline( i8* %tramp, i8* bitcast (i32 (i8* nest , i32, i32)* @f to i8*), i8* %nval ) + %adj = call i8* @llvm.adjust.trampoline( i8* %tramp ) + %fp = bitcast i8* %adj to i32 (i32, i32)* +</pre> + The call <tt>%val = call i32 %fp( i32 %x, i32 %y )</tt> is then equivalent to + <tt>%val = call i32 %f( i8* %nval, i32 %x, i32 %y )</tt>. +</p> +<p> + Trampolines are currently only supported on the X86 architecture. +</p> +</div> + +<!-- _______________________________________________________________________ --> +<div class="doc_subsubsection"> + <a name="int_it">'<tt>llvm.init.trampoline</tt>' Intrinsic</a> +</div> +<div class="doc_text"> +<h5>Syntax:</h5> +<pre> +declare void @llvm.init.trampoline(i8* <tramp>, i8* <func>, i8* <nval>) +</pre> +<h5>Overview:</h5> +<p> + This initializes the memory pointed to by <tt>tramp</tt> as a trampoline. +</p> +<h5>Arguments:</h5> +<p> + The <tt>llvm.init.trampoline</tt> intrinsic takes three arguments, all + pointers. The <tt>tramp</tt> argument must point to a sufficiently large + and sufficiently aligned block of memory; this memory is written to by the + intrinsic. Currently LLVM provides no help in determining just how big and + aligned the memory needs to be. The <tt>func</tt> argument must hold a + function bitcast to an <tt>i8*</tt>. +</p> +<h5>Semantics:</h5> +<p> + The block of memory pointed to by <tt>tramp</tt> is filled with target + dependent code, turning it into a function. + The new function's signature is the same as that of <tt>func</tt> with + any arguments marked with the <tt>nest</tt> attribute removed. At most + one such <tt>nest</tt> argument is allowed, and it must be of pointer + type. Calling the new function is equivalent to calling <tt>func</tt> + with the same argument list, but with <tt>nval</tt> used for the missing + <tt>nest</tt> argument. +</p> +</div> + +<!-- _______________________________________________________________________ --> +<div class="doc_subsubsection"> + <a name="int_at">'<tt>llvm.adjust.trampoline</tt>' Intrinsic</a> +</div> +<div class="doc_text"> +<h5>Syntax:</h5> +<pre> +declare i8* @llvm.adjust.trampoline(i8* <tramp>) +</pre> +<h5>Overview:</h5> +<p> + This intrinsic returns a function pointer suitable for executing + the trampoline code pointed to by <tt>tramp</tt>. +</p> +<h5>Arguments:</h5> +<p> + The <tt>llvm.adjust.trampoline</tt> takes one argument, a pointer to a + trampoline initialized by the + <a href="#int_it">'<tt>llvm.init.trampoline</tt>' intrinsic</a>. +</p> +<h5>Semantics:</h5> +<p> + A function pointer that can be used to execute the trampoline code in + <tt>tramp</tt> is returned. The returned value should be bitcast to an + <a href="#int_trampoline">appropriate function pointer type</a> + before being called. +</p> +</div> + +<!-- ======================================================================= --> +<div class="doc_subsection"> <a name="int_general">General Intrinsics</a> </div> Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=40549&r1=40548&r2=40549&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Fri Jul 27 07:58:54 2007 @@ -66,6 +66,8 @@ StructReturnOffs = 3, ByVal = 1<<4, ///< Struct passed by value ByValOffs = 4, + Nest = 1<<5, ///< Parameter is nested function static chain + NestOffs = 5, OrigAlignment = 0x1F<<27, OrigAlignmentOffs = 27 }; @@ -528,7 +530,19 @@ // number, then a column then a file id (provided by MachineModuleInfo.) It // produces a token chain as output. DEBUG_LOC, - + + // ADJUST_TRAMP - This corresponds to the adjust_trampoline intrinsic. + // It takes a value as input and returns a value as output. + ADJUST_TRAMP, + + // TRAMPOLINE - This corresponds to the init_trampoline intrinsic. + // It takes as input a token chain, the pointer to the trampoline, + // the pointer to the nested function, the pointer to pass for the + // 'nest' parameter, a SRCVALUE for the trampoline and another for + // the nested function (allowing targets to access the original + // Function*). It produces a token chain as output. + TRAMPOLINE, + // BUILTIN_OP_END - This must be the last enum value in this list. BUILTIN_OP_END }; Modified: llvm/trunk/include/llvm/Intrinsics.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=40549&r1=40548&r2=40549&view=diff ============================================================================== --- llvm/trunk/include/llvm/Intrinsics.td (original) +++ llvm/trunk/include/llvm/Intrinsics.td Fri Jul 27 07:58:54 2007 @@ -247,6 +247,14 @@ llvm_ptr_ty, llvm_i32_ty], [], "llvm.var.annotation">; +//===------------------------ Trampoline Intrinsics -----------------------===// +// +def int_init_trampoline : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty, + llvm_ptr_ty], []>, + GCCBuiltin<"__builtin_init_trampoline">; +def int_adjust_trampoline : Intrinsic<[llvm_ptr_ty, llvm_ptr_ty], [IntrNoMem]>, + GCCBuiltin<"__builtin_adjust_trampoline">; + //===----------------------------------------------------------------------===// // Target-specific intrinsics //===----------------------------------------------------------------------===// Modified: llvm/trunk/include/llvm/ParameterAttributes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ParameterAttributes.h?rev=40549&r1=40548&r2=40549&view=diff ============================================================================== --- llvm/trunk/include/llvm/ParameterAttributes.h (original) +++ llvm/trunk/include/llvm/ParameterAttributes.h Fri Jul 27 07:58:54 2007 @@ -30,14 +30,15 @@ /// @brief Function parameter attributes. enum Attributes { None = 0, ///< No attributes have been set - ZExt = 1 << 0, ///< zero extended before/after call - SExt = 1 << 1, ///< sign extended before/after call - NoReturn = 1 << 2, ///< mark the function as not returning - InReg = 1 << 3, ///< force argument to be passed in register - StructRet = 1 << 4, ///< hidden pointer to structure to return + ZExt = 1 << 0, ///< Zero extended before/after call + SExt = 1 << 1, ///< Sign extended before/after call + NoReturn = 1 << 2, ///< Mark the function as not returning + InReg = 1 << 3, ///< Force argument to be passed in register + StructRet = 1 << 4, ///< Hidden pointer to structure to return NoUnwind = 1 << 5, ///< Function doesn't unwind stack - NoAlias = 1 << 6, ///< Considered to not alias after call. - ByVal = 1 << 7 ///< Pass structure by value + NoAlias = 1 << 6, ///< Considered to not alias after call + ByVal = 1 << 7, ///< Pass structure by value + Nest = 1 << 8 ///< Nested function static chain }; } Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=40549&r1=40548&r2=40549&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Fri Jul 27 07:58:54 2007 @@ -812,8 +812,10 @@ bool isZExt; bool isInReg; bool isSRet; + bool isNest; - ArgListEntry():isSExt(false), isZExt(false), isInReg(false), isSRet(false) { }; + ArgListEntry() : isSExt(false), isZExt(false), isInReg(false), + isSRet(false), isNest(false) { }; }; typedef std::vector<ArgListEntry> ArgListTy; virtual std::pair<SDOperand, SDOperand> Modified: llvm/trunk/lib/AsmParser/Lexer.l URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/Lexer.l?rev=40549&r1=40548&r2=40549&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/Lexer.l (original) +++ llvm/trunk/lib/AsmParser/Lexer.l Fri Jul 27 07:58:54 2007 @@ -233,6 +233,7 @@ noreturn { return NORETURN; } noalias { return NOALIAS; } byval { return BYVAL; } +nest { return NEST; } void { RET_TY(Type::VoidTy, VOID); } float { RET_TY(Type::FloatTy, FLOAT); } Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.y URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/llvmAsmParser.y?rev=40549&r1=40548&r2=40549&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/llvmAsmParser.y (original) +++ llvm/trunk/lib/AsmParser/llvmAsmParser.y Fri Jul 27 07:58:54 2007 @@ -1101,7 +1101,7 @@ %token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR // Function Attributes -%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL +%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST // Visibility Styles %token DEFAULT HIDDEN PROTECTED @@ -1229,7 +1229,8 @@ | INREG { $$ = ParamAttr::InReg; } | SRET { $$ = ParamAttr::StructRet; } | NOALIAS { $$ = ParamAttr::NoAlias; } - | BYVAL { $$ = ParamAttr::ByVal; } + | BYVAL { $$ = ParamAttr::ByVal; } + | NEST { $$ = ParamAttr::Nest; } ; OptParamAttrs : /* empty */ { $$ = ParamAttr::None; } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=40549&r1=40548&r2=40549&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Jul 27 07:58:54 2007 @@ -3156,6 +3156,31 @@ } break; } + case ISD::ADJUST_TRAMP: { + Tmp1 = LegalizeOp(Node->getOperand(0)); + switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { + default: assert(0 && "This action is not supported yet!"); + case TargetLowering::Custom: + Result = DAG.UpdateNodeOperands(Result, Tmp1); + Result = TLI.LowerOperation(Result, DAG); + if (Result.Val) break; + // FALL THROUGH + case TargetLowering::Expand: + Result = Tmp1; + break; + } + break; + } + case ISD::TRAMPOLINE: { + SDOperand Ops[6]; + for (unsigned i = 0; i != 6; ++i) + Ops[i] = LegalizeOp(Node->getOperand(i)); + Result = DAG.UpdateNodeOperands(Result, Ops, 6); + // The only option for this node is to custom lower it. + Result = TLI.LowerOperation(Result, DAG); + assert(Result.Val && "Should always custom lower!"); + break; + } } assert(Result.getValueType() == Op.getValueType() && Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=40549&r1=40548&r2=40549&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Jul 27 07:58:54 2007 @@ -3513,6 +3513,10 @@ case ISD::LOCATION: return "location"; case ISD::DEBUG_LOC: return "debug_loc"; + // Trampolines + case ISD::ADJUST_TRAMP: return "adjust_tramp"; + case ISD::TRAMPOLINE: return "trampoline"; + case ISD::CONDCODE: switch (cast<CondCodeSDNode>(this)->get()) { default: assert(0 && "Unknown setcc condition!"); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=40549&r1=40548&r2=40549&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Jul 27 07:58:54 2007 @@ -2863,6 +2863,28 @@ case Intrinsic::var_annotation: // Discard annotate attributes return 0; + + case Intrinsic::adjust_trampoline: { + SDOperand Arg = getValue(I.getOperand(1)); + setValue(&I, DAG.getNode(ISD::ADJUST_TRAMP, TLI.getPointerTy(), Arg)); + return 0; + } + + case Intrinsic::init_trampoline: { + const Function *F = + cast<Function>(IntrinsicInst::StripPointerCasts(I.getOperand(2))); + + SDOperand Ops[6]; + Ops[0] = getRoot(); + Ops[1] = getValue(I.getOperand(1)); + Ops[2] = getValue(I.getOperand(2)); + Ops[3] = getValue(I.getOperand(3)); + Ops[4] = DAG.getSrcValue(I.getOperand(1)); + Ops[5] = DAG.getSrcValue(F); + + DAG.setRoot(DAG.getNode(ISD::TRAMPOLINE, MVT::Other, Ops, 6)); + return 0; + } } } @@ -2892,6 +2914,7 @@ Entry.isZExt = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::ZExt); Entry.isInReg = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::InReg); Entry.isSRet = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::StructRet); + Entry.isNest = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::Nest); Args.push_back(Entry); } @@ -3827,6 +3850,8 @@ Flags |= ISD::ParamFlags::StructReturn; if (Attrs && Attrs->paramHasAttr(j, ParamAttr::ByVal)) Flags |= ISD::ParamFlags::ByVal; + if (Attrs && Attrs->paramHasAttr(j, ParamAttr::Nest)) + Flags |= ISD::ParamFlags::Nest; Flags |= (OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs); switch (getTypeAction(VT)) { @@ -3945,6 +3970,8 @@ Flags |= ISD::ParamFlags::InReg; if (Args[i].isSRet) Flags |= ISD::ParamFlags::StructReturn; + if (Args[i].isNest) + Flags |= ISD::ParamFlags::Nest; Flags |= OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs; switch (getTypeAction(VT)) { Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=40549&r1=40548&r2=40549&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri Jul 27 07:58:54 2007 @@ -190,7 +190,12 @@ setOperationAction(ISD::MEMSET , MVT::Other, Expand); setOperationAction(ISD::MEMCPY , MVT::Other, Custom); setOperationAction(ISD::MEMMOVE , MVT::Other, Expand); - + + if (Subtarget->isThumb()) + setOperationAction(ISD::ADJUST_TRAMP, MVT::i32, Custom); + else + setOperationAction(ISD::ADJUST_TRAMP, MVT::i32, Expand); + // Use the default implementation. setOperationAction(ISD::VASTART , MVT::Other, Expand); setOperationAction(ISD::VAARG , MVT::Other, Expand); @@ -1413,6 +1418,14 @@ return Chain; } +SDOperand ARMTargetLowering::LowerADJUST_TRAMP(SDOperand Op, + SelectionDAG &DAG) { + // Thumb trampolines should be entered in thumb mode, so set the bottom bit + // of the address. + return DAG.getNode(ISD::OR, MVT::i32, Op.getOperand(0), + DAG.getConstant(1, MVT::i32)); +} + SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { switch (Op.getOpcode()) { default: assert(0 && "Don't know how to custom lower this!"); abort(); @@ -1444,6 +1457,7 @@ case ISD::FRAMEADDR: break; case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG); case ISD::MEMCPY: return LowerMEMCPY(Op, DAG); + case ISD::ADJUST_TRAMP: return LowerADJUST_TRAMP(Op, DAG); } return SDOperand(); } Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=40549&r1=40548&r2=40549&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Fri Jul 27 07:58:54 2007 @@ -138,6 +138,7 @@ SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG); SDOperand LowerBR_JT(SDOperand Op, SelectionDAG &DAG); SDOperand LowerMEMCPY(SDOperand Op, SelectionDAG &DAG); + SDOperand LowerADJUST_TRAMP(SDOperand Op, SelectionDAG &DAG); }; } Modified: llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp?rev=40549&r1=40548&r2=40549&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp Fri Jul 27 07:58:54 2007 @@ -124,6 +124,9 @@ setOperationAction(ISD::ExternalSymbol, MVT::i64, Custom); setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom); + setOperationAction(ISD::ADJUST_TRAMP, MVT::i32, Expand); + setOperationAction(ISD::ADJUST_TRAMP, MVT::i64, Expand); + setOperationAction(ISD::VASTART, MVT::Other, Custom); setOperationAction(ISD::VAEND, MVT::Other, Expand); setOperationAction(ISD::VACOPY, MVT::Other, Custom); Modified: llvm/trunk/lib/Target/IA64/IA64ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/IA64/IA64ISelLowering.cpp?rev=40549&r1=40548&r2=40549&view=diff ============================================================================== --- llvm/trunk/lib/Target/IA64/IA64ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/IA64/IA64ISelLowering.cpp Fri Jul 27 07:58:54 2007 @@ -97,6 +97,8 @@ setOperationAction(ISD::ROTR , MVT::i64 , Expand); setOperationAction(ISD::BSWAP, MVT::i64 , Expand); // mux @rev + setOperationAction(ISD::ADJUST_TRAMP, MVT::i64, Expand); + // VASTART needs to be custom lowered to use the VarArgsFrameIndex setOperationAction(ISD::VAARG , MVT::Other, Custom); setOperationAction(ISD::VASTART , MVT::Other, Custom); Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=40549&r1=40548&r2=40549&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Fri Jul 27 07:58:54 2007 @@ -102,6 +102,8 @@ setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); + setOperationAction(ISD::ADJUST_TRAMP, MVT::i32, Expand); + setStackPointerRegisterToSaveRestore(Mips::SP); computeRegisterProperties(); } Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=40549&r1=40548&r2=40549&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Fri Jul 27 07:58:54 2007 @@ -169,7 +169,10 @@ // RET must be custom lowered, to meet ABI requirements setOperationAction(ISD::RET , MVT::Other, Custom); - + + setOperationAction(ISD::ADJUST_TRAMP, MVT::i32, Expand); + setOperationAction(ISD::ADJUST_TRAMP, MVT::i64, Expand); + // VASTART needs to be custom lowered to use the VarArgsFrameIndex setOperationAction(ISD::VASTART , MVT::Other, Custom); Modified: llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp?rev=40549&r1=40548&r2=40549&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp Fri Jul 27 07:58:54 2007 @@ -215,7 +215,9 @@ // RET must be custom lowered, to meet ABI requirements setOperationAction(ISD::RET , MVT::Other, Custom); - + + setOperationAction(ISD::ADJUST_TRAMP, MVT::i32, Expand); + // VASTART needs to be custom lowered to use the VarArgsFrameIndex. setOperationAction(ISD::VASTART , MVT::Other, Custom); // VAARG needs to be lowered to not do unaligned accesses for doubles. Modified: llvm/trunk/lib/Target/TargetCallingConv.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetCallingConv.td?rev=40549&r1=40548&r2=40549&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetCallingConv.td (original) +++ llvm/trunk/lib/Target/TargetCallingConv.td Fri Jul 27 07:58:54 2007 @@ -45,6 +45,10 @@ /// the specified action. class CCIfInReg<CCAction A> : CCIf<"ArgFlags & ISD::ParamFlags::InReg", A> {} +/// CCIfNest - If this argument is marked with the 'nest' attribute, apply +/// the specified action. +class CCIfNest<CCAction A> : CCIf<"ArgFlags & ISD::ParamFlags::Nest", A> {} + /// CCIfNotVarArg - If the current function is not vararg - apply the action class CCIfNotVarArg<CCAction A> : CCIf<"!State.isVarArg()", A> {} Modified: llvm/trunk/lib/VMCore/Function.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Function.cpp?rev=40549&r1=40548&r2=40549&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Function.cpp (original) +++ llvm/trunk/lib/VMCore/Function.cpp Fri Jul 27 07:58:54 2007 @@ -105,6 +105,8 @@ Result += "sret "; if (Attrs & ParamAttr::ByVal) Result += "byval "; + if (Attrs & ParamAttr::Nest) + Result += "nest "; return Result; } Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=40549&r1=40548&r2=40549&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Fri Jul 27 07:58:54 2007 @@ -361,6 +361,7 @@ if (const ParamAttrsList *Attrs = FT->getParamAttrs()) { unsigned Idx = 1; + bool SawNest = false; Assert1(!Attrs->paramHasAttr(0, ParamAttr::ByVal), "Attribute ByVal should not apply to functions!", &F); @@ -368,6 +369,8 @@ "Attribute SRet should not apply to functions!", &F); Assert1(!Attrs->paramHasAttr(0, ParamAttr::InReg), "Attribute InReg should not apply to functions!", &F); + Assert1(!Attrs->paramHasAttr(0, ParamAttr::Nest), + "Attribute Nest should not apply to functions!", &F); for (FunctionType::param_iterator I = FT->param_begin(), E = FT->param_end(); I != E; ++I, ++Idx) { @@ -391,6 +394,20 @@ "Attribute ByVal should only apply to pointer to structs!", &F); } + if (Attrs->paramHasAttr(Idx, ParamAttr::Nest)) { + Assert1(!SawNest, "More than one parameter has attribute Nest!", &F); + SawNest = true; + + Assert1(isa<PointerType>(FT->getParamType(Idx-1)), + "Attribute Nest should only apply to Pointer type!", &F); + Assert1(!Attrs->paramHasAttr(Idx, ParamAttr::ByVal), + "Attributes Nest and ByVal are incompatible!", &F); + Assert1(!Attrs->paramHasAttr(Idx, ParamAttr::InReg), + "Attributes Nest and InReg are incompatible!", &F); + Assert1(!Attrs->paramHasAttr(Idx, ParamAttr::StructRet), + "Attributes Nest and StructRet are incompatible!", &F); + } + Assert1(!Attrs->paramHasAttr(Idx, ParamAttr::NoReturn), "Attribute NoReturn should only be applied to function", &F); Assert1(!Attrs->paramHasAttr(Idx, ParamAttr::NoUnwind), _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits