forked from OSchip/llvm-project
Implements parsing and emitting of .cfi_window_save in MC.
llvm-svn: 191431
This commit is contained in:
parent
8b5773053b
commit
3816d43a9a
|
@ -290,7 +290,8 @@ public:
|
|||
OpEscape,
|
||||
OpRestore,
|
||||
OpUndefined,
|
||||
OpRegister
|
||||
OpRegister,
|
||||
OpWindowSave
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -364,6 +365,11 @@ public:
|
|||
return MCCFIInstruction(OpRegister, L, Register1, Register2);
|
||||
}
|
||||
|
||||
/// \brief .cfi_window_save SPARC register window is saved.
|
||||
static MCCFIInstruction createWindowSave(MCSymbol *L) {
|
||||
return MCCFIInstruction(OpWindowSave, L, 0, 0, "");
|
||||
}
|
||||
|
||||
/// \brief .cfi_restore says that the rule for Register is now the same as it
|
||||
/// was at the beginning of the function, after all initial instructions added
|
||||
/// by .cfi_startproc were executed.
|
||||
|
|
|
@ -578,6 +578,7 @@ public:
|
|||
virtual void EmitCFISignalFrame();
|
||||
virtual void EmitCFIUndefined(int64_t Register);
|
||||
virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);
|
||||
virtual void EmitCFIWindowSave();
|
||||
|
||||
virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
|
||||
virtual void EmitWin64EHEndProc();
|
||||
|
|
|
@ -185,5 +185,8 @@ void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
|
|||
case MCCFIInstruction::OpOffset:
|
||||
OutStreamer.EmitCFIOffset(Inst.getRegister(), Inst.getOffset());
|
||||
break;
|
||||
case MCCFIInstruction::OpWindowSave:
|
||||
OutStreamer.EmitCFIWindowSave();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -229,6 +229,7 @@ public:
|
|||
virtual void EmitCFISignalFrame();
|
||||
virtual void EmitCFIUndefined(int64_t Register);
|
||||
virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);
|
||||
virtual void EmitCFIWindowSave();
|
||||
|
||||
virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
|
||||
virtual void EmitWin64EHEndProc();
|
||||
|
@ -1098,6 +1099,16 @@ void MCAsmStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
|
|||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitCFIWindowSave() {
|
||||
MCStreamer::EmitCFIWindowSave();
|
||||
|
||||
if (!UseCFI)
|
||||
return;
|
||||
|
||||
OS << "\t.cfi_window_save";
|
||||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
|
||||
MCStreamer::EmitWin64EHStartProc(Symbol);
|
||||
|
||||
|
|
|
@ -959,6 +959,10 @@ void FrameEmitterImpl::EmitCFIInstruction(MCStreamer &Streamer,
|
|||
Streamer.EmitULEB128IntValue(Reg2);
|
||||
return;
|
||||
}
|
||||
case MCCFIInstruction::OpWindowSave: {
|
||||
Streamer.EmitIntValue(dwarf::DW_CFA_GNU_window_save, 1);
|
||||
return;
|
||||
}
|
||||
case MCCFIInstruction::OpUndefined: {
|
||||
unsigned Reg = Instr.getRegister();
|
||||
if (VerboseAsm) {
|
||||
|
|
|
@ -355,7 +355,7 @@ private:
|
|||
DK_CFI_OFFSET, DK_CFI_REL_OFFSET, DK_CFI_PERSONALITY, DK_CFI_LSDA,
|
||||
DK_CFI_REMEMBER_STATE, DK_CFI_RESTORE_STATE, DK_CFI_SAME_VALUE,
|
||||
DK_CFI_RESTORE, DK_CFI_ESCAPE, DK_CFI_SIGNAL_FRAME, DK_CFI_UNDEFINED,
|
||||
DK_CFI_REGISTER,
|
||||
DK_CFI_REGISTER, DK_CFI_WINDOW_SAVE,
|
||||
DK_MACROS_ON, DK_MACROS_OFF, DK_MACRO, DK_ENDM, DK_ENDMACRO, DK_PURGEM,
|
||||
DK_SLEB128, DK_ULEB128
|
||||
};
|
||||
|
@ -384,6 +384,7 @@ private:
|
|||
|
||||
// .cfi directives
|
||||
bool parseDirectiveCFIRegister(SMLoc DirectiveLoc);
|
||||
bool parseDirectiveCFIWindowSave();
|
||||
bool parseDirectiveCFISections();
|
||||
bool parseDirectiveCFIStartProc();
|
||||
bool parseDirectiveCFIEndProc();
|
||||
|
@ -1469,6 +1470,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) {
|
|||
return parseDirectiveCFIUndefined(IDLoc);
|
||||
case DK_CFI_REGISTER:
|
||||
return parseDirectiveCFIRegister(IDLoc);
|
||||
case DK_CFI_WINDOW_SAVE:
|
||||
return parseDirectiveCFIWindowSave();
|
||||
case DK_MACROS_ON:
|
||||
case DK_MACROS_OFF:
|
||||
return parseDirectiveMacrosOnOff(IDVal);
|
||||
|
@ -2827,6 +2830,13 @@ bool AsmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) {
|
|||
return false;
|
||||
}
|
||||
|
||||
/// parseDirectiveCFIWindowSave
|
||||
/// ::= .cfi_window_save
|
||||
bool AsmParser::parseDirectiveCFIWindowSave() {
|
||||
getStreamer().EmitCFIWindowSave();
|
||||
return false;
|
||||
}
|
||||
|
||||
/// parseDirectiveCFIAdjustCfaOffset
|
||||
/// ::= .cfi_adjust_cfa_offset adjustment
|
||||
bool AsmParser::parseDirectiveCFIAdjustCfaOffset() {
|
||||
|
@ -3820,6 +3830,7 @@ void AsmParser::initializeDirectiveKindMap() {
|
|||
DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
|
||||
DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED;
|
||||
DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
|
||||
DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
|
||||
DirectiveKindMap[".macros_on"] = DK_MACROS_ON;
|
||||
DirectiveKindMap[".macros_off"] = DK_MACROS_OFF;
|
||||
DirectiveKindMap[".macro"] = DK_MACRO;
|
||||
|
|
|
@ -399,6 +399,14 @@ void MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
|
|||
CurFrame->Instructions.push_back(Instruction);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFIWindowSave() {
|
||||
MCSymbol *Label = EmitCFICommon();
|
||||
MCCFIInstruction Instruction =
|
||||
MCCFIInstruction::createWindowSave(Label);
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
|
||||
CurFrame->Instructions.push_back(Instruction);
|
||||
}
|
||||
|
||||
void MCStreamer::setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame) {
|
||||
W64UnwindInfos.push_back(Frame);
|
||||
CurrentW64UnwindInfo = W64UnwindInfos.back();
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
# RUN: llvm-mc -filetype=asm -triple x86_64-pc-linux-gnu <%s | FileCheck %s
|
||||
|
||||
# Should use SPARC as the target to test this. However, SPARC does not support
|
||||
# asm parsing yet.
|
||||
|
||||
# CHECK: .cfi_window_save
|
||||
|
||||
|
||||
f:
|
||||
.cfi_startproc
|
||||
nop
|
||||
.cfi_window_save
|
||||
nop
|
||||
.cfi_endproc
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | llvm-readobj -s -sr -sd | FileCheck %s
|
||||
|
||||
# Should use SPARC as the target to test this. However, SPARC does not
|
||||
# use MC yet.
|
||||
|
||||
f:
|
||||
.cfi_startproc
|
||||
nop
|
||||
.cfi_window_save
|
||||
nop
|
||||
.cfi_endproc
|
||||
|
||||
// CHECK: Section {
|
||||
// CHECK: Name: .eh_frame
|
||||
// CHECK-NEXT: Type: SHT_PROGBITS
|
||||
// CHECK-NEXT: Flags [
|
||||
// CHECK-NEXT: SHF_ALLOC
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Address: 0x0
|
||||
// CHECK-NEXT: Offset: 0x48
|
||||
// CHECK-NEXT: Size: 48
|
||||
// CHECK-NEXT: Link: 0
|
||||
// CHECK-NEXT: Info: 0
|
||||
// CHECK-NEXT: AddressAlignment: 8
|
||||
// CHECK-NEXT: EntrySize: 0
|
||||
// CHECK-NEXT: Relocations [
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: SectionData (
|
||||
// CHECK-NEXT: 0000: 14000000 00000000 017A5200 01781001
|
||||
// CHECK-NEXT: 0010: 1B0C0708 90010000 14000000 1C000000
|
||||
// CHECK-NEXT: 0020: 00000000 02000000 00412D00 00000000
|
||||
// CHECK-NEXT: )
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: Section {
|
||||
// CHECK: Name: .rela.eh_frame
|
||||
// CHECK-NEXT: Type: SHT_RELA
|
||||
// CHECK-NEXT: Flags [
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Address: 0x0
|
||||
// CHECK-NEXT: Offset: 0x390
|
||||
// CHECK-NEXT: Size: 24
|
||||
// CHECK-NEXT: Link: 7
|
||||
// CHECK-NEXT: Info: 4
|
||||
// CHECK-NEXT: AddressAlignment: 8
|
||||
// CHECK-NEXT: EntrySize: 24
|
||||
// CHECK-NEXT: Relocations [
|
||||
// CHECK-NEXT: 0x20 R_X86_64_PC32 .text 0x0
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK: }
|
||||
|
Loading…
Reference in New Issue