[llvm-commits] [llvm] r122602 - in /llvm/trunk: include/llvm/MC/MCDwarf.h include/llvm/MC/MCStreamer.h lib/MC/MCDwarf.cpp lib/MC/MCParser/AsmParser.cpp lib/MC/MCStreamer.cpp test/MC/ELF/cfi-remember.s
Rafael Espindola
rafael.espindola at gmail.com
Tue Dec 28 10:36:23 PST 2010
Author: rafael
Date: Tue Dec 28 12:36:23 2010
New Revision: 122602
URL: http://llvm.org/viewvc/llvm-project?rev=122602&view=rev
Log:
Implement .cfi_remember_state and .cfi_restore_state.
Added:
llvm/trunk/test/MC/ELF/cfi-remember.s
Modified:
llvm/trunk/include/llvm/MC/MCDwarf.h
llvm/trunk/include/llvm/MC/MCStreamer.h
llvm/trunk/lib/MC/MCDwarf.cpp
llvm/trunk/lib/MC/MCParser/AsmParser.cpp
llvm/trunk/lib/MC/MCStreamer.cpp
Modified: llvm/trunk/include/llvm/MC/MCDwarf.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCDwarf.h?rev=122602&r1=122601&r2=122602&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCDwarf.h (original)
+++ llvm/trunk/include/llvm/MC/MCDwarf.h Tue Dec 28 12:36:23 2010
@@ -228,14 +228,39 @@
int64_t LineDelta, uint64_t AddrDelta);
};
+ class MCCFIInstruction {
+ public:
+ enum OpType { Remember, Restore, Move };
+ private:
+ OpType Operation;
+ MCSymbol *Label;
+ // Move to & from location.
+ MachineLocation Destination;
+ MachineLocation Source;
+ public:
+ MCCFIInstruction(OpType Op, MCSymbol *L)
+ : Operation(Op), Label(L) {
+ assert(Op == Remember || Op == Restore);
+ }
+ MCCFIInstruction(MCSymbol *L, const MachineLocation &D,
+ const MachineLocation &S)
+ : Operation(Move), Label(L), Destination(D), Source(S) {
+ }
+ OpType getOperation() const { return Operation; }
+ MCSymbol *getLabel() const { return Label; }
+ const MachineLocation &getDestination() const { return Destination; }
+ const MachineLocation &getSource() const { return Source; }
+ };
+
struct MCDwarfFrameInfo {
- MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0), Moves(),
- PersonalityEncoding(0), LsdaEncoding(0) {}
+ MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0),
+ Instructions(), PersonalityEncoding(0),
+ LsdaEncoding(0) {}
MCSymbol *Begin;
MCSymbol *End;
const MCSymbol *Personality;
const MCSymbol *Lsda;
- std::vector<MachineMove> Moves;
+ std::vector<MCCFIInstruction> Instructions;
unsigned PersonalityEncoding;
unsigned LsdaEncoding;
};
Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=122602&r1=122601&r2=122602&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCStreamer.h Tue Dec 28 12:36:23 2010
@@ -401,6 +401,8 @@
virtual bool EmitCFIPersonality(const MCSymbol *Sym,
unsigned Encoding);
virtual bool EmitCFILsda(const MCSymbol *Sym, unsigned Encoding);
+ virtual bool EmitCFIRememberState();
+ virtual bool EmitCFIRestoreState();
/// EmitInstruction - Emit the given @p Instruction into the current
/// section.
Modified: llvm/trunk/lib/MC/MCDwarf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=122602&r1=122601&r2=122602&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCDwarf.cpp (original)
+++ llvm/trunk/lib/MC/MCDwarf.cpp Tue Dec 28 12:36:23 2010
@@ -18,6 +18,7 @@
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetAsmBackend.h"
#include "llvm/Target/TargetAsmInfo.h"
@@ -438,71 +439,89 @@
return -size;
}
-/// EmitFrameMoves - Emit frame instructions to describe the layout of the
-/// frame.
-static void EmitFrameMoves(MCStreamer &streamer,
- const std::vector<MachineMove> &Moves,
- MCSymbol *BaseLabel, bool isEH) {
- MCContext &context = streamer.getContext();
+static void EmitCFIInstruction(MCStreamer &Streamer,
+ const MCCFIInstruction &Instr,
+ bool isEH) {
+ MCContext &context = Streamer.getContext();
const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
- int dataAlignmentFactor = getDataAlignmentFactor(streamer);
-
- for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
- const MachineMove &Move = Moves[i];
- MCSymbol *Label = Move.getLabel();
- // Throw out move if the label is invalid.
- if (Label && !Label->isDefined()) continue; // Not emitted, in dead code.
-
- const MachineLocation &Dst = Move.getDestination();
- const MachineLocation &Src = Move.getSource();
+ int dataAlignmentFactor = getDataAlignmentFactor(Streamer);
- // Advance row if new location.
- if (BaseLabel && Label) {
- MCSymbol *ThisSym = Label;
- if (ThisSym != BaseLabel) {
- streamer.EmitDwarfAdvanceFrameAddr(BaseLabel, ThisSym);
- BaseLabel = ThisSym;
- }
- }
+ switch (Instr.getOperation()) {
+ case MCCFIInstruction::Move: {
+ const MachineLocation &Dst = Instr.getDestination();
+ const MachineLocation &Src = Instr.getSource();
// If advancing cfa.
if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
assert(!Src.isReg() && "Machine move not supported yet.");
if (Src.getReg() == MachineLocation::VirtualFP) {
- streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_offset, 1);
+ Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_offset, 1);
} else {
- streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1);
- streamer.EmitULEB128IntValue(asmInfo.getDwarfRegNum(Src.getReg(),
+ Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1);
+ Streamer.EmitULEB128IntValue(asmInfo.getDwarfRegNum(Src.getReg(),
isEH));
}
- streamer.EmitULEB128IntValue(-Src.getOffset(), 1);
- continue;
+ Streamer.EmitULEB128IntValue(-Src.getOffset(), 1);
+ return;
}
if (Src.isReg() && Src.getReg() == MachineLocation::VirtualFP) {
assert(Dst.isReg() && "Machine move not supported yet.");
- streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1);
- streamer.EmitULEB128IntValue(asmInfo.getDwarfRegNum(Dst.getReg(), isEH));
- continue;
+ Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1);
+ Streamer.EmitULEB128IntValue(asmInfo.getDwarfRegNum(Dst.getReg(), isEH));
+ return;
}
unsigned Reg = asmInfo.getDwarfRegNum(Src.getReg(), isEH);
int Offset = Dst.getOffset() / dataAlignmentFactor;
if (Offset < 0) {
- streamer.EmitIntValue(dwarf::DW_CFA_offset_extended_sf, 1);
- streamer.EmitULEB128IntValue(Reg);
- streamer.EmitSLEB128IntValue(Offset);
+ Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended_sf, 1);
+ Streamer.EmitULEB128IntValue(Reg);
+ Streamer.EmitSLEB128IntValue(Offset);
} else if (Reg < 64) {
- streamer.EmitIntValue(dwarf::DW_CFA_offset + Reg, 1);
- streamer.EmitULEB128IntValue(Offset, 1);
+ Streamer.EmitIntValue(dwarf::DW_CFA_offset + Reg, 1);
+ Streamer.EmitULEB128IntValue(Offset, 1);
} else {
- streamer.EmitIntValue(dwarf::DW_CFA_offset_extended, 1);
- streamer.EmitULEB128IntValue(Reg, 1);
- streamer.EmitULEB128IntValue(Offset, 1);
+ Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended, 1);
+ Streamer.EmitULEB128IntValue(Reg, 1);
+ Streamer.EmitULEB128IntValue(Offset, 1);
+ }
+ return;
+ }
+ case MCCFIInstruction::Remember:
+ Streamer.EmitIntValue(dwarf::DW_CFA_remember_state, 1);
+ return;
+ case MCCFIInstruction::Restore:
+ Streamer.EmitIntValue(dwarf::DW_CFA_restore_state, 1);
+ return;
+ }
+ llvm_unreachable("Unhandled case in switch");
+}
+
+/// EmitFrameMoves - Emit frame instructions to describe the layout of the
+/// frame.
+static void EmitCFIInstructions(MCStreamer &streamer,
+ const std::vector<MCCFIInstruction> &Instrs,
+ MCSymbol *BaseLabel, bool isEH) {
+ for (unsigned i = 0, N = Instrs.size(); i < N; ++i) {
+ const MCCFIInstruction &Instr = Instrs[i];
+ MCSymbol *Label = Instr.getLabel();
+ // Throw out move if the label is invalid.
+ if (Label && !Label->isDefined()) continue; // Not emitted, in dead code.
+
+ // Advance row if new location.
+ if (BaseLabel && Label) {
+ MCSymbol *ThisSym = Label;
+ if (ThisSym != BaseLabel) {
+ streamer.EmitDwarfAdvanceFrameAddr(BaseLabel, ThisSym);
+ BaseLabel = ThisSym;
+ }
}
+
+ EmitCFIInstruction(streamer, Instr, isEH);
}
}
@@ -618,8 +637,15 @@
// Initial Instructions
const std::vector<MachineMove> Moves = asmInfo.getInitialFrameState();
+ std::vector<MCCFIInstruction> Instructions;
+
+ for (int i = 0, n = Moves.size(); i != n; ++i) {
+ MCCFIInstruction Inst(Moves[i].getLabel(), Moves[i].getDestination(),
+ Moves[i].getSource());
+ Instructions.push_back(Inst);
+ }
- EmitFrameMoves(streamer, Moves, NULL, true);
+ EmitCFIInstructions(streamer, Instructions, NULL, true);
// Padding
streamer.EmitValueToAlignment(4);
@@ -668,7 +694,7 @@
streamer.EmitLabel(augmentationEnd);
// Call Frame Instructions
- EmitFrameMoves(streamer, frame.Moves, frame.Begin, true);
+ EmitCFIInstructions(streamer, frame.Instructions, frame.Begin, true);
// Padding
streamer.EmitValueToAlignment(4);
Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=122602&r1=122601&r2=122602&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Tue Dec 28 12:36:23 2010
@@ -254,6 +254,10 @@
&GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda>(".cfi_personality");
AddDirectiveHandler<
&GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda>(".cfi_lsda");
+ AddDirectiveHandler<
+ &GenericAsmParser::ParseDirectiveCFIRememberState>(".cfi_remember_state");
+ AddDirectiveHandler<
+ &GenericAsmParser::ParseDirectiveCFIRestoreState>(".cfi_restore_state");
// Macro directives.
AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacrosOnOff>(
@@ -278,6 +282,8 @@
bool ParseDirectiveCFIDefCfaRegister(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveCFIPersonalityOrLsda(StringRef, SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIRememberState(StringRef, SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIRestoreState(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveMacrosOnOff(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveMacro(StringRef, SMLoc DirectiveLoc);
@@ -2261,6 +2267,20 @@
}
}
+/// ParseDirectiveCFIRememberState
+/// ::= .cfi_remember_state
+bool GenericAsmParser::ParseDirectiveCFIRememberState(StringRef IDVal,
+ SMLoc DirectiveLoc) {
+ return getStreamer().EmitCFIRememberState();
+}
+
+/// ParseDirectiveCFIRestoreState
+/// ::= .cfi_remember_state
+bool GenericAsmParser::ParseDirectiveCFIRestoreState(StringRef IDVal,
+ SMLoc DirectiveLoc) {
+ return getStreamer().EmitCFIRestoreState();
+}
+
/// ParseDirectiveMacrosOnOff
/// ::= .macros_on
/// ::= .macros_off
Modified: llvm/trunk/lib/MC/MCStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=122602&r1=122601&r2=122602&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCStreamer.cpp Tue Dec 28 12:36:23 2010
@@ -179,8 +179,8 @@
EmitLabel(Label);
MachineLocation Dest(MachineLocation::VirtualFP);
MachineLocation Source(MachineLocation::VirtualFP, -Offset);
- MachineMove Move(Label, Dest, Source);
- CurFrame->Moves.push_back(Move);
+ MCCFIInstruction Instruction(Label, Dest, Source);
+ CurFrame->Instructions.push_back(Instruction);
return false;
}
@@ -211,6 +211,27 @@
return false;
}
+bool MCStreamer::EmitCFIRememberState() {
+ EnsureValidFrame();
+ MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCSymbol *Label = getContext().CreateTempSymbol();
+ EmitLabel(Label);
+ MCCFIInstruction Instruction(MCCFIInstruction::Remember, Label);
+ CurFrame->Instructions.push_back(Instruction);
+ return false;
+}
+
+bool MCStreamer::EmitCFIRestoreState() {
+ // FIXME: Error if there is no matching cfi_remember_state.
+ EnsureValidFrame();
+ MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCSymbol *Label = getContext().CreateTempSymbol();
+ EmitLabel(Label);
+ MCCFIInstruction Instruction(MCCFIInstruction::Restore, Label);
+ CurFrame->Instructions.push_back(Instruction);
+ return false;
+}
+
/// EmitRawText - If this file is backed by an assembly streamer, this dumps
/// the specified string in the output .s file. This capability is
/// indicated by the hasRawTextSupport() predicate.
Added: llvm/trunk/test/MC/ELF/cfi-remember.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi-remember.s?rev=122602&view=auto
==============================================================================
--- llvm/trunk/test/MC/ELF/cfi-remember.s (added)
+++ llvm/trunk/test/MC/ELF/cfi-remember.s Tue Dec 28 12:36:23 2010
@@ -0,0 +1,45 @@
+// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump --dump-section-data | FileCheck %s
+
+f:
+ .cfi_startproc
+ nop
+ .cfi_remember_state
+ nop
+ .cfi_restore_state
+ nop
+ .cfi_endproc
+
+// CHECK: # Section 0x00000004
+// CHECK-NEXT: (('sh_name', 0x00000012) # '.eh_frame'
+// CHECK-NEXT: ('sh_type', 0x00000001)
+// CHECK-NEXT: ('sh_flags', 0x00000002)
+// CHECK-NEXT: ('sh_addr', 0x00000000)
+// CHECK-NEXT: ('sh_offset', 0x00000048)
+// CHECK-NEXT: ('sh_size', 0x00000030)
+// CHECK-NEXT: ('sh_link', 0x00000000)
+// CHECK-NEXT: ('sh_info', 0x00000000)
+// CHECK-NEXT: ('sh_addralign', 0x00000008)
+// CHECK-NEXT: ('sh_entsize', 0x00000000)
+// CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 14000000 1c000000 00000000 03000000 00410a41 0b000000')
+// CHECK-NEXT: ),
+
+// CHECK: # Section 0x00000008
+// CHECK-NEXT: (('sh_name', 0x00000036) # '.rela.eh_frame'
+// CHECK-NEXT: ('sh_type', 0x00000004)
+// CHECK-NEXT: ('sh_flags', 0x00000000)
+// CHECK-NEXT: ('sh_addr', 0x00000000)
+// CHECK-NEXT: ('sh_offset', 0x00000158)
+// CHECK-NEXT: ('sh_size', 0x00000018)
+// CHECK-NEXT: ('sh_link', 0x00000006)
+// CHECK-NEXT: ('sh_info', 0x00000004)
+// CHECK-NEXT: ('sh_addralign', 0x00000008)
+// CHECK-NEXT: ('sh_entsize', 0x00000018)
+// CHECK-NEXT: ('_relocations', [
+// CHECK-NEXT: # Relocation 0x00000000
+// CHECK-NEXT: (('r_offset', 0x00000020)
+// CHECK-NEXT: ('r_sym', 0x00000002)
+// CHECK-NEXT: ('r_type', 0x00000002)
+// CHECK-NEXT: ('r_addend', 0x00000000)
+// CHECK-NEXT: ),
+// CHECK-NEXT: ])
+// CHECK-NEXT: ),
More information about the llvm-commits
mailing list