Index: llvm/trunk/lib/Target/X86/X86FrameLowering.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86FrameLowering.cpp +++ llvm/trunk/lib/Target/X86/X86FrameLowering.cpp @@ -2298,6 +2298,28 @@ #endif } +/// Lookup an ERTS parameter in the !hipe.literals named metadata node. +/// HiPE provides Erlang Runtime System-internal parameters, such as PCB offsets +/// to fields it needs, through a named metadata node "hipe.literals" containing +/// name-value pairs. +static unsigned getHiPELiteral( + NamedMDNode *HiPELiteralsMD, const StringRef LiteralName) { + for (int i = 0, e = HiPELiteralsMD->getNumOperands(); i != e; ++i) { + MDNode *Node = HiPELiteralsMD->getOperand(i); + if (Node->getNumOperands() != 2) continue; + MDString *NodeName = dyn_cast(Node->getOperand(0)); + ValueAsMetadata *NodeVal = dyn_cast(Node->getOperand(1)); + if (!NodeName || !NodeVal) continue; + ConstantInt *ValConst = dyn_cast_or_null(NodeVal->getValue()); + if (ValConst && NodeName->getString() == LiteralName) { + return ValConst->getZExtValue(); + } + } + + report_fatal_error("HiPE literal " + LiteralName + + " required but not provided"); +} + /// Erlang programs may need a special prologue to handle the stack size they /// might need at runtime. That is because Erlang/OTP does not implement a C /// stack but uses a custom implementation of hybrid stack/heap architecture. @@ -2323,7 +2345,14 @@ assert(&(*MF.begin()) == &PrologueMBB && "Shrink-wrapping not supported yet"); // HiPE-specific values - const unsigned HipeLeafWords = 24; + NamedMDNode *HiPELiteralsMD = MF.getMMI().getModule() + ->getNamedMetadata("hipe.literals"); + if (!HiPELiteralsMD) + report_fatal_error( + "Can't generate HiPE prologue without runtime parameters"); + const unsigned HipeLeafWords + = getHiPELiteral(HiPELiteralsMD, + Is64Bit ? "AMD64_LEAF_WORDS" : "X86_LEAF_WORDS"); const unsigned CCRegisteredArgs = Is64Bit ? 6 : 5; const unsigned Guaranteed = HipeLeafWords * SlotSize; unsigned CallerStkArity = MF.getFunction()->arg_size() > CCRegisteredArgs ? @@ -2395,20 +2424,19 @@ unsigned ScratchReg, SPReg, PReg, SPLimitOffset; unsigned LEAop, CMPop, CALLop; + SPLimitOffset = getHiPELiteral(HiPELiteralsMD, "P_NSP_LIMIT"); if (Is64Bit) { SPReg = X86::RSP; PReg = X86::RBP; LEAop = X86::LEA64r; CMPop = X86::CMP64rm; CALLop = X86::CALL64pcrel32; - SPLimitOffset = 0x90; } else { SPReg = X86::ESP; PReg = X86::EBP; LEAop = X86::LEA32r; CMPop = X86::CMP32rm; CALLop = X86::CALLpcrel32; - SPLimitOffset = 0x4c; } ScratchReg = GetScratchRegister(Is64Bit, IsLP64, MF, true); Index: llvm/trunk/test/CodeGen/X86/hipe-cc.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/hipe-cc.ll +++ llvm/trunk/test/CodeGen/X86/hipe-cc.ll @@ -73,5 +73,9 @@ ret void } +!hipe.literals = !{ !0, !1, !2 } +!0 = !{ !"P_NSP_LIMIT", i32 84 } +!1 = !{ !"X86_LEAF_WORDS", i32 24 } +!2 = !{ !"AMD64_LEAF_WORDS", i32 24 } @clos = external constant i32 declare cc 11 void @bar(i32, i32, i32, i32, i32) Index: llvm/trunk/test/CodeGen/X86/hipe-cc64.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/hipe-cc64.ll +++ llvm/trunk/test/CodeGen/X86/hipe-cc64.ll @@ -83,5 +83,9 @@ ret void } +!hipe.literals = !{ !0, !1, !2 } +!0 = !{ !"P_NSP_LIMIT", i32 160 } +!1 = !{ !"X86_LEAF_WORDS", i32 24 } +!2 = !{ !"AMD64_LEAF_WORDS", i32 24 } @clos = external constant i64 declare cc 11 void @bar(i64, i64, i64, i64, i64, i64) Index: llvm/trunk/test/CodeGen/X86/hipe-prologue.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/hipe-prologue.ll +++ llvm/trunk/test/CodeGen/X86/hipe-prologue.ll @@ -25,7 +25,7 @@ define cc 11 {i32, i32} @test_basic_hipecc(i32 %hp, i32 %p) { ; X32-Linux-LABEL: test_basic_hipecc: ; X32-Linux: leal -140(%esp), %ebx - ; X32-Linux-NEXT: cmpl 76(%ebp), %ebx + ; X32-Linux-NEXT: cmpl 120(%ebp), %ebx ; X32-Linux-NEXT: jb .LBB1_1 ; X32-Linux: ret @@ -34,8 +34,8 @@ ; X32-Linux-NEXT: calll inc_stack_0 ; X64-Linux-LABEL: test_basic_hipecc: - ; X64-Linux: leaq -232(%rsp), %r14 - ; X64-Linux-NEXT: cmpq 144(%rbp), %r14 + ; X64-Linux: leaq -184(%rsp), %r14 + ; X64-Linux-NEXT: cmpq 120(%rbp), %r14 ; X64-Linux-NEXT: jb .LBB1_1 ; X64-Linux: ret @@ -65,3 +65,8 @@ %6 = insertvalue {i32, i32, i32} %5, i32 %p, 2 ret {i32, i32, i32} %6 } + +!hipe.literals = !{ !0, !1, !2 } +!0 = !{ !"P_NSP_LIMIT", i32 120 } +!1 = !{ !"X86_LEAF_WORDS", i32 24 } +!2 = !{ !"AMD64_LEAF_WORDS", i32 18 }