Add code to emit the case, keep and segment start/end directives in the output assembly file. Indent the instructions as ORCA/M expects.

This commit is contained in:
Jeremy Rand 2016-04-20 23:48:48 -04:00
parent f0e0e4ec4a
commit 48276b8f1f
3 changed files with 101 additions and 3 deletions

View File

@ -6,7 +6,9 @@
// Copyright © 2016 Jeremy Rand. All rights reserved.
//
#include "WDC65816.h"
#include "WDC65816TargetStreamer.h"
#include "llvm/Support/FormattedStream.h"
using namespace llvm;
@ -20,3 +22,52 @@ WDC65816TargetAsmStreamer::~WDC65816TargetAsmStreamer()
{
}
StringRef &WDC65816TargetAsmStreamer::trimFilename(StringRef &filename)
{
size_t lastSlash = filename.find_last_of('/');
if (lastSlash != StringRef::npos) {
filename = filename.drop_front(lastSlash + 1);
}
size_t lastPeriod = filename.find_last_of('.');
if (lastPeriod != StringRef::npos) {
filename = filename.substr(0, lastPeriod);
}
return filename;
}
void WDC65816TargetAsmStreamer::EmitCaseDirective(void)
{
OS << indent;
OS << "case on";
OS << '\n';
}
void WDC65816TargetAsmStreamer::EmitKeepDirective(StringRef filename)
{
OS << indent;
OS << "keep ";
OS << trimFilename(filename);
OS << '\n';
}
void WDC65816TargetAsmStreamer::EmitSegStartDirective(StringRef filename)
{
OS << trimFilename(filename);
OS << "seg start";
OS << '\n';
}
void WDC65816TargetAsmStreamer::EmitSegEndDirective(void)
{
OS << indent;
OS << "end";
OS << '\n';
}

View File

@ -20,14 +20,26 @@ namespace llvm {
virtual void anchor();
public:
// Add pure virtual functions here to the base class...
virtual void EmitCaseDirective(void) = 0;
virtual void EmitKeepDirective(StringRef filename) = 0;
virtual void EmitSegStartDirective(StringRef filename) = 0;
virtual void EmitSegEndDirective(void) = 0;
};
class WDC65816TargetAsmStreamer : public WDC65816TargetStreamer {
formatted_raw_ostream &OS;
StringRef indent;
StringRef &trimFilename(StringRef &filename);
public:
WDC65816TargetAsmStreamer(formatted_raw_ostream &OS) : OS(OS) {}
WDC65816TargetAsmStreamer(formatted_raw_ostream &OS) : OS(OS), indent(" ") {}
virtual ~WDC65816TargetAsmStreamer();
virtual void EmitCaseDirective(void);
virtual void EmitKeepDirective(StringRef filename);
virtual void EmitSegStartDirective(StringRef filename);
virtual void EmitSegEndDirective(void);
};
}

View File

@ -17,20 +17,25 @@
#include "WDC65816InstrInfo.h"
#include "WDC65816TargetMachine.h"
#include "MCTargetDesc/WDC65816BaseInfo.h"
#include "MCTargetDesc/WDC65816TargetStreamer.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/Mangler.h"
using namespace llvm;
namespace {
class WDC65816AsmPrinter : public AsmPrinter {
WDC65816TargetStreamer &getTargetStreamer();
public:
explicit WDC65816AsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
: AsmPrinter(TM, Streamer) {}
@ -48,11 +53,17 @@ namespace {
static const char *getRegisterName(unsigned RegNo);
virtual void EmitStartOfAsmFile(Module &module);
virtual void EmitEndOfAsmFile(Module &module);
virtual void EmitInstruction(const MachineInstr *MI) {
SmallString<128> Str;
raw_svector_ostream OS(Str);
printInstruction(MI, OS);
OutStreamer.EmitRawText(OS.str());
StringRef instrString = OS.str().ltrim();
OutStreamer.EmitRawText(" " + instrString);
}
};
@ -61,6 +72,30 @@ namespace {
#include "WDC65816GenAsmWriter.inc"
WDC65816TargetStreamer &WDC65816AsmPrinter::getTargetStreamer() {
return static_cast<WDC65816TargetStreamer &>(OutStreamer.getTargetStreamer());
}
void WDC65816AsmPrinter::EmitStartOfAsmFile(Module &module)
{
WDC65816TargetStreamer &streamer = getTargetStreamer();
streamer.EmitCaseDirective();
streamer.EmitKeepDirective(module.getModuleIdentifier());
streamer.EmitSegStartDirective(module.getModuleIdentifier());
}
void WDC65816AsmPrinter::EmitEndOfAsmFile(Module &module)
{
WDC65816TargetStreamer &streamer = getTargetStreamer();
streamer.EmitSegEndDirective();
}
void WDC65816AsmPrinter::printOperand(const MachineInstr *MI, int opNum,
raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(opNum);