From 0e5b79c174235b8f2857f7f8f858684b590dd21a Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 15 Feb 2004 01:04:03 +0000 Subject: [PATCH] Implement llvm.(frame|return)address(0) correctly. They are used by the LLVM JIT, among other applications git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11459 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/InstSelectSimple.cpp | 25 +++++++++++++++++++++++++ lib/Target/X86/X86ISelSimple.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp index 6129c744ca3..ed61165b7e5 100644 --- a/lib/Target/X86/InstSelectSimple.cpp +++ b/lib/Target/X86/InstSelectSimple.cpp @@ -62,6 +62,7 @@ namespace { MachineFunction *F; // The function we are compiling into MachineBasicBlock *BB; // The current MBB we are compiling int VarArgsFrameIndex; // FrameIndex for start of varargs area + int ReturnAddressIndex; // FrameIndex for the return address std::map RegMap; // Mapping between Val's and SSA Regs @@ -86,6 +87,10 @@ namespace { BB = &F->front(); + // Set up a frame object for the return address. This is used by the + // llvm.returnaddress & llvm.frameaddress intrinisics. + ReturnAddressIndex = F->getFrameInfo()->CreateFixedObject(4, -4); + // Copy incoming arguments off of the stack... LoadArgumentsToVirtualRegs(Fn); @@ -1157,6 +1162,8 @@ void ISel::LowerUnknownIntrinsicFunctionCalls(Function &F) { case Intrinsic::va_start: case Intrinsic::va_copy: case Intrinsic::va_end: + case Intrinsic::returnaddress: + case Intrinsic::frameaddress: case Intrinsic::memcpy: case Intrinsic::memset: // We directly implement these intrinsics @@ -1190,6 +1197,24 @@ void ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) { return; case Intrinsic::va_end: return; // Noop on X86 + case Intrinsic::returnaddress: + case Intrinsic::frameaddress: + TmpReg1 = getReg(CI); + if (cast(CI.getOperand(1))->isNullValue()) { + if (ID == Intrinsic::returnaddress) { + // Just load the return address + addFrameReference(BuildMI(BB, X86::MOVmr32, 4, TmpReg1), + ReturnAddressIndex); + } else { + addFrameReference(BuildMI(BB, X86::LEAr32, 4, TmpReg1), + ReturnAddressIndex, -4); + } + } else { + // Values other than zero are not implemented yet. + BuildMI(BB, X86::MOVir32, 1, TmpReg1).addZImm(0); + } + return; + case Intrinsic::memcpy: { assert(CI.getNumOperands() == 5 && "Illegal llvm.memcpy call!"); unsigned Align = 1; diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp index 6129c744ca3..ed61165b7e5 100644 --- a/lib/Target/X86/X86ISelSimple.cpp +++ b/lib/Target/X86/X86ISelSimple.cpp @@ -62,6 +62,7 @@ namespace { MachineFunction *F; // The function we are compiling into MachineBasicBlock *BB; // The current MBB we are compiling int VarArgsFrameIndex; // FrameIndex for start of varargs area + int ReturnAddressIndex; // FrameIndex for the return address std::map RegMap; // Mapping between Val's and SSA Regs @@ -86,6 +87,10 @@ namespace { BB = &F->front(); + // Set up a frame object for the return address. This is used by the + // llvm.returnaddress & llvm.frameaddress intrinisics. + ReturnAddressIndex = F->getFrameInfo()->CreateFixedObject(4, -4); + // Copy incoming arguments off of the stack... LoadArgumentsToVirtualRegs(Fn); @@ -1157,6 +1162,8 @@ void ISel::LowerUnknownIntrinsicFunctionCalls(Function &F) { case Intrinsic::va_start: case Intrinsic::va_copy: case Intrinsic::va_end: + case Intrinsic::returnaddress: + case Intrinsic::frameaddress: case Intrinsic::memcpy: case Intrinsic::memset: // We directly implement these intrinsics @@ -1190,6 +1197,24 @@ void ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) { return; case Intrinsic::va_end: return; // Noop on X86 + case Intrinsic::returnaddress: + case Intrinsic::frameaddress: + TmpReg1 = getReg(CI); + if (cast(CI.getOperand(1))->isNullValue()) { + if (ID == Intrinsic::returnaddress) { + // Just load the return address + addFrameReference(BuildMI(BB, X86::MOVmr32, 4, TmpReg1), + ReturnAddressIndex); + } else { + addFrameReference(BuildMI(BB, X86::LEAr32, 4, TmpReg1), + ReturnAddressIndex, -4); + } + } else { + // Values other than zero are not implemented yet. + BuildMI(BB, X86::MOVir32, 1, TmpReg1).addZImm(0); + } + return; + case Intrinsic::memcpy: { assert(CI.getNumOperands() == 5 && "Illegal llvm.memcpy call!"); unsigned Align = 1;