#define DEBUG_TYPE "asm-printer"
#include "MSP430.h"
#include "MSP430InstrInfo.h"
+#include "MSP430InstPrinter.h"
#include "MSP430MCAsmInfo.h"
+#include "MSP430MCInstLower.h"
#include "MSP430TargetMachine.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Mangler.h"
STATISTIC(EmittedInsts, "Number of machine instrs printed");
+static cl::opt<bool>
+EnableMCInst("enable-msp430-mcinst-printer", cl::Hidden,
+ cl::desc("enable experimental mcinst gunk in the msp430 backend"));
+
namespace {
class VISIBILITY_HIDDEN MSP430AsmPrinter : public AsmPrinter {
public:
return "MSP430 Assembly Printer";
}
+ void printMCInst(const MCInst *MI) {
+ MSP430InstPrinter(O, *MAI).printInstruction(MI);
+ }
void printOperand(const MachineInstr *MI, int OpNum,
const char* Modifier = 0);
void printSrcMemOperand(const MachineInstr *MI, int OpNum,
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant,
const char *ExtraCode);
+ bool PrintAsmMemoryOperand(const MachineInstr *MI,
+ unsigned OpNo, unsigned AsmVariant,
+ const char *ExtraCode);
+ void printInstructionThroughMCStreamer(const MachineInstr *MI);
void emitFunctionHeader(const MachineFunction &MF);
bool runOnMachineFunction(MachineFunction &F);
for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
I != E; ++I) {
// Print a label for the basic block.
- if (!VerboseAsm && (I->pred_empty() || I->isOnlyReachableByFallthrough())) {
- // This is an entry block or a block that's only reachable via a
- // fallthrough edge. In non-VerboseAsm mode, don't print the label.
- } else {
- EmitBasicBlockStart(I);
- O << '\n';
- }
+ EmitBasicBlockStart(I);
for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
II != E; ++II)
void MSP430AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
++EmittedInsts;
- processDebugLoc(MI->getDebugLoc());
+ processDebugLoc(MI, true);
// Call the autogenerated instruction printer routines.
- printInstruction(MI);
-
+ if (EnableMCInst) {
+ printInstructionThroughMCStreamer(MI);
+ } else {
+ printInstruction(MI);
+ }
+
if (VerboseAsm && !MI->getDebugLoc().isUnknown())
EmitComments(*MI);
O << '\n';
+
+ processDebugLoc(MI, false);
}
void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
return;
case MachineOperand::MO_GlobalAddress: {
bool isMemOp = Modifier && !strcmp(Modifier, "mem");
- bool isCallOp = Modifier && !strcmp(Modifier, "call");
std::string Name = Mang->getMangledName(MO.getGlobal());
- assert(MO.getOffset() == 0 && "No offsets allowed!");
+ uint64_t Offset = MO.getOffset();
- if (isCallOp)
- O << '#';
- else if (isMemOp)
- O << '&';
+ O << (isMemOp ? '&' : '#');
+ if (Offset)
+ O << '(' << Offset << '+';
O << Name;
+ if (Offset)
+ O << ')';
return;
}
case MachineOperand::MO_ExternalSymbol: {
- bool isCallOp = Modifier && !strcmp(Modifier, "call");
+ bool isMemOp = Modifier && !strcmp(Modifier, "mem");
std::string Name(MAI->getGlobalPrefix());
Name += MO.getSymbolName();
- if (isCallOp)
- O << '#';
- O << Name;
+
+ O << (isMemOp ? '&' : '#') << Name;
+
return;
}
default:
return false;
}
+bool MSP430AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
+ unsigned OpNo, unsigned AsmVariant,
+ const char *ExtraCode) {
+ if (ExtraCode && ExtraCode[0]) {
+ return true; // Unknown modifier.
+ }
+ printSrcMemOperand(MI, OpNo);
+ return false;
+}
+
+//===----------------------------------------------------------------------===//
+void MSP430AsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI)
+{
+
+ MSP430MCInstLower MCInstLowering(OutContext, Mang);
+
+ switch (MI->getOpcode()) {
+ case TargetInstrInfo::DBG_LABEL:
+ case TargetInstrInfo::EH_LABEL:
+ case TargetInstrInfo::GC_LABEL:
+ printLabel(MI);
+ return;
+ case TargetInstrInfo::KILL:
+ return;
+ case TargetInstrInfo::INLINEASM:
+ O << '\t';
+ printInlineAsm(MI);
+ return;
+ case TargetInstrInfo::IMPLICIT_DEF:
+ printImplicitDef(MI);
+ return;
+ default: break;
+ }
+
+ MCInst TmpInst;
+ MCInstLowering.Lower(MI, TmpInst);
+
+ printMCInst(&TmpInst);
+}
+
// Force static initialization.
extern "C" void LLVMInitializeMSP430AsmPrinter() {
RegisterAsmPrinter<MSP430AsmPrinter> X(TheMSP430Target);