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::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;
  }
}
예제 #2
0
void MIPrinter::print(const MCCFIInstruction &CFI,
                      const TargetRegisterInfo *TRI) {
  switch (CFI.getOperation()) {
  case MCCFIInstruction::OpSameValue:
    OS << ".cfi_same_value ";
    if (CFI.getLabel())
      OS << "<mcsymbol> ";
    printCFIRegister(CFI.getRegister(), OS, TRI);
    break;
  case MCCFIInstruction::OpOffset:
    OS << ".cfi_offset ";
    if (CFI.getLabel())
      OS << "<mcsymbol> ";
    printCFIRegister(CFI.getRegister(), OS, TRI);
    OS << ", " << CFI.getOffset();
    break;
  case MCCFIInstruction::OpDefCfaRegister:
    OS << ".cfi_def_cfa_register ";
    if (CFI.getLabel())
      OS << "<mcsymbol> ";
    printCFIRegister(CFI.getRegister(), OS, TRI);
    break;
  case MCCFIInstruction::OpDefCfaOffset:
    OS << ".cfi_def_cfa_offset ";
    if (CFI.getLabel())
      OS << "<mcsymbol> ";
    OS << CFI.getOffset();
    break;
  case MCCFIInstruction::OpDefCfa:
    OS << ".cfi_def_cfa ";
    if (CFI.getLabel())
      OS << "<mcsymbol> ";
    printCFIRegister(CFI.getRegister(), OS, TRI);
    OS << ", " << CFI.getOffset();
    break;
  default:
    // TODO: Print the other CFI Operations.
    OS << "<unserializable cfi operation>";
    break;
  }
}
예제 #3
0
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;
  }
}
예제 #4
0
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");
}