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 #include "Hexagon.h" 00017 #include "HexagonAsmPrinter.h" 00018 #include "HexagonMachineFunctionInfo.h" 00019 #include "HexagonSubtarget.h" 00020 #include "HexagonTargetMachine.h" 00021 #include "InstPrinter/HexagonInstPrinter.h" 00022 #include "MCTargetDesc/HexagonMCInst.h" 00023 #include "llvm/ADT/SmallString.h" 00024 #include "llvm/ADT/SmallVector.h" 00025 #include "llvm/ADT/StringExtras.h" 00026 #include "llvm/Analysis/ConstantFolding.h" 00027 #include "llvm/CodeGen/AsmPrinter.h" 00028 #include "llvm/CodeGen/MachineFunctionPass.h" 00029 #include "llvm/CodeGen/MachineInstr.h" 00030 #include "llvm/CodeGen/MachineInstrBuilder.h" 00031 #include "llvm/CodeGen/MachineModuleInfo.h" 00032 #include "llvm/IR/Constants.h" 00033 #include "llvm/IR/DataLayout.h" 00034 #include "llvm/IR/DerivedTypes.h" 00035 #include "llvm/IR/Mangler.h" 00036 #include "llvm/IR/Module.h" 00037 #include "llvm/MC/MCAsmInfo.h" 00038 #include "llvm/MC/MCContext.h" 00039 #include "llvm/MC/MCExpr.h" 00040 #include "llvm/MC/MCInst.h" 00041 #include "llvm/MC/MCSection.h" 00042 #include "llvm/MC/MCStreamer.h" 00043 #include "llvm/MC/MCSymbol.h" 00044 #include "llvm/Support/CommandLine.h" 00045 #include "llvm/Support/Compiler.h" 00046 #include "llvm/Support/Debug.h" 00047 #include "llvm/Support/Format.h" 00048 #include "llvm/Support/MathExtras.h" 00049 #include "llvm/Support/TargetRegistry.h" 00050 #include "llvm/Support/raw_ostream.h" 00051 #include "llvm/Target/TargetInstrInfo.h" 00052 #include "llvm/Target/TargetLoweringObjectFile.h" 00053 #include "llvm/Target/TargetOptions.h" 00054 #include "llvm/Target/TargetRegisterInfo.h" 00055 00056 using namespace llvm; 00057 00058 #define DEBUG_TYPE "asm-printer" 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::printOperand(const MachineInstr *MI, unsigned OpNo, 00065 raw_ostream &O) { 00066 const MachineOperand &MO = MI->getOperand(OpNo); 00067 00068 switch (MO.getType()) { 00069 default: llvm_unreachable ("<unknown operand type>"); 00070 case MachineOperand::MO_Register: 00071 O << HexagonInstPrinter::getRegisterName(MO.getReg()); 00072 return; 00073 case MachineOperand::MO_Immediate: 00074 O << MO.getImm(); 00075 return; 00076 case MachineOperand::MO_MachineBasicBlock: 00077 O << *MO.getMBB()->getSymbol(); 00078 return; 00079 case MachineOperand::MO_ConstantPoolIndex: 00080 O << *GetCPISymbol(MO.getIndex()); 00081 return; 00082 case MachineOperand::MO_GlobalAddress: 00083 // Computing the address of a global symbol, not calling it. 00084 O << *getSymbol(MO.getGlobal()); 00085 printOffset(MO.getOffset(), O); 00086 return; 00087 } 00088 } 00089 00090 // 00091 // isBlockOnlyReachableByFallthrough - We need to override this since the 00092 // default AsmPrinter does not print labels for any basic block that 00093 // is only reachable by a fall through. That works for all cases except 00094 // for the case in which the basic block is reachable by a fall through but 00095 // through an indirect from a jump table. In this case, the jump table 00096 // will contain a label not defined by AsmPrinter. 00097 // 00098 bool HexagonAsmPrinter:: 00099 isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const { 00100 if (MBB->hasAddressTaken()) { 00101 return false; 00102 } 00103 return AsmPrinter::isBlockOnlyReachableByFallthrough(MBB); 00104 } 00105 00106 00107 /// PrintAsmOperand - Print out an operand for an inline asm expression. 00108 /// 00109 bool HexagonAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 00110 unsigned AsmVariant, 00111 const char *ExtraCode, 00112 raw_ostream &OS) { 00113 // Does this asm operand have a single letter operand modifier? 00114 if (ExtraCode && ExtraCode[0]) { 00115 if (ExtraCode[1] != 0) return true; // Unknown modifier. 00116 00117 switch (ExtraCode[0]) { 00118 default: 00119 // See if this is a generic print operand 00120 return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, OS); 00121 case 'c': // Don't print "$" before a global var name or constant. 00122 // Hexagon never has a prefix. 00123 printOperand(MI, OpNo, OS); 00124 return false; 00125 case 'L': // Write second word of DImode reference. 00126 // Verify that this operand has two consecutive registers. 00127 if (!MI->getOperand(OpNo).isReg() || 00128 OpNo+1 == MI->getNumOperands() || 00129 !MI->getOperand(OpNo+1).isReg()) 00130 return true; 00131 ++OpNo; // Return the high-part. 00132 break; 00133 case 'I': 00134 // Write 'i' if an integer constant, otherwise nothing. Used to print 00135 // addi vs add, etc. 00136 if (MI->getOperand(OpNo).isImm()) 00137 OS << "i"; 00138 return false; 00139 } 00140 } 00141 00142 printOperand(MI, OpNo, OS); 00143 return false; 00144 } 00145 00146 bool HexagonAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 00147 unsigned OpNo, unsigned AsmVariant, 00148 const char *ExtraCode, 00149 raw_ostream &O) { 00150 if (ExtraCode && ExtraCode[0]) 00151 return true; // Unknown modifier. 00152 00153 const MachineOperand &Base = MI->getOperand(OpNo); 00154 const MachineOperand &Offset = MI->getOperand(OpNo+1); 00155 00156 if (Base.isReg()) 00157 printOperand(MI, OpNo, O); 00158 else 00159 llvm_unreachable("Unimplemented"); 00160 00161 if (Offset.isImm()) { 00162 if (Offset.getImm()) 00163 O << " + #" << Offset.getImm(); 00164 } 00165 else 00166 llvm_unreachable("Unimplemented"); 00167 00168 return false; 00169 } 00170 00171 00172 /// printMachineInstruction -- Print out a single Hexagon MI in Darwin syntax to 00173 /// the current output stream. 00174 /// 00175 void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) { 00176 if (MI->isBundle()) { 00177 std::vector<const MachineInstr*> BundleMIs; 00178 00179 const MachineBasicBlock *MBB = MI->getParent(); 00180 MachineBasicBlock::const_instr_iterator MII = MI; 00181 ++MII; 00182 unsigned int IgnoreCount = 0; 00183 while (MII != MBB->end() && MII->isInsideBundle()) { 00184 const MachineInstr *MInst = MII; 00185 if (MInst->getOpcode() == TargetOpcode::DBG_VALUE || 00186 MInst->getOpcode() == TargetOpcode::IMPLICIT_DEF) { 00187 IgnoreCount++; 00188 ++MII; 00189 continue; 00190 } 00191 //BundleMIs.push_back(&*MII); 00192 BundleMIs.push_back(MInst); 00193 ++MII; 00194 } 00195 unsigned Size = BundleMIs.size(); 00196 assert((Size+IgnoreCount) == MI->getBundleSize() && "Corrupt Bundle!"); 00197 for (unsigned Index = 0; Index < Size; Index++) { 00198 HexagonMCInst MCI; 00199 MCI.setPacketStart(Index == 0); 00200 MCI.setPacketEnd(Index == (Size-1)); 00201 00202 HexagonLowerToMC(BundleMIs[Index], MCI, *this); 00203 EmitToStreamer(OutStreamer, MCI); 00204 } 00205 } 00206 else { 00207 HexagonMCInst MCI; 00208 if (MI->getOpcode() == Hexagon::ENDLOOP0) { 00209 MCI.setPacketStart(true); 00210 MCI.setPacketEnd(true); 00211 } 00212 HexagonLowerToMC(MI, MCI, *this); 00213 EmitToStreamer(OutStreamer, MCI); 00214 } 00215 00216 return; 00217 } 00218 00219 static MCInstPrinter *createHexagonMCInstPrinter(const Target &T, 00220 unsigned SyntaxVariant, 00221 const MCAsmInfo &MAI, 00222 const MCInstrInfo &MII, 00223 const MCRegisterInfo &MRI, 00224 const MCSubtargetInfo &STI) { 00225 if (SyntaxVariant == 0) 00226 return(new HexagonInstPrinter(MAI, MII, MRI)); 00227 else 00228 return nullptr; 00229 } 00230 00231 extern "C" void LLVMInitializeHexagonAsmPrinter() { 00232 RegisterAsmPrinter<HexagonAsmPrinter> X(TheHexagonTarget); 00233 00234 TargetRegistry::RegisterMCInstPrinter(TheHexagonTarget, 00235 createHexagonMCInstPrinter); 00236 }