diff options
author | Bill Wendling <isanbard@gmail.com> | 2011-07-14 22:01:34 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2011-07-14 22:01:34 +0000 |
commit | 13123d94630494d5b1ac87472eb45de681549166 (patch) | |
tree | e609a7035912b2d40815564b48bf5b6851f552b2 /lib/Target/X86 | |
parent | 3dcb4ef757127d69c3748dec92787520e039bd53 (diff) | |
download | external_llvm-13123d94630494d5b1ac87472eb45de681549166.zip external_llvm-13123d94630494d5b1ac87472eb45de681549166.tar.gz external_llvm-13123d94630494d5b1ac87472eb45de681549166.tar.bz2 |
* Redo the permutation encoding for frameless stacks to be more like what the
unwind library expects.
* Comment the permutation encoding for frameless stacks.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135202 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86')
-rw-r--r-- | lib/Target/X86/X86FrameLowering.cpp | 117 |
1 files changed, 73 insertions, 44 deletions
diff --git a/lib/Target/X86/X86FrameLowering.cpp b/lib/Target/X86/X86FrameLowering.cpp index af1595e..ed45a9a 100644 --- a/lib/Target/X86/X86FrameLowering.cpp +++ b/lib/Target/X86/X86FrameLowering.cpp @@ -1031,45 +1031,67 @@ X86FrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, } } +/// permuteEncode - 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 permuteEncode(unsigned SavedCount, unsigned Registers[6]) { - uint32_t RenumRegs[6]; - for (int i = 6 - SavedCount; i < 6; ++i) { - int countless = 0; - for (int j = 6 - SavedCount; j < i; ++j) - if (Registers[j] < Registers[i]) - ++countless; - - RenumRegs[i] = Registers[i] - countless - 1; - } - - uint32_t permutationEncoding = 0; - switch (SavedCount) { - 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; - } - return permutationEncoding; + // 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 + // + bool Used[7] = { false, false, false, false, false, false, false }; + uint32_t RenumRegs[6]; + for (unsigned I = 0; I < SavedCount; ++I) { + uint32_t Renum = 0; + for (unsigned U = 1; U < 7; ++U) { + if (U == Registers[I]) + break; + if (!Used[U]) + ++Renum; + } + + Used[Registers[I]] = true; + RenumRegs[I] = Renum; + } + + // Take the renumbered values and encode them into a 10-bit number. + uint32_t permutationEncoding = 0; + switch (SavedCount) { + case 6: + permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1] + + 6 * RenumRegs[2] + 2 * RenumRegs[3] + + RenumRegs[4]; + break; + case 5: + permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1] + + 6 * RenumRegs[2] + 2 * RenumRegs[3] + + RenumRegs[4]; + break; + case 4: + permutationEncoding |= 60 * RenumRegs[0] + 12 * RenumRegs[1] + + 3 * RenumRegs[2] + RenumRegs[3]; + break; + case 3: + permutationEncoding |= 20 * RenumRegs[0] + 4 * RenumRegs[1] + + RenumRegs[2]; + break; + case 2: + permutationEncoding |= 5 * RenumRegs[0] + RenumRegs[1]; + break; + case 1: + permutationEncoding |= RenumRegs[0]; + break; + } + + return permutationEncoding; } uint32_t X86FrameLowering:: @@ -1104,12 +1126,12 @@ getCompactUnwindEncoding(ArrayRef<MCCFIInstruction> Instrs, if (Src.getReg() != MachineLocation::VirtualFP) { // DW_CFA_def_cfa assert(FramePointerReg == -1 &&"Defining more than one frame pointer?"); - FramePointerReg = Src.getReg(); - if (TRI->getLLVMRegNum(FramePointerReg, IsEH) != X86::EBP && - TRI->getLLVMRegNum(FramePointerReg, IsEH) != X86::RBP) + if (TRI->getLLVMRegNum(Src.getReg(), IsEH) != X86::EBP && + TRI->getLLVMRegNum(Src.getReg(), IsEH) != X86::RBP) // The frame pointer isn't EBP/RBP. Cannot make unwind information // compact. return 0; + FramePointerReg = TRI->getCompactUnwindRegNum(Src.getReg(), IsEH); } // else DW_CFA_def_cfa_offset if (IsRelative) @@ -1123,12 +1145,19 @@ 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?"); - FramePointerReg = Dst.getReg(); - if (TRI->getLLVMRegNum(FramePointerReg, IsEH) != X86::EBP && - TRI->getLLVMRegNum(FramePointerReg, IsEH) != X86::RBP) + + if (TRI->getLLVMRegNum(Dst.getReg(), IsEH) != X86::EBP && + TRI->getLLVMRegNum(Dst.getReg(), IsEH) != X86::RBP) // The frame pointer isn't EBP/RBP. Cannot make unwind information // compact. return 0; + + FramePointerReg = TRI->getCompactUnwindRegNum(Dst.getReg(), IsEH); + if (SavedRegIdx != 1 || SavedRegs[0] != unsigned(FramePointerReg)) + return 0; + + SavedRegs[0] = 0; + SavedRegIdx = 0; continue; } |