Implement llvm.(frame|return)address(0) correctly. They are used by the LLVM JIT...
authorChris Lattner <sabre@nondot.org>
Sun, 15 Feb 2004 01:04:03 +0000 (01:04 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 15 Feb 2004 01:04:03 +0000 (01:04 +0000)
applications

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11459 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/InstSelectSimple.cpp
lib/Target/X86/X86ISelSimple.cpp

index 6129c744ca3b8bcce6328470f24bc9ee92e1aba4..ed61165b7e5f97f2036024a333d96aae0d161504 100644 (file)
@@ -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<Value*, unsigned> 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<Constant>(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;
index 6129c744ca3b8bcce6328470f24bc9ee92e1aba4..ed61165b7e5f97f2036024a333d96aae0d161504 100644 (file)
@@ -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<Value*, unsigned> 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<Constant>(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;