summaryrefslogtreecommitdiffstats
path: root/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp')
-rw-r--r--lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp149
1 files changed, 115 insertions, 34 deletions
diff --git a/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp b/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
index 11ac931..145359f 100644
--- a/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
+++ b/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
@@ -22,6 +22,7 @@
#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"
@@ -70,9 +71,6 @@ namespace {
void printSrcMemOperand(const MachineInstr *MI, int OpNum,
const char* Modifier = 0);
void printCCOperand(const MachineInstr *MI, int OpNum);
- void printInstruction(const MachineInstr *MI); // autogenerated.
- static const char *getRegisterName(unsigned RegNo);
-
void printMachineInstruction(const MachineInstr * MI);
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant,
@@ -82,13 +80,10 @@ namespace {
const char *ExtraCode);
void printInstructionThroughMCStreamer(const MachineInstr *MI);
+ void PrintGlobalVariable(const GlobalVariable* GVar);
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();
@@ -96,8 +91,89 @@ namespace {
};
} // end of anonymous namespace
-#include "MSP430GenAsmWriter.inc"
+void MSP430AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
+ if (!GVar->hasInitializer())
+ return; // External global require no code
+
+ // Check to see if this is a special global used by LLVM, if so, emit it.
+ if (EmitSpecialLLVMGlobal(GVar))
+ return;
+
+ const TargetData *TD = TM.getTargetData();
+
+ std::string name = Mang->getMangledName(GVar);
+ Constant *C = GVar->getInitializer();
+ unsigned Size = TD->getTypeAllocSize(C->getType());
+ unsigned Align = TD->getPreferredAlignmentLog(GVar);
+
+ printVisibility(name, GVar->getVisibility());
+
+ O << "\t.type\t" << name << ",@object\n";
+
+ OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
+ TM));
+
+ if (C->isNullValue() && !GVar->hasSection() &&
+ !GVar->isThreadLocal() &&
+ (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
+
+ if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
+
+ if (GVar->hasLocalLinkage())
+ O << "\t.local\t" << name << '\n';
+
+ O << MAI->getCOMMDirective() << name << ',' << Size;
+ if (MAI->getCOMMDirectiveTakesAlignment())
+ O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
+
+ if (VerboseAsm) {
+ O.PadToColumn(MAI->getCommentColumn());
+ O << MAI->getCommentString() << ' ';
+ WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
+ }
+ O << '\n';
+ return;
+ }
+
+ switch (GVar->getLinkage()) {
+ case GlobalValue::CommonLinkage:
+ case GlobalValue::LinkOnceAnyLinkage:
+ case GlobalValue::LinkOnceODRLinkage:
+ case GlobalValue::WeakAnyLinkage:
+ case GlobalValue::WeakODRLinkage:
+ O << "\t.weak\t" << name << '\n';
+ break;
+ case GlobalValue::DLLExportLinkage:
+ case GlobalValue::AppendingLinkage:
+ // FIXME: appending linkage variables should go into a section of
+ // their name or something. For now, just emit them as external.
+ case GlobalValue::ExternalLinkage:
+ // If external or appending, declare as a global symbol
+ O << "\t.globl " << name << '\n';
+ // FALL THROUGH
+ case GlobalValue::PrivateLinkage:
+ case GlobalValue::LinkerPrivateLinkage:
+ case GlobalValue::InternalLinkage:
+ break;
+ default:
+ assert(0 && "Unknown linkage type!");
+ }
+
+ // Use 16-bit alignment by default to simplify bunch of stuff
+ EmitAlignment(Align, GVar);
+ O << name << ":";
+ if (VerboseAsm) {
+ O.PadToColumn(MAI->getCommentColumn());
+ O << MAI->getCommentString() << ' ';
+ WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
+ }
+ O << '\n';
+ EmitGlobalConstant(C);
+
+ if (MAI->hasDotTypeDotSizeDirective())
+ O << "\t.size\t" << name << ", " << Size << '\n';
+}
void MSP430AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
const Function *F = MF.getFunction();
@@ -161,14 +237,9 @@ void MSP430AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
processDebugLoc(MI, true);
- // Call the autogenerated instruction printer routines.
- if (EnableMCInst) {
- printInstructionThroughMCStreamer(MI);
- } else {
- printInstruction(MI);
- }
+ printInstructionThroughMCStreamer(MI);
- if (VerboseAsm && !MI->getDebugLoc().isUnknown())
+ if (VerboseAsm)
EmitComments(*MI);
O << '\n';
@@ -180,7 +251,7 @@ void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
const MachineOperand &MO = MI->getOperand(OpNum);
switch (MO.getType()) {
case MachineOperand::MO_Register:
- O << getRegisterName(MO.getReg());
+ O << MSP430InstPrinter::getRegisterName(MO.getReg());
return;
case MachineOperand::MO_Immediate:
if (!Modifier || strcmp(Modifier, "nohash"))
@@ -224,22 +295,23 @@ void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum,
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())
+ // Print displacement first
+ if (!Disp.isImm()) {
+ printOperand(MI, OpNum+1, "mem");
+ } else {
+ if (!Base.getReg())
+ O << '&';
+
+ printOperand(MI, OpNum+1, "nohash");
+ }
+
+
+ // Print register base field
+ if (Base.getReg()) {
+ O << '(';
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");
+ O << ')';
+ }
}
void MSP430AsmPrinter::printCCOperand(const MachineInstr *MI, int OpNum) {
@@ -294,8 +366,7 @@ bool MSP430AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
}
//===----------------------------------------------------------------------===//
-void MSP430AsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI)
-{
+void MSP430AsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI){
MSP430MCInstLower MCInstLowering(OutContext, *Mang, *this);
@@ -309,7 +380,6 @@ void MSP430AsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI)
printKill(MI);
return;
case TargetInstrInfo::INLINEASM:
- O << '\t';
printInlineAsm(MI);
return;
case TargetInstrInfo::IMPLICIT_DEF:
@@ -324,7 +394,18 @@ void MSP430AsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI)
printMCInst(&TmpInst);
}
+static MCInstPrinter *createMSP430MCInstPrinter(const Target &T,
+ unsigned SyntaxVariant,
+ const MCAsmInfo &MAI,
+ raw_ostream &O) {
+ if (SyntaxVariant == 0)
+ return new MSP430InstPrinter(O, MAI);
+ return 0;
+}
+
// Force static initialization.
extern "C" void LLVMInitializeMSP430AsmPrinter() {
RegisterAsmPrinter<MSP430AsmPrinter> X(TheMSP430Target);
+ TargetRegistry::RegisterMCInstPrinter(TheMSP430Target,
+ createMSP430MCInstPrinter);
}
OpenPOWER on IntegriCloud