1 //===-- BlackfinAsmPrinter.cpp - Blackfin LLVM assembly writer ------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains a printer that converts from our internal representation
11 // of machine-dependent LLVM code to GAS-format BLACKFIN assembly language.
13 //===----------------------------------------------------------------------===//
15 #define DEBUG_TYPE "asm-printer"
17 #include "BlackfinInstrInfo.h"
18 #include "llvm/Constants.h"
19 #include "llvm/DerivedTypes.h"
20 #include "llvm/Module.h"
21 #include "llvm/CodeGen/AsmPrinter.h"
22 #include "llvm/CodeGen/DwarfWriter.h"
23 #include "llvm/CodeGen/MachineFunctionPass.h"
24 #include "llvm/CodeGen/MachineConstantPool.h"
25 #include "llvm/CodeGen/MachineInstr.h"
26 #include "llvm/MC/MCStreamer.h"
27 #include "llvm/MC/MCAsmInfo.h"
28 #include "llvm/MC/MCContext.h"
29 #include "llvm/MC/MCSymbol.h"
30 #include "llvm/Target/TargetData.h"
31 #include "llvm/Target/TargetLoweringObjectFile.h"
32 #include "llvm/Target/TargetRegistry.h"
33 #include "llvm/ADT/Statistic.h"
34 #include "llvm/ADT/SmallString.h"
35 #include "llvm/Support/ErrorHandling.h"
36 #include "llvm/Support/FormattedStream.h"
39 STATISTIC(EmittedInsts, "Number of machine instrs printed");
42 class BlackfinAsmPrinter : public AsmPrinter {
44 BlackfinAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
45 const MCAsmInfo *MAI, bool V)
46 : AsmPrinter(O, TM, MAI, V) {}
48 virtual const char *getPassName() const {
49 return "Blackfin Assembly Printer";
52 void printOperand(const MachineInstr *MI, int opNum);
53 void printMemoryOperand(const MachineInstr *MI, int opNum);
54 void printInstruction(const MachineInstr *MI); // autogenerated.
55 static const char *getRegisterName(unsigned RegNo);
57 void emitLinkage(const MCSymbol *GVSym, GlobalValue::LinkageTypes l);
58 bool runOnMachineFunction(MachineFunction &F);
59 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
60 unsigned AsmVariant, const char *ExtraCode);
61 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
62 unsigned AsmVariant, const char *ExtraCode);
64 } // end of anonymous namespace
66 #include "BlackfinGenAsmWriter.inc"
68 extern "C" void LLVMInitializeBlackfinAsmPrinter() {
69 RegisterAsmPrinter<BlackfinAsmPrinter> X(TheBlackfinTarget);
72 void BlackfinAsmPrinter::emitLinkage(const MCSymbol *GVSym,
73 GlobalValue::LinkageTypes L) {
75 default: llvm_unreachable("Unknown linkage type!");
76 case GlobalValue::InternalLinkage: // Symbols default to internal.
77 case GlobalValue::PrivateLinkage:
78 case GlobalValue::LinkerPrivateLinkage:
80 case GlobalValue::ExternalLinkage:
81 O << MAI->getGlobalDirective() << *GVSym << "\n";
83 case GlobalValue::LinkOnceAnyLinkage:
84 case GlobalValue::LinkOnceODRLinkage:
85 case GlobalValue::WeakAnyLinkage:
86 case GlobalValue::WeakODRLinkage:
87 O << MAI->getGlobalDirective() << *GVSym << "\n";
88 O << MAI->getWeakDefDirective() << *GVSym << "\n";
93 /// runOnMachineFunction - This uses the printInstruction()
94 /// method to print assembly for each instruction.
96 bool BlackfinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
97 SetupMachineFunction(MF);
98 EmitConstantPool(MF.getConstantPool());
99 EmitJumpTableInfo(MF);
101 const Function *F = MF.getFunction();
102 OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
104 emitLinkage(CurrentFnSym, F->getLinkage());
105 printVisibility(CurrentFnSym, F->getVisibility());
107 O << "\t.type\t" << *CurrentFnSym << ", STT_FUNC\n";
108 O << *CurrentFnSym << ":\n";
111 DW->BeginFunction(&MF);
113 // Print out code for the function.
114 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
116 // Print a label for the basic block.
117 EmitBasicBlockStart(I);
119 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
121 // Print the assembly for the instruction.
122 processDebugLoc(II, true);
124 printInstruction(II);
129 processDebugLoc(II, false);
134 O << "\t.size " << *CurrentFnSym << ", .-" << *CurrentFnSym << "\n";
137 DW->EndFunction(&MF);
142 void BlackfinAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
143 const MachineOperand &MO = MI->getOperand (opNum);
144 switch (MO.getType()) {
145 case MachineOperand::MO_Register:
146 assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
147 "Virtual registers should be already mapped!");
148 O << getRegisterName(MO.getReg());
151 case MachineOperand::MO_Immediate:
154 case MachineOperand::MO_MachineBasicBlock:
155 O << *MO.getMBB()->getSymbol(OutContext);
157 case MachineOperand::MO_GlobalAddress:
158 O << *GetGlobalValueSymbol(MO.getGlobal());
159 printOffset(MO.getOffset());
161 case MachineOperand::MO_ExternalSymbol:
162 O << *GetExternalSymbolSymbol(MO.getSymbolName());
164 case MachineOperand::MO_ConstantPoolIndex:
165 O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_"
168 case MachineOperand::MO_JumpTableIndex:
169 O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
170 << '_' << MO.getIndex();
173 llvm_unreachable("<unknown operand type>");
178 void BlackfinAsmPrinter::printMemoryOperand(const MachineInstr *MI, int opNum) {
179 printOperand(MI, opNum);
181 if (MI->getOperand(opNum+1).isImm() && MI->getOperand(opNum+1).getImm() == 0)
185 printOperand(MI, opNum+1);
188 /// PrintAsmOperand - Print out an operand for an inline asm expression.
190 bool BlackfinAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
193 const char *ExtraCode) {
194 if (ExtraCode && ExtraCode[0]) {
195 if (ExtraCode[1] != 0) return true; // Unknown modifier.
197 switch (ExtraCode[0]) {
198 default: return true; // Unknown modifier.
204 printOperand(MI, OpNo);
209 bool BlackfinAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
212 const char *ExtraCode) {
213 if (ExtraCode && ExtraCode[0])
214 return true; // Unknown modifier
217 printOperand(MI, OpNo);