diff options
Diffstat (limited to 'lib/MC/MCDwarf.cpp')
-rw-r--r-- | lib/MC/MCDwarf.cpp | 110 |
1 files changed, 68 insertions, 42 deletions
diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp index 96ba69aaea..93a447ceae 100644 --- a/lib/MC/MCDwarf.cpp +++ b/lib/MC/MCDwarf.cpp @@ -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 @@ static int getDataAlignmentFactor(MCStreamer &streamer) { 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 @@ static const MCSymbol &EmitCIE(MCStreamer &streamer, // 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 @@ static MCSymbol *EmitFDE(MCStreamer &streamer, streamer.EmitLabel(augmentationEnd); // Call Frame Instructions - EmitFrameMoves(streamer, frame.Moves, frame.Begin, true); + EmitCFIInstructions(streamer, frame.Instructions, frame.Begin, true); // Padding streamer.EmitValueToAlignment(4); |