mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-29 22:50:47 +00:00
Add a target hook to encode the compact unwind information.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134577 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e727d67c58
commit
6a6b8c3e96
@ -30,8 +30,9 @@ class TargetAsmInfo {
|
||||
unsigned PointerSize;
|
||||
bool IsLittleEndian;
|
||||
TargetFrameLowering::StackDirection StackDir;
|
||||
const TargetRegisterInfo *TRI;
|
||||
std::vector<MachineMove> InitialFrameState;
|
||||
const TargetRegisterInfo *TRI;
|
||||
const TargetFrameLowering *TFI;
|
||||
const TargetLoweringObjectFile *TLOF;
|
||||
|
||||
public:
|
||||
@ -83,6 +84,11 @@ public:
|
||||
return TLOF->isFunctionEHFrameSymbolPrivate();
|
||||
}
|
||||
|
||||
int getCompactUnwindEncoding(const std::vector<MCCFIInstruction> &Instrs,
|
||||
int DataAlignmentFactor, bool IsEH) const {
|
||||
return TFI->getCompactUnwindEncoding(Instrs, DataAlignmentFactor, IsEH);
|
||||
}
|
||||
|
||||
const unsigned *getCalleeSavedRegs(MachineFunction *MF = 0) const {
|
||||
return TRI->getCalleeSavedRegs(MF);
|
||||
}
|
||||
@ -106,10 +112,6 @@ public:
|
||||
int getSEHRegNum(unsigned RegNum) const {
|
||||
return TRI->getSEHRegNum(RegNum);
|
||||
}
|
||||
|
||||
int getCompactUnwindRegNum(unsigned RegNum, bool isEH) const {
|
||||
return TRI->getCompactUnwindRegNum(RegNum, isEH);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
#ifndef LLVM_TARGET_TARGETFRAMELOWERING_H
|
||||
#define LLVM_TARGET_TARGETFRAMELOWERING_H
|
||||
|
||||
#include "llvm/MC/MCDwarf.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
|
||||
#include <utility>
|
||||
@ -189,6 +190,14 @@ public:
|
||||
///
|
||||
virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
|
||||
}
|
||||
|
||||
/// getCompactUnwindEncoding - Get the compact unwind encoding for the
|
||||
/// function. Return 0 if the compact unwind isn't available.
|
||||
virtual uint32_t getCompactUnwindEncoding(const std::vector<MCCFIInstruction>&,
|
||||
int /*DataAlignmentFactor*/,
|
||||
bool /*IsEH*/) const {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -499,7 +499,6 @@ namespace {
|
||||
bool UsingCFI;
|
||||
bool IsEH;
|
||||
const MCSymbol *SectionStart;
|
||||
|
||||
public:
|
||||
FrameEmitterImpl(bool usingCFI, bool isEH, const MCSymbol *sectionStart) :
|
||||
CFAOffset(0), CIENum(0), UsingCFI(usingCFI), IsEH(isEH),
|
||||
@ -714,6 +713,11 @@ bool FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer,
|
||||
// .quad __gxx_personality
|
||||
// .quad except_tab1
|
||||
|
||||
uint32_t Encoding =
|
||||
TAI.getCompactUnwindEncoding(Frame.Instructions,
|
||||
getDataAlignmentFactor(Streamer), IsEH);
|
||||
if (!Encoding) return false;
|
||||
|
||||
Streamer.SwitchSection(TAI.getCompactUnwindSection());
|
||||
|
||||
// Range Start
|
||||
@ -728,12 +732,10 @@ bool FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer,
|
||||
if (VerboseAsm) Streamer.AddComment("Range Length");
|
||||
Streamer.EmitAbsValue(Range, 4);
|
||||
|
||||
// FIXME:
|
||||
// Compact Encoding
|
||||
const std::vector<MachineMove> &Moves = TAI.getInitialFrameState();
|
||||
uint32_t Encoding = 0;
|
||||
Size = getSizeForEncoding(Streamer, dwarf::DW_EH_PE_udata4);
|
||||
if (VerboseAsm) Streamer.AddComment("Compact Unwind Encoding");
|
||||
if (VerboseAsm) Streamer.AddComment(Twine("Compact Unwind Encoding: 0x") +
|
||||
Twine(llvm::utohexstr(Encoding)));
|
||||
Streamer.EmitIntValue(Encoding, Size);
|
||||
|
||||
// Personality Function
|
||||
@ -774,7 +776,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
|
||||
streamer.EmitLabel(sectionStart);
|
||||
CIENum++;
|
||||
|
||||
MCSymbol *sectionEnd = streamer.getContext().CreateTempSymbol();
|
||||
MCSymbol *sectionEnd = context.CreateTempSymbol();
|
||||
|
||||
// Length
|
||||
const MCExpr *Length = MakeStartMinusEndExpr(streamer, *sectionStart,
|
||||
|
@ -20,8 +20,9 @@ TargetAsmInfo::TargetAsmInfo(const TargetMachine &TM) {
|
||||
const TargetData &TD = *TM.getTargetData();
|
||||
IsLittleEndian = TD.isLittleEndian();
|
||||
PointerSize = TD.getPointerSize();
|
||||
const TargetFrameLowering &TFI = *TM.getFrameLowering();
|
||||
StackDir = TFI.getStackGrowthDirection();
|
||||
|
||||
TFI = TM.getFrameLowering();
|
||||
StackDir = TFI->getStackGrowthDirection();
|
||||
TRI = TM.getRegisterInfo();
|
||||
TFI.getInitialFrameState(InitialFrameState);
|
||||
TFI->getInitialFrameState(InitialFrameState);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
@ -1029,3 +1030,100 @@ X86FrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||
FrameIdx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t X86FrameLowering::
|
||||
getCompactUnwindEncoding(const std::vector<MCCFIInstruction> &Instrs,
|
||||
int DataAlignmentFactor, bool IsEH) const {
|
||||
uint32_t Encoding = 0;
|
||||
int CFAOffset = 0;
|
||||
const TargetRegisterInfo *TRI = TM.getRegisterInfo();
|
||||
SmallVector<unsigned, 8> SavedRegs;
|
||||
int FramePointerReg = -1;
|
||||
|
||||
for (std::vector<MCCFIInstruction>::const_iterator
|
||||
I = Instrs.begin(), E = Instrs.end(); I != E; ++I) {
|
||||
const MCCFIInstruction &Inst = *I;
|
||||
MCSymbol *Label = Inst.getLabel();
|
||||
|
||||
// Ignore invalid labels.
|
||||
if (Label && !Label->isDefined()) continue;
|
||||
|
||||
unsigned Operation = Inst.getOperation();
|
||||
if (Operation != MCCFIInstruction::Move &&
|
||||
Operation != MCCFIInstruction::RelMove)
|
||||
// FIXME: We can't handle this frame just yet.
|
||||
return 0;
|
||||
|
||||
const MachineLocation &Dst = Inst.getDestination();
|
||||
const MachineLocation &Src = Inst.getSource();
|
||||
const bool IsRelative = (Operation == MCCFIInstruction::RelMove);
|
||||
|
||||
if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
|
||||
if (Src.getReg() == MachineLocation::VirtualFP) {
|
||||
// DW_CFA_def_cfa_offset
|
||||
if (IsRelative)
|
||||
CFAOffset += Src.getOffset();
|
||||
else
|
||||
CFAOffset = -Src.getOffset();
|
||||
} // else DW_CFA_def_cfa
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Src.isReg() && Src.getReg() == MachineLocation::VirtualFP) {
|
||||
// DW_CFA_def_cfa_register
|
||||
FramePointerReg = Dst.getReg();
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned Reg = Src.getReg();
|
||||
int Offset = Dst.getOffset();
|
||||
if (IsRelative)
|
||||
Offset -= CFAOffset;
|
||||
Offset /= DataAlignmentFactor;
|
||||
|
||||
if (Offset < 0) {
|
||||
// FIXME: Handle?
|
||||
// DW_CFA_offset_extended_sf
|
||||
return 0;
|
||||
} else if (Reg < 64) {
|
||||
// DW_CFA_offset + Reg
|
||||
SavedRegs.push_back(Reg);
|
||||
} else {
|
||||
// FIXME: Handle?
|
||||
// DW_CFA_offset_extended
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
CFAOffset /= 4;
|
||||
|
||||
// Check if the offset is too big.
|
||||
if ((CFAOffset & 0xFF) != CFAOffset)
|
||||
return 0;
|
||||
|
||||
// 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;
|
||||
|
||||
int CURegNum = TRI->getCompactUnwindRegNum(*I, IsEH);
|
||||
if (CURegNum == -1) return 0;
|
||||
|
||||
Encoding |= (CURegNum & 0x7) << (Idx++ * 3);
|
||||
}
|
||||
|
||||
return Encoding;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#define X86_FRAMELOWERING_H
|
||||
|
||||
#include "X86Subtarget.h"
|
||||
#include "llvm/MC/MCDwarf.h"
|
||||
#include "llvm/Target/TargetFrameLowering.h"
|
||||
|
||||
namespace llvm {
|
||||
@ -58,6 +59,9 @@ public:
|
||||
|
||||
void getInitialFrameState(std::vector<MachineMove> &Moves) const;
|
||||
int getFrameIndexOffset(const MachineFunction &MF, int FI) const;
|
||||
|
||||
uint32_t getCompactUnwindEncoding(const std::vector<MCCFIInstruction> &Instrs,
|
||||
int DataAlignmentFactor, bool IsEH) const;
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
Loading…
Reference in New Issue
Block a user