void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const { switch (Inst.getOperation()) { default: llvm_unreachable("Unexpected instruction"); case MCCFIInstruction::OpDefCfaOffset: OutStreamer->EmitCFIDefCfaOffset(Inst.getOffset()); break; case MCCFIInstruction::OpAdjustCfaOffset: OutStreamer->EmitCFIAdjustCfaOffset(Inst.getOffset()); break; case MCCFIInstruction::OpDefCfa: OutStreamer->EmitCFIDefCfa(Inst.getRegister(), Inst.getOffset()); break; case MCCFIInstruction::OpDefCfaRegister: OutStreamer->EmitCFIDefCfaRegister(Inst.getRegister()); break; case MCCFIInstruction::OpOffset: OutStreamer->EmitCFIOffset(Inst.getRegister(), Inst.getOffset()); break; case MCCFIInstruction::OpRegister: OutStreamer->EmitCFIRegister(Inst.getRegister(), Inst.getRegister2()); break; case MCCFIInstruction::OpWindowSave: OutStreamer->EmitCFIWindowSave(); break; case MCCFIInstruction::OpSameValue: OutStreamer->EmitCFISameValue(Inst.getRegister()); break; case MCCFIInstruction::OpGnuArgsSize: OutStreamer->EmitCFIGnuArgsSize(Inst.getOffset()); break; case MCCFIInstruction::OpEscape: OutStreamer->EmitCFIEscape(Inst.getValues()); break; } }
static void printCFI(raw_ostream &OS, const MCCFIInstruction &CFI, const TargetRegisterInfo *TRI) { switch (CFI.getOperation()) { case MCCFIInstruction::OpSameValue: OS << "same_value "; if (MCSymbol *Label = CFI.getLabel()) MachineOperand::printSymbol(OS, *Label); printCFIRegister(CFI.getRegister(), OS, TRI); break; case MCCFIInstruction::OpRememberState: OS << "remember_state "; if (MCSymbol *Label = CFI.getLabel()) MachineOperand::printSymbol(OS, *Label); break; case MCCFIInstruction::OpRestoreState: OS << "restore_state "; if (MCSymbol *Label = CFI.getLabel()) MachineOperand::printSymbol(OS, *Label); break; case MCCFIInstruction::OpOffset: OS << "offset "; if (MCSymbol *Label = CFI.getLabel()) MachineOperand::printSymbol(OS, *Label); printCFIRegister(CFI.getRegister(), OS, TRI); OS << ", " << CFI.getOffset(); break; case MCCFIInstruction::OpDefCfaRegister: OS << "def_cfa_register "; if (MCSymbol *Label = CFI.getLabel()) MachineOperand::printSymbol(OS, *Label); printCFIRegister(CFI.getRegister(), OS, TRI); break; case MCCFIInstruction::OpDefCfaOffset: OS << "def_cfa_offset "; if (MCSymbol *Label = CFI.getLabel()) MachineOperand::printSymbol(OS, *Label); OS << CFI.getOffset(); break; case MCCFIInstruction::OpDefCfa: OS << "def_cfa "; if (MCSymbol *Label = CFI.getLabel()) MachineOperand::printSymbol(OS, *Label); printCFIRegister(CFI.getRegister(), OS, TRI); OS << ", " << CFI.getOffset(); break; case MCCFIInstruction::OpRelOffset: OS << "rel_offset "; if (MCSymbol *Label = CFI.getLabel()) MachineOperand::printSymbol(OS, *Label); printCFIRegister(CFI.getRegister(), OS, TRI); OS << ", " << CFI.getOffset(); break; case MCCFIInstruction::OpAdjustCfaOffset: OS << "adjust_cfa_offset "; if (MCSymbol *Label = CFI.getLabel()) MachineOperand::printSymbol(OS, *Label); OS << CFI.getOffset(); break; case MCCFIInstruction::OpRestore: OS << "restore "; if (MCSymbol *Label = CFI.getLabel()) MachineOperand::printSymbol(OS, *Label); printCFIRegister(CFI.getRegister(), OS, TRI); break; case MCCFIInstruction::OpEscape: { OS << "escape "; if (MCSymbol *Label = CFI.getLabel()) MachineOperand::printSymbol(OS, *Label); if (!CFI.getValues().empty()) { size_t e = CFI.getValues().size() - 1; for (size_t i = 0; i < e; ++i) OS << format("0x%02x", uint8_t(CFI.getValues()[i])) << ", "; OS << format("0x%02x", uint8_t(CFI.getValues()[e])) << ", "; } break; } case MCCFIInstruction::OpUndefined: OS << "undefined "; if (MCSymbol *Label = CFI.getLabel()) MachineOperand::printSymbol(OS, *Label); printCFIRegister(CFI.getRegister(), OS, TRI); break; case MCCFIInstruction::OpRegister: OS << "register "; if (MCSymbol *Label = CFI.getLabel()) MachineOperand::printSymbol(OS, *Label); printCFIRegister(CFI.getRegister(), OS, TRI); OS << ", "; printCFIRegister(CFI.getRegister2(), OS, TRI); break; case MCCFIInstruction::OpWindowSave: OS << "window_save "; if (MCSymbol *Label = CFI.getLabel()) MachineOperand::printSymbol(OS, *Label); break; case MCCFIInstruction::OpNegateRAState: OS << "negate_ra_sign_state "; if (MCSymbol *Label = CFI.getLabel()) MachineOperand::printSymbol(OS, *Label); break; default: // TODO: Print the other CFI Operations. OS << "<unserializable cfi directive>"; break; } }
void EmitCFIInstruction(MCStreamer &Streamer, const MCCFIInstruction &Instr, int &CFAOffset, int DataAlignmentFactor) { // Same as MCDwarf::EmitCFIInstruction () // FIXME: Unify int dataAlignmentFactor = DataAlignmentFactor; bool VerboseAsm = Streamer.isVerboseAsm(); switch (Instr.getOperation()) { case MCCFIInstruction::OpWindowSave: { Streamer.EmitIntValue(dwarf::DW_CFA_GNU_window_save, 1); return; } case MCCFIInstruction::OpUndefined: { unsigned Reg = Instr.getRegister(); if (VerboseAsm) { Streamer.AddComment("DW_CFA_undefined"); Streamer.AddComment(Twine("Reg ") + Twine(Reg)); } Streamer.EmitIntValue(dwarf::DW_CFA_undefined, 1); Streamer.EmitULEB128IntValue(Reg); return; } case MCCFIInstruction::OpAdjustCfaOffset: case MCCFIInstruction::OpDefCfaOffset: { const bool IsRelative = Instr.getOperation() == MCCFIInstruction::OpAdjustCfaOffset; if (VerboseAsm) Streamer.AddComment("DW_CFA_def_cfa_offset"); Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_offset, 1); if (IsRelative) CFAOffset += Instr.getOffset(); else // The backends pass in a negative value, // then createDefCfaOffset () negates it CFAOffset = Instr.getOffset(); if (VerboseAsm) Streamer.AddComment(Twine("Offset " + Twine(CFAOffset))); Streamer.EmitULEB128IntValue(CFAOffset); return; } case MCCFIInstruction::OpDefCfa: { if (VerboseAsm) Streamer.AddComment("DW_CFA_def_cfa"); Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1); if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Instr.getRegister())); Streamer.EmitULEB128IntValue(Instr.getRegister()); // Backends pass a negative value to createDefCfa () which // negates it back CFAOffset = Instr.getOffset(); if (VerboseAsm) Streamer.AddComment(Twine("Offset " + Twine(CFAOffset))); Streamer.EmitULEB128IntValue(CFAOffset); return; } case MCCFIInstruction::OpDefCfaRegister: { if (VerboseAsm) Streamer.AddComment("DW_CFA_def_cfa_register"); Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1); if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Instr.getRegister())); Streamer.EmitULEB128IntValue(Instr.getRegister()); return; } case MCCFIInstruction::OpOffset: case MCCFIInstruction::OpRelOffset: { const bool IsRelative = Instr.getOperation() == MCCFIInstruction::OpRelOffset; unsigned Reg = Instr.getRegister(); int Offset = Instr.getOffset(); if (IsRelative) Offset -= CFAOffset; Offset = Offset / dataAlignmentFactor; if (Offset < 0) { if (VerboseAsm) Streamer.AddComment("DW_CFA_offset_extended_sf"); Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended_sf, 1); if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg)); Streamer.EmitULEB128IntValue(Reg); if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset)); Streamer.EmitSLEB128IntValue(Offset); } else if (Reg < 64) { if (VerboseAsm) Streamer.AddComment(Twine("DW_CFA_offset + Reg(") + Twine(Reg) + ")"); Streamer.EmitIntValue(dwarf::DW_CFA_offset + Reg, 1); if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset)); Streamer.EmitULEB128IntValue(Offset); } else { if (VerboseAsm) Streamer.AddComment("DW_CFA_offset_extended"); Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended, 1); if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg)); Streamer.EmitULEB128IntValue(Reg); if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset)); Streamer.EmitULEB128IntValue(Offset); } return; } case MCCFIInstruction::OpRememberState: if (VerboseAsm) Streamer.AddComment("DW_CFA_remember_state"); Streamer.EmitIntValue(dwarf::DW_CFA_remember_state, 1); return; case MCCFIInstruction::OpRestoreState: if (VerboseAsm) Streamer.AddComment("DW_CFA_restore_state"); Streamer.EmitIntValue(dwarf::DW_CFA_restore_state, 1); return; case MCCFIInstruction::OpSameValue: { unsigned Reg = Instr.getRegister(); if (VerboseAsm) Streamer.AddComment("DW_CFA_same_value"); Streamer.EmitIntValue(dwarf::DW_CFA_same_value, 1); if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg)); Streamer.EmitULEB128IntValue(Reg); return; } case MCCFIInstruction::OpRestore: { unsigned Reg = Instr.getRegister(); if (VerboseAsm) { Streamer.AddComment("DW_CFA_restore"); Streamer.AddComment(Twine("Reg ") + Twine(Reg)); } Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1); return; } case MCCFIInstruction::OpEscape: if (VerboseAsm) Streamer.AddComment("Escape bytes"); Streamer.EmitBytes(Instr.getValues()); return; case MCCFIInstruction::OpRegister: llvm_unreachable("Unhandled case in switch"); return; } llvm_unreachable("Unhandled case in switch"); }