-//===-- MSP430AsmPrinter.cpp - MSP430 LLVM assembly writer ------------------===//
+//===-- MSP430AsmPrinter.cpp - MSP430 LLVM assembly writer ----------------===//
//
// The LLVM Compiler Infrastructure
//
#define DEBUG_TYPE "asm-printer"
#include "MSP430.h"
#include "MSP430InstrInfo.h"
+#include "MSP430MCInstLower.h"
#include "MSP430TargetMachine.h"
+#include "InstPrinter/MSP430InstPrinter.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
+#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/Target/TargetAsmInfo.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Mangler.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/Target/Mangler.h"
+#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
-
using namespace llvm;
-STATISTIC(EmittedInsts, "Number of machine instrs printed");
-
namespace {
- class VISIBILITY_HIDDEN MSP430AsmPrinter : public AsmPrinter {
+ class MSP430AsmPrinter : public AsmPrinter {
public:
- MSP430AsmPrinter(raw_ostream &O, MSP430TargetMachine &TM,
- const TargetAsmInfo *TAI, bool Fast, bool Verbose)
- : AsmPrinter(O, TM, TAI, Fast, Verbose) {}
+ MSP430AsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
+ : AsmPrinter(TM, Streamer) {}
virtual const char *getPassName() const {
return "MSP430 Assembly Printer";
}
- bool printInstruction(const MachineInstr *MI); // autogenerated.
- void printMachineInstruction(const MachineInstr * MI);
- bool runOnMachineFunction(MachineFunction &F);
- bool doInitialization(Module &M);
- bool doFinalization(Module &M);
-
- void getAnalysisUsage(AnalysisUsage &AU) const {
- AsmPrinter::getAnalysisUsage(AU);
- AU.setPreservesAll();
- }
+ void printOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O, const char* Modifier = 0);
+ void printSrcMemOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O);
+ bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O);
+ bool PrintAsmMemoryOperand(const MachineInstr *MI,
+ unsigned OpNo, unsigned AsmVariant,
+ const char *ExtraCode, raw_ostream &O);
+ void EmitInstruction(const MachineInstr *MI);
};
} // end of anonymous namespace
-#include "MSP430GenAsmWriter.inc"
-/// createMSP430CodePrinterPass - Returns a pass that prints the MSP430
-/// assembly code for a MachineFunction to the given output stream,
-/// using the given target machine description. This should work
-/// regardless of whether the function is in SSA form.
-///
-FunctionPass *llvm::createMSP430CodePrinterPass(raw_ostream &o,
- MSP430TargetMachine &tm,
- bool fast, bool verbose) {
- return new MSP430AsmPrinter(o, tm, tm.getTargetAsmInfo(), fast, verbose);
-}
+void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O, const char *Modifier) {
+ const MachineOperand &MO = MI->getOperand(OpNum);
+ switch (MO.getType()) {
+ default: assert(0 && "Not implemented yet!");
+ case MachineOperand::MO_Register:
+ O << MSP430InstPrinter::getRegisterName(MO.getReg());
+ return;
+ case MachineOperand::MO_Immediate:
+ if (!Modifier || strcmp(Modifier, "nohash"))
+ O << '#';
+ O << MO.getImm();
+ return;
+ case MachineOperand::MO_MachineBasicBlock:
+ O << *MO.getMBB()->getSymbol();
+ return;
+ case MachineOperand::MO_GlobalAddress: {
+ bool isMemOp = Modifier && !strcmp(Modifier, "mem");
+ uint64_t Offset = MO.getOffset();
+
+ // If the global address expression is a part of displacement field with a
+ // register base, we should not emit any prefix symbol here, e.g.
+ // mov.w &foo, r1
+ // vs
+ // mov.w glb(r1), r2
+ // Otherwise (!) msp430-as will silently miscompile the output :(
+ if (!Modifier || strcmp(Modifier, "nohash"))
+ O << (isMemOp ? '&' : '#');
+ if (Offset)
+ O << '(' << Offset << '+';
+
+ O << *Mang->getSymbol(MO.getGlobal());
+
+ if (Offset)
+ O << ')';
-bool MSP430AsmPrinter::doInitialization(Module &M) {
- Mang = new Mangler(M, "", TAI->getPrivateGlobalPrefix());
- return false; // success
+ return;
+ }
+ case MachineOperand::MO_ExternalSymbol: {
+ bool isMemOp = Modifier && !strcmp(Modifier, "mem");
+ O << (isMemOp ? '&' : '#');
+ O << MAI->getGlobalPrefix() << MO.getSymbolName();
+ return;
+ }
+ }
}
+void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {
+ const MachineOperand &Base = MI->getOperand(OpNum);
+ const MachineOperand &Disp = MI->getOperand(OpNum+1);
+
+ // Print displacement first
+
+ // Imm here is in fact global address - print extra modifier.
+ if (Disp.isImm() && !Base.getReg())
+ O << '&';
+ printOperand(MI, OpNum+1, O, "nohash");
+
+ // Print register base field
+ if (Base.getReg()) {
+ O << '(';
+ printOperand(MI, OpNum, O);
+ O << ')';
+ }
+}
-bool MSP430AsmPrinter::doFinalization(Module &M) {
- return AsmPrinter::doFinalization(M);
+/// PrintAsmOperand - Print out an operand for an inline asm expression.
+///
+bool MSP430AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant,
+ const char *ExtraCode, raw_ostream &O) {
+ // Does this asm operand have a single letter operand modifier?
+ if (ExtraCode && ExtraCode[0])
+ return true; // Unknown modifier.
+
+ printOperand(MI, OpNo, O);
+ return false;
}
-bool MSP430AsmPrinter::runOnMachineFunction(MachineFunction &F) {
- // We didn't modify anything
+bool MSP430AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
+ unsigned OpNo, unsigned AsmVariant,
+ const char *ExtraCode,
+ raw_ostream &O) {
+ if (ExtraCode && ExtraCode[0]) {
+ return true; // Unknown modifier.
+ }
+ printSrcMemOperand(MI, OpNo, O);
return false;
}
-void MSP430AsmPrinter::printMachineInstruction(const MachineInstr * MI) {
- ++EmittedInsts;
+//===----------------------------------------------------------------------===//
+void MSP430AsmPrinter::EmitInstruction(const MachineInstr *MI) {
+ MSP430MCInstLower MCInstLowering(OutContext, *Mang, *this);
- // Call the autogenerated instruction printer routines.
- if (printInstruction(MI))
- return;
+ MCInst TmpInst;
+ MCInstLowering.Lower(MI, TmpInst);
+ OutStreamer.EmitInstruction(TmpInst);
+}
- assert(0 && "Should not happen");
+// Force static initialization.
+extern "C" void LLVMInitializeMSP430AsmPrinter() {
+ RegisterAsmPrinter<MSP430AsmPrinter> X(TheMSP430Target);
}