LLVM API Documentation
00001 //===-- HexagonAsmPrinter.cpp - Print machine instrs to Hexagon assembly --===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains a printer that converts from our internal representation 00011 // of machine-dependent LLVM code to Hexagon assembly language. This printer is 00012 // the output mechanism used by `llc'. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #define DEBUG_TYPE "asm-printer" 00017 #include "Hexagon.h" 00018 #include "HexagonAsmPrinter.h" 00019 #include "HexagonMachineFunctionInfo.h" 00020 #include "HexagonTargetMachine.h" 00021 #include "HexagonSubtarget.h" 00022 #include "MCTargetDesc/HexagonMCInst.h" 00023 #include "InstPrinter/HexagonInstPrinter.h" 00024 #include "llvm/ADT/SmallString.h" 00025 #include "llvm/ADT/SmallVector.h" 00026 #include "llvm/ADT/StringExtras.h" 00027 #include "llvm/Analysis/ConstantFolding.h" 00028 #include "llvm/Assembly/Writer.h" 00029 #include "llvm/CodeGen/AsmPrinter.h" 00030 #include "llvm/CodeGen/MachineFunctionPass.h" 00031 #include "llvm/CodeGen/MachineInstr.h" 00032 #include "llvm/CodeGen/MachineInstrBuilder.h" 00033 #include "llvm/CodeGen/MachineModuleInfo.h" 00034 #include "llvm/IR/Constants.h" 00035 #include "llvm/IR/DataLayout.h" 00036 #include "llvm/IR/DerivedTypes.h" 00037 #include "llvm/IR/Module.h" 00038 #include "llvm/MC/MCAsmInfo.h" 00039 #include "llvm/MC/MCContext.h" 00040 #include "llvm/MC/MCExpr.h" 00041 #include "llvm/MC/MCInst.h" 00042 #include "llvm/MC/MCSection.h" 00043 #include "llvm/MC/MCStreamer.h" 00044 #include "llvm/MC/MCSymbol.h" 00045 #include "llvm/Support/CommandLine.h" 00046 #include "llvm/Support/Compiler.h" 00047 #include "llvm/Support/Debug.h" 00048 #include "llvm/Support/Format.h" 00049 #include "llvm/Support/MathExtras.h" 00050 #include "llvm/Support/TargetRegistry.h" 00051 #include "llvm/Support/raw_ostream.h" 00052 #include "llvm/Target/Mangler.h" 00053 #include "llvm/Target/TargetInstrInfo.h" 00054 #include "llvm/Target/TargetLoweringObjectFile.h" 00055 #include "llvm/Target/TargetOptions.h" 00056 #include "llvm/Target/TargetRegisterInfo.h" 00057 00058 using namespace llvm; 00059 00060 static cl::opt<bool> AlignCalls( 00061 "hexagon-align-calls", cl::Hidden, cl::init(true), 00062 cl::desc("Insert falign after call instruction for Hexagon target")); 00063 00064 void HexagonAsmPrinter::EmitAlignment(unsigned NumBits, 00065 const GlobalValue *GV) const { 00066 // For basic block level alignment, use ".falign". 00067 if (!GV) { 00068 OutStreamer.EmitRawText(StringRef("\t.falign")); 00069 return; 00070 } 00071 00072 AsmPrinter::EmitAlignment(NumBits, GV); 00073 } 00074 00075 void HexagonAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, 00076 raw_ostream &O) { 00077 const MachineOperand &MO = MI->getOperand(OpNo); 00078 00079 switch (MO.getType()) { 00080 default: llvm_unreachable ("<unknown operand type>"); 00081 case MachineOperand::MO_Register: 00082 O << HexagonInstPrinter::getRegisterName(MO.getReg()); 00083 return; 00084 case MachineOperand::MO_Immediate: 00085 O << MO.getImm(); 00086 return; 00087 case MachineOperand::MO_MachineBasicBlock: 00088 O << *MO.getMBB()->getSymbol(); 00089 return; 00090 case MachineOperand::MO_JumpTableIndex: 00091 O << *GetJTISymbol(MO.getIndex()); 00092 // FIXME: PIC relocation model. 00093 return; 00094 case MachineOperand::MO_ConstantPoolIndex: 00095 O << *GetCPISymbol(MO.getIndex()); 00096 return; 00097 case MachineOperand::MO_ExternalSymbol: 00098 O << *GetExternalSymbolSymbol(MO.getSymbolName()); 00099 return; 00100 case MachineOperand::MO_GlobalAddress: 00101 // Computing the address of a global symbol, not calling it. 00102 O << *Mang->getSymbol(MO.getGlobal()); 00103 printOffset(MO.getOffset(), O); 00104 return; 00105 } 00106 } 00107 00108 // 00109 // isBlockOnlyReachableByFallthrough - We need to override this since the 00110 // default AsmPrinter does not print labels for any basic block that 00111 // is only reachable by a fall through. That works for all cases except 00112 // for the case in which the basic block is reachable by a fall through but 00113 // through an indirect from a jump table. In this case, the jump table 00114 // will contain a label not defined by AsmPrinter. 00115 // 00116 bool HexagonAsmPrinter:: 00117 isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const { 00118 if (MBB->hasAddressTaken()) { 00119 return false; 00120 } 00121 return AsmPrinter::isBlockOnlyReachableByFallthrough(MBB); 00122 } 00123 00124 00125 /// PrintAsmOperand - Print out an operand for an inline asm expression. 00126 /// 00127 bool HexagonAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 00128 unsigned AsmVariant, 00129 const char *ExtraCode, 00130 raw_ostream &OS) { 00131 // Does this asm operand have a single letter operand modifier? 00132 if (ExtraCode && ExtraCode[0]) { 00133 if (ExtraCode[1] != 0) return true; // Unknown modifier. 00134 00135 switch (ExtraCode[0]) { 00136 default: 00137 // See if this is a generic print operand 00138 return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, OS); 00139 case 'c': // Don't print "$" before a global var name or constant. 00140 // Hexagon never has a prefix. 00141 printOperand(MI, OpNo, OS); 00142 return false; 00143 case 'L': // Write second word of DImode reference. 00144 // Verify that this operand has two consecutive registers. 00145 if (!MI->getOperand(OpNo).isReg() || 00146 OpNo+1 == MI->getNumOperands() || 00147 !MI->getOperand(OpNo+1).isReg()) 00148 return true; 00149 ++OpNo; // Return the high-part. 00150 break; 00151 case 'I': 00152 // Write 'i' if an integer constant, otherwise nothing. Used to print 00153 // addi vs add, etc. 00154 if (MI->getOperand(OpNo).isImm()) 00155 OS << "i"; 00156 return false; 00157 } 00158 } 00159 00160 printOperand(MI, OpNo, OS); 00161 return false; 00162 } 00163 00164 bool HexagonAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 00165 unsigned OpNo, unsigned AsmVariant, 00166 const char *ExtraCode, 00167 raw_ostream &O) { 00168 if (ExtraCode && ExtraCode[0]) 00169 return true; // Unknown modifier. 00170 00171 const MachineOperand &Base = MI->getOperand(OpNo); 00172 const MachineOperand &Offset = MI->getOperand(OpNo+1); 00173 00174 if (Base.isReg()) 00175 printOperand(MI, OpNo, O); 00176 else 00177 llvm_unreachable("Unimplemented"); 00178 00179 if (Offset.isImm()) { 00180 if (Offset.getImm()) 00181 O << " + #" << Offset.getImm(); 00182 } 00183 else 00184 llvm_unreachable("Unimplemented"); 00185 00186 return false; 00187 } 00188 00189 void HexagonAsmPrinter::printPredicateOperand(const MachineInstr *MI, 00190 unsigned OpNo, 00191 raw_ostream &O) { 00192 llvm_unreachable("Unimplemented"); 00193 } 00194 00195 00196 /// printMachineInstruction -- Print out a single Hexagon MI in Darwin syntax to 00197 /// the current output stream. 00198 /// 00199 void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) { 00200 if (MI->isBundle()) { 00201 std::vector<const MachineInstr*> BundleMIs; 00202 00203 const MachineBasicBlock *MBB = MI->getParent(); 00204 MachineBasicBlock::const_instr_iterator MII = MI; 00205 ++MII; 00206 unsigned int IgnoreCount = 0; 00207 while (MII != MBB->end() && MII->isInsideBundle()) { 00208 const MachineInstr *MInst = MII; 00209 if (MInst->getOpcode() == TargetOpcode::DBG_VALUE || 00210 MInst->getOpcode() == TargetOpcode::IMPLICIT_DEF) { 00211 IgnoreCount++; 00212 ++MII; 00213 continue; 00214 } 00215 //BundleMIs.push_back(&*MII); 00216 BundleMIs.push_back(MInst); 00217 ++MII; 00218 } 00219 unsigned Size = BundleMIs.size(); 00220 assert((Size+IgnoreCount) == MI->getBundleSize() && "Corrupt Bundle!"); 00221 for (unsigned Index = 0; Index < Size; Index++) { 00222 HexagonMCInst MCI; 00223 MCI.setPacketStart(Index == 0); 00224 MCI.setPacketEnd(Index == (Size-1)); 00225 00226 HexagonLowerToMC(BundleMIs[Index], MCI, *this); 00227 OutStreamer.EmitInstruction(MCI); 00228 } 00229 } 00230 else { 00231 HexagonMCInst MCI; 00232 if (MI->getOpcode() == Hexagon::ENDLOOP0) { 00233 MCI.setPacketStart(true); 00234 MCI.setPacketEnd(true); 00235 } 00236 HexagonLowerToMC(MI, MCI, *this); 00237 OutStreamer.EmitInstruction(MCI); 00238 } 00239 00240 return; 00241 } 00242 00243 /// PrintUnmangledNameSafely - Print out the printable characters in the name. 00244 /// Don't print things like \n or \0. 00245 // static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) { 00246 // for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen(); 00247 // Name != E; ++Name) 00248 // if (isprint(*Name)) 00249 // OS << *Name; 00250 // } 00251 00252 00253 void HexagonAsmPrinter::printAddrModeBasePlusOffset(const MachineInstr *MI, 00254 int OpNo, raw_ostream &O) { 00255 const MachineOperand &MO1 = MI->getOperand(OpNo); 00256 const MachineOperand &MO2 = MI->getOperand(OpNo+1); 00257 00258 O << HexagonInstPrinter::getRegisterName(MO1.getReg()) 00259 << " + #" 00260 << MO2.getImm(); 00261 } 00262 00263 00264 void HexagonAsmPrinter::printGlobalOperand(const MachineInstr *MI, int OpNo, 00265 raw_ostream &O) { 00266 const MachineOperand &MO = MI->getOperand(OpNo); 00267 assert( (MO.getType() == MachineOperand::MO_GlobalAddress) && 00268 "Expecting global address"); 00269 00270 O << *Mang->getSymbol(MO.getGlobal()); 00271 if (MO.getOffset() != 0) { 00272 O << " + "; 00273 O << MO.getOffset(); 00274 } 00275 } 00276 00277 void HexagonAsmPrinter::printJumpTable(const MachineInstr *MI, int OpNo, 00278 raw_ostream &O) { 00279 const MachineOperand &MO = MI->getOperand(OpNo); 00280 assert( (MO.getType() == MachineOperand::MO_JumpTableIndex) && 00281 "Expecting jump table index"); 00282 00283 // Hexagon_TODO: Do we need name mangling? 00284 O << *GetJTISymbol(MO.getIndex()); 00285 } 00286 00287 void HexagonAsmPrinter::printConstantPool(const MachineInstr *MI, int OpNo, 00288 raw_ostream &O) { 00289 const MachineOperand &MO = MI->getOperand(OpNo); 00290 assert( (MO.getType() == MachineOperand::MO_ConstantPoolIndex) && 00291 "Expecting constant pool index"); 00292 00293 // Hexagon_TODO: Do we need name mangling? 00294 O << *GetCPISymbol(MO.getIndex()); 00295 } 00296 00297 static MCInstPrinter *createHexagonMCInstPrinter(const Target &T, 00298 unsigned SyntaxVariant, 00299 const MCAsmInfo &MAI, 00300 const MCInstrInfo &MII, 00301 const MCRegisterInfo &MRI, 00302 const MCSubtargetInfo &STI) { 00303 if (SyntaxVariant == 0) 00304 return(new HexagonInstPrinter(MAI, MII, MRI)); 00305 else 00306 return NULL; 00307 } 00308 00309 extern "C" void LLVMInitializeHexagonAsmPrinter() { 00310 RegisterAsmPrinter<HexagonAsmPrinter> X(TheHexagonTarget); 00311 00312 TargetRegistry::RegisterMCInstPrinter(TheHexagonTarget, 00313 createHexagonMCInstPrinter); 00314 }