Clean up the handling of an EBP/RBP unwind frame pointer. In particular, don't
authorBill Wendling <isanbard@gmail.com>
Wed, 13 Jul 2011 00:16:14 +0000 (00:16 +0000)
committerBill Wendling <isanbard@gmail.com>
Wed, 13 Jul 2011 00:16:14 +0000 (00:16 +0000)
assert when the frame pointer is -1 (i.e., the function is "frameless").

Still to do: "frameless" unwind information.

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

lib/Target/X86/X86FrameLowering.cpp

index fb53e2734aaf671e4d86785cd0f6d504fad11a0b..87368f3a589e57c8ab4fd08effb73a6448b6a39f 100644 (file)
@@ -1064,7 +1064,7 @@ getCompactUnwindEncoding(ArrayRef<MCCFIInstruction> Instrs,
         if (IsRelative)
           CFAOffset += Src.getOffset();
         else
-          CFAOffset = -Src.getOffset();
+          CFAOffset -= Src.getOffset();
       } // else DW_CFA_def_cfa
 
       continue;
@@ -1072,6 +1072,13 @@ getCompactUnwindEncoding(ArrayRef<MCCFIInstruction> Instrs,
 
     if (Src.isReg() && Src.getReg() == MachineLocation::VirtualFP) {
       // DW_CFA_def_cfa_register
+      assert(FramePointerReg != -1 && "Defining more than one frame pointer?");
+      if (TRI->getLLVMRegNum(FramePointerReg, IsEH) != X86::EBP &&
+          TRI->getLLVMRegNum(FramePointerReg, IsEH) != X86::RBP)
+        // The frame pointer isn't EBP/RBP. Cannot make unwind information
+        // compact.
+        return 0;
+
       FramePointerReg = Dst.getReg();
       continue;
     }
@@ -1088,7 +1095,9 @@ getCompactUnwindEncoding(ArrayRef<MCCFIInstruction> Instrs,
       return 0;
     } else if (Reg < 64) {
       // DW_CFA_offset + Reg
-      SavedRegs.push_back(Reg);
+      int CURegNum = TRI->getCompactUnwindRegNum(Reg, IsEH);
+      if (CURegNum == -1) return 0;
+      SavedRegs.push_back(CURegNum);
     } else {
       // FIXME: Handle?
       // DW_CFA_offset_extended
@@ -1096,33 +1105,27 @@ getCompactUnwindEncoding(ArrayRef<MCCFIInstruction> Instrs,
     }
   }
 
-  CFAOffset /= 4;
-
   // Check if the offset is too big.
+  CFAOffset /= 4;
   if ((CFAOffset & 0xFF) != CFAOffset)
     return 0;
+  Encoding |= (CFAOffset & 0xFF) << 16; // Size encoding.
 
-  // Bail if there are too many registers to encode.
-  unsigned NumRegsToEncode = SavedRegs.size() - (FramePointerReg != -1 ? 1 : 0);
-  if (NumRegsToEncode > 5) return 0;
-
-  if (TRI->getLLVMRegNum(FramePointerReg, IsEH) != X86::EBP &&
-      TRI->getLLVMRegNum(FramePointerReg, IsEH) != X86::RBP)
-    // FIXME: Handle frameless version!
-    return 0;
-
-  Encoding |= 1 << 24;
-  Encoding |= (CFAOffset & 0xFF) << 16;
-
-  unsigned Idx = 0;
-  for (SmallVectorImpl<unsigned>::iterator
-         I = SavedRegs.begin(), E = SavedRegs.end(); I != E; ++I) {
-    if (*I == unsigned(FramePointerReg)) continue;
+  if (FramePointerReg != -1) {
+    // Bail if there are too many registers to encode.
+    if (SavedRegs.size() - 1 > 5) return 0;
 
-    int CURegNum = TRI->getCompactUnwindRegNum(*I, IsEH);
-    if (CURegNum == -1) return 0;
+    Encoding |= 1 << 24;        // EBP/RBP Unwind Frame
 
-    Encoding |= (CURegNum & 0x7) << (Idx++ * 3);
+    unsigned Idx = 0;
+    for (SmallVectorImpl<unsigned>::iterator
+           I = SavedRegs.begin(), E = SavedRegs.end(); I != E; ++I) {
+      unsigned Reg = *I;
+      if (Reg == unsigned(FramePointerReg)) continue;
+      Encoding |= (Reg & 0x7) << (Idx++ * 3); // Register encoding
+    }
+  } else {
+    // FIXME: Handle frameless version!
   }
 
   return Encoding;