#include "llvm/MC/MCSymbol.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
namespace {
class MCAsmStreamer : public MCStreamer {
+protected:
formatted_raw_ostream &OS;
const MCAsmInfo &MAI;
+private:
OwningPtr<MCInstPrinter> InstPrinter;
OwningPtr<MCCodeEmitter> Emitter;
OwningPtr<TargetAsmBackend> AsmBackend;
bool needsSet(const MCExpr *Value);
+ void EmitRegisterName(int64_t Register);
+
public:
MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os,
bool isVerboseAsm, bool useLoc, bool useCFI,
virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
- virtual void EmitWin64EHStartProc(MCSymbol *Symbol);
+ virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
virtual void EmitWin64EHEndProc();
virtual void EmitWin64EHStartChained();
virtual void EmitWin64EHEndChained();
EmitEOL();
}
+void MCAsmStreamer::EmitRegisterName(int64_t Register) {
+ if (InstPrinter && !MAI.useDwarfRegNumForCFI()) {
+ const TargetAsmInfo &asmInfo = getContext().getTargetAsmInfo();
+ unsigned LLVMRegister = asmInfo.getLLVMRegNum(Register, true);
+ InstPrinter->printRegName(OS, LLVMRegister);
+ } else {
+ OS << Register;
+ }
+}
+
void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
MCStreamer::EmitCFIDefCfa(Register, Offset);
if (!UseCFI)
return;
- OS << ".cfi_def_cfa " << Register << ", " << Offset;
+ OS << "\t.cfi_def_cfa ";
+ EmitRegisterName(Register);
+ OS << ", " << Offset;
EmitEOL();
}
if (!UseCFI)
return;
- OS << "\t.cfi_def_cfa_register " << Register;
+ OS << "\t.cfi_def_cfa_register ";
+ EmitRegisterName(Register);
EmitEOL();
}
if (!UseCFI)
return;
- OS << "\t.cfi_offset " << Register << ", " << Offset;
+ OS << "\t.cfi_offset ";
+ EmitRegisterName(Register);
+ OS << ", " << Offset;
EmitEOL();
}
if (!UseCFI)
return;
- OS << "\t.cfi_same_value " << Register;
+ OS << "\t.cfi_same_value ";
+ EmitRegisterName(Register);
EmitEOL();
}
if (!UseCFI)
return;
- OS << "\t.cfi_rel_offset " << Register << ", " << Offset;
+ OS << "\t.cfi_rel_offset ";
+ EmitRegisterName(Register);
+ OS << ", " << Offset;
EmitEOL();
}
EmitEOL();
}
-void MCAsmStreamer::EmitWin64EHStartProc(MCSymbol *Symbol) {
+void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
MCStreamer::EmitWin64EHStartProc(Symbol);
OS << ".seh_proc " << *Symbol;
void MCAsmStreamer::EmitWin64EHHandlerData() {
MCStreamer::EmitWin64EHHandlerData();
+ // Switch sections. Don't call SwitchSection directly, because that will
+ // cause the section switch to be visible in the emitted assembly.
+ // We only do this so the section switch that terminates the handler
+ // data block is visible.
+ MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
+ StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function);
+ const MCSection *xdataSect =
+ getContext().getTargetAsmInfo().getWin64EHTableSection(suffix);
+ if (xdataSect)
+ SwitchSectionNoChange(xdataSect);
+
OS << "\t.seh_handlerdata";
EmitEOL();
}
}
}
- // FIXME: Node the fixup comments for Thumb2 are completely bogus since the
+ // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
// high order halfword of a 32-bit Thumb2 instruction is emitted first.
OS << "encoding: [";
for (unsigned i = 0, e = Code.size(); i != e; ++i) {
}
void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
- OS << "\t.setfp\t" << InstPrinter->getRegName(FpReg)
- << ", " << InstPrinter->getRegName(SpReg);
+ OS << "\t.setfp\t";
+ InstPrinter->printRegName(OS, FpReg);
+ OS << ", ";
+ InstPrinter->printRegName(OS, SpReg);
if (Offset)
OS << ", #" << Offset;
EmitEOL();
else
OS << "\t.save\t{";
- OS << InstPrinter->getRegName(RegList[0]);
+ InstPrinter->printRegName(OS, RegList[0]);
- for (unsigned i = 1, e = RegList.size(); i != e; ++i)
- OS << ", " << InstPrinter->getRegName(RegList[i]);
+ for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
+ OS << ", ";
+ InstPrinter->printRegName(OS, RegList[i]);
+ }
OS << "}";
EmitEOL();
if (!UseCFI)
EmitFrames(false);
}
-
MCStreamer *llvm::createAsmStreamer(MCContext &Context,
formatted_raw_ostream &OS,
bool isVerboseAsm, bool useLoc,
- bool useCFI,
- MCInstPrinter *IP, MCCodeEmitter *CE,
- TargetAsmBackend *TAB, bool ShowInst) {
+ bool useCFI, MCInstPrinter *IP,
+ MCCodeEmitter *CE, TargetAsmBackend *TAB,
+ bool ShowInst) {
return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI,
IP, CE, TAB, ShowInst);
}