aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/X86/X86FrameLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/X86/X86FrameLowering.cpp')
-rw-r--r--lib/Target/X86/X86FrameLowering.cpp268
1 files changed, 3 insertions, 265 deletions
diff --git a/lib/Target/X86/X86FrameLowering.cpp b/lib/Target/X86/X86FrameLowering.cpp
index b994e67..a06ba9d 100644
--- a/lib/Target/X86/X86FrameLowering.cpp
+++ b/lib/Target/X86/X86FrameLowering.cpp
@@ -365,270 +365,13 @@ void X86FrameLowering::emitCalleeSavedFrameMoves(MachineFunction &MF,
}
}
-/// getCompactUnwindRegNum - Get the compact unwind number for a given
-/// register. The number corresponds to the enum lists in
-/// compact_unwind_encoding.h.
-static int getCompactUnwindRegNum(unsigned Reg, bool is64Bit) {
- static const uint16_t CU32BitRegs[] = {
- X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0
- };
- static const uint16_t CU64BitRegs[] = {
- X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0
- };
- const uint16_t *CURegs = is64Bit ? CU64BitRegs : CU32BitRegs;
- for (int Idx = 1; *CURegs; ++CURegs, ++Idx)
- if (*CURegs == Reg)
- return Idx;
-
- return -1;
-}
-
-// Number of registers that can be saved in a compact unwind encoding.
-#define CU_NUM_SAVED_REGS 6
-
-/// encodeCompactUnwindRegistersWithoutFrame - Create the permutation encoding
-/// used with frameless stacks. It is passed the number of registers to be saved
-/// and an array of the registers saved.
-static uint32_t
-encodeCompactUnwindRegistersWithoutFrame(unsigned SavedRegs[CU_NUM_SAVED_REGS],
- unsigned RegCount, bool Is64Bit) {
- // The saved registers are numbered from 1 to 6. In order to encode the order
- // in which they were saved, we re-number them according to their place in the
- // register order. The re-numbering is relative to the last re-numbered
- // register. E.g., if we have registers {6, 2, 4, 5} saved in that order:
- //
- // Orig Re-Num
- // ---- ------
- // 6 6
- // 2 2
- // 4 3
- // 5 3
- //
- for (unsigned i = 0; i != CU_NUM_SAVED_REGS; ++i) {
- int CUReg = getCompactUnwindRegNum(SavedRegs[i], Is64Bit);
- if (CUReg == -1) return ~0U;
- SavedRegs[i] = CUReg;
- }
-
- // Reverse the list.
- std::swap(SavedRegs[0], SavedRegs[5]);
- std::swap(SavedRegs[1], SavedRegs[4]);
- std::swap(SavedRegs[2], SavedRegs[3]);
-
- uint32_t RenumRegs[CU_NUM_SAVED_REGS];
- for (unsigned i = CU_NUM_SAVED_REGS - RegCount; i < CU_NUM_SAVED_REGS; ++i) {
- unsigned Countless = 0;
- for (unsigned j = CU_NUM_SAVED_REGS - RegCount; j < i; ++j)
- if (SavedRegs[j] < SavedRegs[i])
- ++Countless;
-
- RenumRegs[i] = SavedRegs[i] - Countless - 1;
- }
-
- // Take the renumbered values and encode them into a 10-bit number.
- uint32_t permutationEncoding = 0;
- switch (RegCount) {
- case 6:
- permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1]
- + 6 * RenumRegs[2] + 2 * RenumRegs[3]
- + RenumRegs[4];
- break;
- case 5:
- permutationEncoding |= 120 * RenumRegs[1] + 24 * RenumRegs[2]
- + 6 * RenumRegs[3] + 2 * RenumRegs[4]
- + RenumRegs[5];
- break;
- case 4:
- permutationEncoding |= 60 * RenumRegs[2] + 12 * RenumRegs[3]
- + 3 * RenumRegs[4] + RenumRegs[5];
- break;
- case 3:
- permutationEncoding |= 20 * RenumRegs[3] + 4 * RenumRegs[4]
- + RenumRegs[5];
- break;
- case 2:
- permutationEncoding |= 5 * RenumRegs[4] + RenumRegs[5];
- break;
- case 1:
- permutationEncoding |= RenumRegs[5];
- break;
- }
-
- assert((permutationEncoding & 0x3FF) == permutationEncoding &&
- "Invalid compact register encoding!");
- return permutationEncoding;
-}
-
-/// encodeCompactUnwindRegistersWithFrame - Return the registers encoded for a
-/// compact encoding with a frame pointer.
-static uint32_t
-encodeCompactUnwindRegistersWithFrame(unsigned SavedRegs[CU_NUM_SAVED_REGS],
- bool Is64Bit) {
- // Encode the registers in the order they were saved, 3-bits per register. The
- // registers are numbered from 1 to CU_NUM_SAVED_REGS.
- uint32_t RegEnc = 0;
- for (int I = CU_NUM_SAVED_REGS - 1, Idx = 0; I != -1; --I) {
- unsigned Reg = SavedRegs[I];
- if (Reg == 0) continue;
-
- int CURegNum = getCompactUnwindRegNum(Reg, Is64Bit);
- if (CURegNum == -1) return ~0U;
-
- // Encode the 3-bit register number in order, skipping over 3-bits for each
- // register.
- RegEnc |= (CURegNum & 0x7) << (Idx++ * 3);
- }
-
- assert((RegEnc & 0x3FFFF) == RegEnc && "Invalid compact register encoding!");
- return RegEnc;
-}
-
-uint32_t X86FrameLowering::getCompactUnwindEncoding(MachineFunction &MF) const {
- const X86RegisterInfo *RegInfo = TM.getRegisterInfo();
- unsigned FramePtr = RegInfo->getFrameRegister(MF);
- unsigned StackPtr = RegInfo->getStackRegister();
-
- bool Is64Bit = STI.is64Bit();
- bool HasFP = hasFP(MF);
-
- unsigned SavedRegs[CU_NUM_SAVED_REGS] = { 0, 0, 0, 0, 0, 0 };
- unsigned SavedRegIdx = 0;
-
- unsigned OffsetSize = (Is64Bit ? 8 : 4);
-
- unsigned PushInstr = (Is64Bit ? X86::PUSH64r : X86::PUSH32r);
- unsigned PushInstrSize = 1;
- unsigned MoveInstr = (Is64Bit ? X86::MOV64rr : X86::MOV32rr);
- unsigned MoveInstrSize = (Is64Bit ? 3 : 2);
- unsigned SubtractInstrIdx = (Is64Bit ? 3 : 2);
-
- unsigned StackDivide = (Is64Bit ? 8 : 4);
-
- unsigned InstrOffset = 0;
- unsigned StackAdjust = 0;
- unsigned StackSize = 0;
-
- MachineBasicBlock &MBB = MF.front(); // Prologue is in entry BB.
- bool ExpectEnd = false;
- for (MachineBasicBlock::iterator
- MBBI = MBB.begin(), MBBE = MBB.end(); MBBI != MBBE; ++MBBI) {
- MachineInstr &MI = *MBBI;
- unsigned Opc = MI.getOpcode();
- if (Opc == X86::PROLOG_LABEL) continue;
- if (!MI.getFlag(MachineInstr::FrameSetup)) break;
-
- // We don't exect any more prolog instructions.
- if (ExpectEnd) return CU::UNWIND_MODE_DWARF;
-
- if (Opc == PushInstr) {
- // If there are too many saved registers, we cannot use compact encoding.
- if (SavedRegIdx >= CU_NUM_SAVED_REGS) return CU::UNWIND_MODE_DWARF;
-
- unsigned Reg = MI.getOperand(0).getReg();
- if (Reg == (Is64Bit ? X86::RAX : X86::EAX)) {
- ExpectEnd = true;
- continue;
- }
-
- SavedRegs[SavedRegIdx++] = MI.getOperand(0).getReg();
- StackAdjust += OffsetSize;
- InstrOffset += PushInstrSize;
- } else if (Opc == MoveInstr) {
- unsigned SrcReg = MI.getOperand(1).getReg();
- unsigned DstReg = MI.getOperand(0).getReg();
-
- if (DstReg != FramePtr || SrcReg != StackPtr)
- return CU::UNWIND_MODE_DWARF;
-
- StackAdjust = 0;
- memset(SavedRegs, 0, sizeof(SavedRegs));
- SavedRegIdx = 0;
- InstrOffset += MoveInstrSize;
- } else if (Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 ||
- Opc == X86::SUB32ri || Opc == X86::SUB32ri8) {
- if (StackSize)
- // We already have a stack size.
- return CU::UNWIND_MODE_DWARF;
-
- if (!MI.getOperand(0).isReg() ||
- MI.getOperand(0).getReg() != MI.getOperand(1).getReg() ||
- MI.getOperand(0).getReg() != StackPtr || !MI.getOperand(2).isImm())
- // We need this to be a stack adjustment pointer. Something like:
- //
- // %RSP<def> = SUB64ri8 %RSP, 48
- return CU::UNWIND_MODE_DWARF;
-
- StackSize = MI.getOperand(2).getImm() / StackDivide;
- SubtractInstrIdx += InstrOffset;
- ExpectEnd = true;
- }
- }
-
- // Encode that we are using EBP/RBP as the frame pointer.
- uint32_t CompactUnwindEncoding = 0;
- StackAdjust /= StackDivide;
- if (HasFP) {
- if ((StackAdjust & 0xFF) != StackAdjust)
- // Offset was too big for compact encoding.
- return CU::UNWIND_MODE_DWARF;
-
- // Get the encoding of the saved registers when we have a frame pointer.
- uint32_t RegEnc = encodeCompactUnwindRegistersWithFrame(SavedRegs, Is64Bit);
- if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF;
-
- CompactUnwindEncoding |= CU::UNWIND_MODE_BP_FRAME;
- CompactUnwindEncoding |= (StackAdjust & 0xFF) << 16;
- CompactUnwindEncoding |= RegEnc & CU::UNWIND_BP_FRAME_REGISTERS;
- } else {
- ++StackAdjust;
- uint32_t TotalStackSize = StackAdjust + StackSize;
- if ((TotalStackSize & 0xFF) == TotalStackSize) {
- // Frameless stack with a small stack size.
- CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IMMD;
-
- // Encode the stack size.
- CompactUnwindEncoding |= (TotalStackSize & 0xFF) << 16;
- } else {
- if ((StackAdjust & 0x7) != StackAdjust)
- // The extra stack adjustments are too big for us to handle.
- return CU::UNWIND_MODE_DWARF;
-
- // Frameless stack with an offset too large for us to encode compactly.
- CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IND;
-
- // Encode the offset to the nnnnnn value in the 'subl $nnnnnn, ESP'
- // instruction.
- CompactUnwindEncoding |= (SubtractInstrIdx & 0xFF) << 16;
-
- // Encode any extra stack stack adjustments (done via push instructions).
- CompactUnwindEncoding |= (StackAdjust & 0x7) << 13;
- }
-
- // Encode the number of registers saved.
- CompactUnwindEncoding |= (SavedRegIdx & 0x7) << 10;
-
- // Get the encoding of the saved registers when we don't have a frame
- // pointer.
- uint32_t RegEnc =
- encodeCompactUnwindRegistersWithoutFrame(SavedRegs, SavedRegIdx,
- Is64Bit);
- if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF;
-
- // Encode the register encoding.
- CompactUnwindEncoding |=
- RegEnc & CU::UNWIND_FRAMELESS_STACK_REG_PERMUTATION;
- }
-
- return CompactUnwindEncoding;
-}
-
/// usesTheStack - This function checks if any of the users of EFLAGS
/// copies the EFLAGS. We know that the code that lowers COPY of EFLAGS has
/// to use the stack, and if we don't adjust the stack we clobber the first
/// frame index.
/// See X86InstrInfo::copyPhysReg.
-static bool usesTheStack(MachineFunction &MF) {
- MachineRegisterInfo &MRI = MF.getRegInfo();
+static bool usesTheStack(const MachineFunction &MF) {
+ const MachineRegisterInfo &MRI = MF.getRegInfo();
for (MachineRegisterInfo::reg_iterator ri = MRI.reg_begin(X86::EFLAGS),
re = MRI.reg_end(); ri != re; ++ri)
@@ -863,7 +606,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF) const {
// responsible for adjusting the stack pointer. Touching the stack at 4K
// increments is necessary to ensure that the guard pages used by the OS
// virtual memory manager are allocated in correct sequence.
- if (NumBytes >= 4096 && STI.isTargetCOFF() && !STI.isTargetEnvMacho()) {
+ if (NumBytes >= 4096 && STI.isOSWindows() && !STI.isTargetEnvMacho()) {
const char *StackProbeSymbol;
bool isSPUpdateNeeded = false;
@@ -964,11 +707,6 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF) const {
if (PushedRegs)
emitCalleeSavedFrameMoves(MF, Label, HasFP ? FramePtr : StackPtr);
}
-
- // Darwin 10.7 and greater has support for compact unwind encoding.
- if (STI.getTargetTriple().isMacOSX() &&
- !STI.getTargetTriple().isMacOSXVersionLT(10, 7))
- MMI.setCompactUnwindEncoding(getCompactUnwindEncoding(MF));
}
void X86FrameLowering::emitEpilogue(MachineFunction &MF,