--- /dev/null
+include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. )
+
+add_llvm_library(LLVMMSP430AsmPrinter
+ MSP430AsmPrinter.cpp
+ )
+add_dependencies(LLVMMSP430AsmPrinter MSP430CodeGenTable_gen)
--- /dev/null
+//===-- MSP430AsmPrinter.cpp - MSP430 LLVM assembly writer ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains a printer that converts from our internal representation
+// of machine-dependent LLVM code to the MSP430 assembly language.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "asm-printer"
+#include "MSP430.h"
+#include "MSP430InstrInfo.h"
+#include "MSP430TargetAsmInfo.h"
+#include "MSP430TargetMachine.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Module.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/TargetData.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/TargetRegistry.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/Mangler.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace llvm;
+
+STATISTIC(EmittedInsts, "Number of machine instrs printed");
+
+namespace {
+ class VISIBILITY_HIDDEN MSP430AsmPrinter : public AsmPrinter {
+ public:
+ MSP430AsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
+ const TargetAsmInfo *TAI, bool V)
+ : AsmPrinter(O, TM, TAI, V) {}
+
+ virtual const char *getPassName() const {
+ return "MSP430 Assembly Printer";
+ }
+
+ void printOperand(const MachineInstr *MI, int OpNum,
+ const char* Modifier = 0);
+ void printSrcMemOperand(const MachineInstr *MI, int OpNum,
+ const char* Modifier = 0);
+ void printCCOperand(const MachineInstr *MI, int OpNum);
+ void printInstruction(const MachineInstr *MI); // autogenerated.
+ void printMachineInstruction(const MachineInstr * MI);
+
+ void emitFunctionHeader(const MachineFunction &MF);
+ bool runOnMachineFunction(MachineFunction &F);
+
+ virtual void PrintGlobalVariable(const GlobalVariable *GV) {
+ // FIXME: No support for global variables?
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const {
+ AsmPrinter::getAnalysisUsage(AU);
+ AU.setPreservesAll();
+ }
+ };
+} // end of anonymous namespace
+
+#include "MSP430GenAsmWriter.inc"
+
+
+void MSP430AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
+ const Function *F = MF.getFunction();
+
+ SwitchToSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
+
+ unsigned FnAlign = MF.getAlignment();
+ EmitAlignment(FnAlign, F);
+
+ switch (F->getLinkage()) {
+ default: llvm_unreachable("Unknown linkage type!");
+ case Function::InternalLinkage: // Symbols default to internal.
+ case Function::PrivateLinkage:
+ case Function::LinkerPrivateLinkage:
+ break;
+ case Function::ExternalLinkage:
+ O << "\t.globl\t" << CurrentFnName << '\n';
+ break;
+ case Function::LinkOnceAnyLinkage:
+ case Function::LinkOnceODRLinkage:
+ case Function::WeakAnyLinkage:
+ case Function::WeakODRLinkage:
+ O << "\t.weak\t" << CurrentFnName << '\n';
+ break;
+ }
+
+ printVisibility(CurrentFnName, F->getVisibility());
+
+ O << "\t.type\t" << CurrentFnName << ",@function\n"
+ << CurrentFnName << ":\n";
+}
+
+bool MSP430AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
+ SetupMachineFunction(MF);
+ O << "\n\n";
+
+ // Print the 'header' of function
+ emitFunctionHeader(MF);
+
+ // Print out code for the function.
+ 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 {
+ printBasicBlockLabel(I, true, true, VerboseAsm);
+ O << '\n';
+ }
+
+ for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
+ II != E; ++II)
+ // Print the assembly for the instruction.
+ printMachineInstruction(II);
+ }
+
+ if (TAI->hasDotTypeDotSizeDirective())
+ O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n';
+
+ // We didn't modify anything
+ return false;
+}
+
+void MSP430AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
+ ++EmittedInsts;
+
+ // Call the autogenerated instruction printer routines.
+ printInstruction(MI);
+}
+
+void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
+ const char* Modifier) {
+ const MachineOperand &MO = MI->getOperand(OpNum);
+ switch (MO.getType()) {
+ case MachineOperand::MO_Register:
+ assert (TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
+ "Virtual registers should be already mapped!");
+ O << TM.getRegisterInfo()->get(MO.getReg()).AsmName;
+ return;
+ case MachineOperand::MO_Immediate:
+ if (!Modifier || strcmp(Modifier, "nohash"))
+ O << '#';
+ O << MO.getImm();
+ return;
+ case MachineOperand::MO_MachineBasicBlock:
+ printBasicBlockLabel(MO.getMBB());
+ 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!");
+
+ if (isCallOp)
+ O << '#';
+ else if (isMemOp)
+ O << '&';
+
+ O << Name;
+
+ return;
+ }
+ case MachineOperand::MO_ExternalSymbol: {
+ bool isCallOp = Modifier && !strcmp(Modifier, "call");
+ std::string Name(TAI->getGlobalPrefix());
+ Name += MO.getSymbolName();
+ if (isCallOp)
+ O << '#';
+ O << Name;
+ return;
+ }
+ default:
+ llvm_unreachable("Not implemented yet!");
+ }
+}
+
+void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum,
+ const char* Modifier) {
+ const MachineOperand &Base = MI->getOperand(OpNum);
+ const MachineOperand &Disp = MI->getOperand(OpNum+1);
+
+ if (Base.isGlobal())
+ printOperand(MI, OpNum, "mem");
+ else if (Disp.isImm() && !Base.getReg())
+ printOperand(MI, OpNum);
+ else if (Base.getReg()) {
+ if (Disp.getImm()) {
+ printOperand(MI, OpNum + 1, "nohash");
+ O << '(';
+ printOperand(MI, OpNum);
+ O << ')';
+ } else {
+ O << '@';
+ printOperand(MI, OpNum);
+ }
+ } else
+ llvm_unreachable("Unsupported memory operand");
+}
+
+void MSP430AsmPrinter::printCCOperand(const MachineInstr *MI, int OpNum) {
+ unsigned CC = MI->getOperand(OpNum).getImm();
+
+ switch (CC) {
+ default:
+ llvm_unreachable("Unsupported CC code");
+ break;
+ case MSP430::COND_E:
+ O << "eq";
+ break;
+ case MSP430::COND_NE:
+ O << "ne";
+ break;
+ case MSP430::COND_HS:
+ O << "hs";
+ break;
+ case MSP430::COND_LO:
+ O << "lo";
+ break;
+ case MSP430::COND_GE:
+ O << "ge";
+ break;
+ case MSP430::COND_L:
+ O << 'l';
+ break;
+ }
+}
+
+extern "C" void LLVMInitializeMSP430Target() {
+ // Register the target.
+ RegisterTargetMachine<MSP430TargetMachine> X(TheMSP430Target);
+ RegisterAsmPrinter<MSP430AsmPrinter> Y(TheMSP430Target);
+ RegisterAsmInfo<MSP430TargetAsmInfo> Z(TheMSP430Target);
+}
--- /dev/null
+##===- lib/Target/MSP430/Makefile --------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+LEVEL = ../../../..
+LIBRARYNAME = LLVMMSP430AsmPrinter
+
+# Hack: we need to include 'main' MSP430 target directory to grab private headers
+CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+
+include $(LEVEL)/Makefile.common
+++ /dev/null
-//===-- MSP430AsmPrinter.cpp - MSP430 LLVM assembly writer ----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains a printer that converts from our internal representation
-// of machine-dependent LLVM code to the MSP430 assembly language.
-//
-//===----------------------------------------------------------------------===//
-
-#define DEBUG_TYPE "asm-printer"
-#include "MSP430.h"
-#include "MSP430InstrInfo.h"
-#include "MSP430TargetAsmInfo.h"
-#include "MSP430TargetMachine.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Module.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/TargetData.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
-#include "llvm/Target/TargetRegistry.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
-#include "llvm/Support/ErrorHandling.h"
-
-using namespace llvm;
-
-STATISTIC(EmittedInsts, "Number of machine instrs printed");
-
-namespace {
- class VISIBILITY_HIDDEN MSP430AsmPrinter : public AsmPrinter {
- public:
- MSP430AsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- const TargetAsmInfo *TAI, bool V)
- : AsmPrinter(O, TM, TAI, V) {}
-
- virtual const char *getPassName() const {
- return "MSP430 Assembly Printer";
- }
-
- void printOperand(const MachineInstr *MI, int OpNum,
- const char* Modifier = 0);
- void printSrcMemOperand(const MachineInstr *MI, int OpNum,
- const char* Modifier = 0);
- void printCCOperand(const MachineInstr *MI, int OpNum);
- void printInstruction(const MachineInstr *MI); // autogenerated.
- void printMachineInstruction(const MachineInstr * MI);
-
- void emitFunctionHeader(const MachineFunction &MF);
- bool runOnMachineFunction(MachineFunction &F);
-
- virtual void PrintGlobalVariable(const GlobalVariable *GV) {
- // FIXME: No support for global variables?
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const {
- AsmPrinter::getAnalysisUsage(AU);
- AU.setPreservesAll();
- }
- };
-} // end of anonymous namespace
-
-#include "MSP430GenAsmWriter.inc"
-
-
-void MSP430AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
- const Function *F = MF.getFunction();
-
- SwitchToSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
-
- unsigned FnAlign = MF.getAlignment();
- EmitAlignment(FnAlign, F);
-
- switch (F->getLinkage()) {
- default: llvm_unreachable("Unknown linkage type!");
- case Function::InternalLinkage: // Symbols default to internal.
- case Function::PrivateLinkage:
- case Function::LinkerPrivateLinkage:
- break;
- case Function::ExternalLinkage:
- O << "\t.globl\t" << CurrentFnName << '\n';
- break;
- case Function::LinkOnceAnyLinkage:
- case Function::LinkOnceODRLinkage:
- case Function::WeakAnyLinkage:
- case Function::WeakODRLinkage:
- O << "\t.weak\t" << CurrentFnName << '\n';
- break;
- }
-
- printVisibility(CurrentFnName, F->getVisibility());
-
- O << "\t.type\t" << CurrentFnName << ",@function\n"
- << CurrentFnName << ":\n";
-}
-
-bool MSP430AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
- SetupMachineFunction(MF);
- O << "\n\n";
-
- // Print the 'header' of function
- emitFunctionHeader(MF);
-
- // Print out code for the function.
- 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 {
- printBasicBlockLabel(I, true, true, VerboseAsm);
- O << '\n';
- }
-
- for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
- II != E; ++II)
- // Print the assembly for the instruction.
- printMachineInstruction(II);
- }
-
- if (TAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n';
-
- // We didn't modify anything
- return false;
-}
-
-void MSP430AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
- ++EmittedInsts;
-
- // Call the autogenerated instruction printer routines.
- printInstruction(MI);
-}
-
-void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
- const char* Modifier) {
- const MachineOperand &MO = MI->getOperand(OpNum);
- switch (MO.getType()) {
- case MachineOperand::MO_Register:
- assert (TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
- "Virtual registers should be already mapped!");
- O << TM.getRegisterInfo()->get(MO.getReg()).AsmName;
- return;
- case MachineOperand::MO_Immediate:
- if (!Modifier || strcmp(Modifier, "nohash"))
- O << '#';
- O << MO.getImm();
- return;
- case MachineOperand::MO_MachineBasicBlock:
- printBasicBlockLabel(MO.getMBB());
- 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!");
-
- if (isCallOp)
- O << '#';
- else if (isMemOp)
- O << '&';
-
- O << Name;
-
- return;
- }
- case MachineOperand::MO_ExternalSymbol: {
- bool isCallOp = Modifier && !strcmp(Modifier, "call");
- std::string Name(TAI->getGlobalPrefix());
- Name += MO.getSymbolName();
- if (isCallOp)
- O << '#';
- O << Name;
- return;
- }
- default:
- llvm_unreachable("Not implemented yet!");
- }
-}
-
-void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum,
- const char* Modifier) {
- const MachineOperand &Base = MI->getOperand(OpNum);
- const MachineOperand &Disp = MI->getOperand(OpNum+1);
-
- if (Base.isGlobal())
- printOperand(MI, OpNum, "mem");
- else if (Disp.isImm() && !Base.getReg())
- printOperand(MI, OpNum);
- else if (Base.getReg()) {
- if (Disp.getImm()) {
- printOperand(MI, OpNum + 1, "nohash");
- O << '(';
- printOperand(MI, OpNum);
- O << ')';
- } else {
- O << '@';
- printOperand(MI, OpNum);
- }
- } else
- llvm_unreachable("Unsupported memory operand");
-}
-
-void MSP430AsmPrinter::printCCOperand(const MachineInstr *MI, int OpNum) {
- unsigned CC = MI->getOperand(OpNum).getImm();
-
- switch (CC) {
- default:
- llvm_unreachable("Unsupported CC code");
- break;
- case MSP430::COND_E:
- O << "eq";
- break;
- case MSP430::COND_NE:
- O << "ne";
- break;
- case MSP430::COND_HS:
- O << "hs";
- break;
- case MSP430::COND_LO:
- O << "lo";
- break;
- case MSP430::COND_GE:
- O << "ge";
- break;
- case MSP430::COND_L:
- O << 'l';
- break;
- }
-}
-
-extern "C" void LLVMInitializeMSP430Target() {
- // Register the target.
- RegisterTargetMachine<MSP430TargetMachine> X(TheMSP430Target);
- RegisterAsmPrinter<MSP430AsmPrinter> Y(TheMSP430Target);
- RegisterAsmInfo<MSP430TargetAsmInfo> Z(TheMSP430Target);
-}
#
##===----------------------------------------------------------------------===##
LEVEL = ../../..
-LIBRARYNAME = LLVMMSP430
+LIBRARYNAME = LLVMMSP430CodeGen
TARGET = MSP430
# Make sure that tblgen is run, first thing.
MSP430GenDAGISel.inc MSP430GenCallingConv.inc \
MSP430GenSubtarget.inc
-DIRS = TargetInfo
+DIRS = AsmPrinter TargetInfo
include $(LEVEL)/Makefile.common