diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AsmParser/Lexer.l | 1 | ||||
-rw-r--r-- | lib/AsmParser/llvmAsmParser.y | 3 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 2 | ||||
-rw-r--r-- | lib/Target/TargetCallingConv.td | 12 | ||||
-rw-r--r-- | lib/Target/X86/X86CallingConv.td | 4 | ||||
-rw-r--r-- | lib/VMCore/Function.cpp | 2 | ||||
-rw-r--r-- | lib/VMCore/Verifier.cpp | 3 |
7 files changed, 23 insertions, 4 deletions
diff --git a/lib/AsmParser/Lexer.l b/lib/AsmParser/Lexer.l index 6391d17a52..bc61e97ca9 100644 --- a/lib/AsmParser/Lexer.l +++ b/lib/AsmParser/Lexer.l @@ -230,6 +230,7 @@ sret { return SRET; } nounwind { return NOUNWIND; } noreturn { return NORETURN; } noalias { return NOALIAS; } +byval { return BYVAL; } void { RET_TY(Type::VoidTy, VOID); } float { RET_TY(Type::FloatTy, FLOAT); } diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index 94aeecaf83..c8790819d3 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -1101,7 +1101,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { %token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR // Function Attributes -%token NORETURN INREG SRET NOUNWIND NOALIAS +%token NORETURN INREG SRET NOUNWIND NOALIAS BYVAL // Visibility Styles %token DEFAULT HIDDEN PROTECTED @@ -1229,6 +1229,7 @@ ParamAttr : ZEXT { $$ = ParamAttr::ZExt; } | INREG { $$ = ParamAttr::InReg; } | SRET { $$ = ParamAttr::StructRet; } | NOALIAS { $$ = ParamAttr::NoAlias; } + | BYVAL { $$ = ParamAttr::ByVal; } ; OptParamAttrs : /* empty */ { $$ = ParamAttr::None; } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 182063fac2..8af76b1cd1 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -3789,6 +3789,8 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { Flags |= ISD::ParamFlags::InReg; if (Attrs && Attrs->paramHasAttr(j, ParamAttr::StructRet)) Flags |= ISD::ParamFlags::StructReturn; + if (Attrs && Attrs->paramHasAttr(j, ParamAttr::ByVal)) + Flags |= ISD::ParamFlags::ByVal; Flags |= (OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs); switch (getTypeAction(VT)) { diff --git a/lib/Target/TargetCallingConv.td b/lib/Target/TargetCallingConv.td index e710ad08e7..94193200ea 100644 --- a/lib/Target/TargetCallingConv.td +++ b/lib/Target/TargetCallingConv.td @@ -32,6 +32,11 @@ class CCIf<string predicate, CCAction A> : CCPredicateAction<A> { string Predicate = predicate; } +/// CCIfStruct - If the current argument is a struct, apply +/// Action A. +class CCIfStruct<CCAction A> : CCIf<"ArgFlags & ISD::ParamFlags::ByVal", A> { +} + /// CCIfCC - Match of the current calling convention is 'CC'. class CCIfCC<string CC, CCAction A> : CCIf<!strconcat("State.getCallingConv() == ", CC), A> {} @@ -57,6 +62,12 @@ class CCAssignToStack<int size, int align> : CCAction { int Align = align; } +/// CCStructAssign - This action always matches: it will use the C ABI and +/// the register availability to decided whether to assign to a set of +/// registers or to a stack slot. +class CCStructAssign<list<Register> regList> : CCAction { + list<Register> RegList = regList; +} /// CCPromoteToType - If applied, this promotes the specified current value to /// the specified type. @@ -75,4 +86,3 @@ class CCDelegateTo<CallingConv cc> : CCAction { class CallingConv<list<CCAction> actions> { list<CCAction> Actions = actions; } - diff --git a/lib/Target/X86/X86CallingConv.td b/lib/Target/X86/X86CallingConv.td index c98b3a2aec..39811bd740 100644 --- a/lib/Target/X86/X86CallingConv.td +++ b/lib/Target/X86/X86CallingConv.td @@ -94,6 +94,8 @@ def CC_X86_64_C : CallingConv<[ // Promote i8/i16 arguments to i32. CCIfType<[i8, i16], CCPromoteToType<i32>>, + CCIfStruct<CCStructAssign<[RDI, RSI, RDX, RCX, R8, R9 ]>>, + // The first 6 integer arguments are passed in integer registers. CCIfType<[i32], CCAssignToReg<[EDI, ESI, EDX, ECX, R8D, R9D]>>, CCIfType<[i64], CCAssignToReg<[RDI, RSI, RDX, RCX, R8 , R9 ]>>, @@ -168,5 +170,3 @@ def CC_X86_32_FastCall : CallingConv<[ // Otherwise, same as everything else. CCDelegateTo<CC_X86_32_Common> ]>; - - diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index c10f8d75bd..ab12ae8bfe 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -103,6 +103,8 @@ ParamAttrsList::getParamAttrsText(uint16_t Attrs) { Result += "noalias "; if (Attrs & ParamAttr::StructRet) Result += "sret "; + if (Attrs & ParamAttr::ByVal) + Result += "byval "; return Result; } diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 3442149401..16e87f4f7a 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -370,6 +370,9 @@ void Verifier::visitFunction(Function &F) { if (Attrs->paramHasAttr(Idx, ParamAttr::NoAlias)) Assert1(isa<PointerType>(FT->getParamType(Idx-1)), "Attribute NoAlias should only apply to Pointer type!", &F); + if (Attrs->paramHasAttr(Idx, ParamAttr::ByVal)) + Assert1(isa<PointerType>(FT->getParamType(Idx-1)), + "Attribute ByVal should only apply to Pointer type!", &F); } } |