1 //===-- HexagonAsmPrinter.cpp - Print machine instrs to Hexagon assembly --===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains a printer that converts from our internal representation 11 // of machine-dependent LLVM code to Hexagon assembly language. This printer is 12 // the output mechanism used by `llc'. 13 // 14 //===----------------------------------------------------------------------===// 15 16 17 #define DEBUG_TYPE "asm-printer" 18 #include "Hexagon.h" 19 #include "HexagonAsmPrinter.h" 20 #include "HexagonMachineFunctionInfo.h" 21 #include "HexagonTargetMachine.h" 22 #include "HexagonSubtarget.h" 23 #include "InstPrinter/HexagonInstPrinter.h" 24 #include "llvm/Constants.h" 25 #include "llvm/DerivedTypes.h" 26 #include "llvm/Module.h" 27 #include "llvm/Analysis/ConstantFolding.h" 28 #include "llvm/Assembly/Writer.h" 29 #include "llvm/CodeGen/AsmPrinter.h" 30 #include "llvm/CodeGen/MachineModuleInfo.h" 31 #include "llvm/CodeGen/MachineFunctionPass.h" 32 #include "llvm/CodeGen/MachineInstr.h" 33 #include "llvm/CodeGen/MachineInstrBuilder.h" 34 #include "llvm/MC/MCAsmInfo.h" 35 #include "llvm/MC/MCContext.h" 36 #include "llvm/MC/MCExpr.h" 37 #include "llvm/MC/MCInst.h" 38 #include "llvm/MC/MCSection.h" 39 #include "llvm/MC/MCStreamer.h" 40 #include "llvm/MC/MCSymbol.h" 41 #include "llvm/Support/MathExtras.h" 42 #include "llvm/Support/CommandLine.h" 43 #include "llvm/Support/Debug.h" 44 #include "llvm/Support/Compiler.h" 45 #include "llvm/Support/Format.h" 46 #include "llvm/Support/raw_ostream.h" 47 #include "llvm/Support/TargetRegistry.h" 48 #include "llvm/Target/Mangler.h" 49 #include "llvm/Target/TargetData.h" 50 #include "llvm/Target/TargetLoweringObjectFile.h" 51 #include "llvm/Target/TargetRegisterInfo.h" 52 #include "llvm/Target/TargetInstrInfo.h" 53 #include "llvm/Target/TargetOptions.h" 54 #include "llvm/ADT/SmallString.h" 55 #include "llvm/ADT/SmallVector.h" 56 #include "llvm/ADT/StringExtras.h" 57 58 using namespace llvm; 59 60 static cl::opt<bool> AlignCalls( 61 "hexagon-align-calls", cl::Hidden, cl::init(true), 62 cl::desc("Insert falign after call instruction for Hexagon target")); 63 64 void HexagonAsmPrinter::EmitAlignment(unsigned NumBits, 65 const GlobalValue *GV) const { 66 // For basic block level alignment, use ".falign". 67 if (!GV) { 68 OutStreamer.EmitRawText(StringRef("\t.falign")); 69 return; 70 } 71 72 AsmPrinter::EmitAlignment(NumBits, GV); 73 } 74 75 void HexagonAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, 76 raw_ostream &O) { 77 const MachineOperand &MO = MI->getOperand(OpNo); 78 79 switch (MO.getType()) { 80 default: 81 assert(0 && "<unknown operand type>"); 82 case MachineOperand::MO_Register: 83 O << HexagonInstPrinter::getRegisterName(MO.getReg()); 84 return; 85 case MachineOperand::MO_Immediate: 86 O << MO.getImm(); 87 return; 88 case MachineOperand::MO_MachineBasicBlock: 89 O << *MO.getMBB()->getSymbol(); 90 return; 91 case MachineOperand::MO_JumpTableIndex: 92 O << *GetJTISymbol(MO.getIndex()); 93 // FIXME: PIC relocation model. 94 return; 95 case MachineOperand::MO_ConstantPoolIndex: 96 O << *GetCPISymbol(MO.getIndex()); 97 return; 98 case MachineOperand::MO_ExternalSymbol: 99 O << *GetExternalSymbolSymbol(MO.getSymbolName()); 100 return; 101 case MachineOperand::MO_GlobalAddress: 102 // Computing the address of a global symbol, not calling it. 103 O << *Mang->getSymbol(MO.getGlobal()); 104 printOffset(MO.getOffset(), O); 105 return; 106 } 107 } 108 109 // 110 // isBlockOnlyReachableByFallthrough - We need to override this since the 111 // default AsmPrinter does not print labels for any basic block that 112 // is only reachable by a fall through. That works for all cases except 113 // for the case in which the basic block is reachable by a fall through but 114 // through an indirect from a jump table. In this case, the jump table 115 // will contain a label not defined by AsmPrinter. 116 // 117 bool HexagonAsmPrinter:: 118 isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const { 119 if (MBB->hasAddressTaken()) { 120 return false; 121 } 122 return AsmPrinter::isBlockOnlyReachableByFallthrough(MBB); 123 } 124 125 126 /// PrintAsmOperand - Print out an operand for an inline asm expression. 127 /// 128 bool HexagonAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 129 unsigned AsmVariant, 130 const char *ExtraCode, 131 raw_ostream &OS) { 132 // Does this asm operand have a single letter operand modifier? 133 if (ExtraCode && ExtraCode[0]) { 134 if (ExtraCode[1] != 0) return true; // Unknown modifier. 135 136 switch (ExtraCode[0]) { 137 default: return true; // Unknown modifier. 138 case 'c': // Don't print "$" before a global var name or constant. 139 // Hexagon never has a prefix. 140 printOperand(MI, OpNo, OS); 141 return false; 142 case 'L': // Write second word of DImode reference. 143 // Verify that this operand has two consecutive registers. 144 if (!MI->getOperand(OpNo).isReg() || 145 OpNo+1 == MI->getNumOperands() || 146 !MI->getOperand(OpNo+1).isReg()) 147 return true; 148 ++OpNo; // Return the high-part. 149 break; 150 case 'I': 151 // Write 'i' if an integer constant, otherwise nothing. Used to print 152 // addi vs add, etc. 153 if (MI->getOperand(OpNo).isImm()) 154 OS << "i"; 155 return false; 156 } 157 } 158 159 printOperand(MI, OpNo, OS); 160 return false; 161 } 162 163 bool HexagonAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 164 unsigned OpNo, unsigned AsmVariant, 165 const char *ExtraCode, 166 raw_ostream &O) { 167 if (ExtraCode && ExtraCode[0]) 168 return true; // Unknown modifier. 169 170 const MachineOperand &Base = MI->getOperand(OpNo); 171 const MachineOperand &Offset = MI->getOperand(OpNo+1); 172 173 if (Base.isReg()) 174 printOperand(MI, OpNo, O); 175 else 176 llvm_unreachable("Unimplemented"); 177 178 if (Offset.isImm()) { 179 if (Offset.getImm()) 180 O << " + #" << Offset.getImm(); 181 } 182 else 183 llvm_unreachable("Unimplemented"); 184 185 return false; 186 } 187 188 void HexagonAsmPrinter::printPredicateOperand(const MachineInstr *MI, 189 unsigned OpNo, 190 raw_ostream &O) { 191 llvm_unreachable("Unimplemented"); 192 } 193 194 195 /// printMachineInstruction -- Print out a single Hexagon MI in Darwin syntax to 196 /// the current output stream. 197 /// 198 void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) { 199 MCInst MCI; 200 201 HexagonLowerToMC(MI, MCI, *this); 202 OutStreamer.EmitInstruction(MCI); 203 204 return; 205 } 206 207 /// PrintUnmangledNameSafely - Print out the printable characters in the name. 208 /// Don't print things like \n or \0. 209 // static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) { 210 // for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen(); 211 // Name != E; ++Name) 212 // if (isprint(*Name)) 213 // OS << *Name; 214 // } 215 216 217 void HexagonAsmPrinter::printAddrModeBasePlusOffset(const MachineInstr *MI, 218 int OpNo, raw_ostream &O) { 219 const MachineOperand &MO1 = MI->getOperand(OpNo); 220 const MachineOperand &MO2 = MI->getOperand(OpNo+1); 221 222 O << HexagonInstPrinter::getRegisterName(MO1.getReg()) 223 << " + #" 224 << MO2.getImm(); 225 } 226 227 228 void HexagonAsmPrinter::printGlobalOperand(const MachineInstr *MI, int OpNo, 229 raw_ostream &O) { 230 const MachineOperand &MO = MI->getOperand(OpNo); 231 assert( (MO.getType() == MachineOperand::MO_GlobalAddress) && 232 "Expecting global address"); 233 234 O << *Mang->getSymbol(MO.getGlobal()); 235 if (MO.getOffset() != 0) { 236 O << " + "; 237 O << MO.getOffset(); 238 } 239 } 240 241 void HexagonAsmPrinter::printJumpTable(const MachineInstr *MI, int OpNo, 242 raw_ostream &O) { 243 const MachineOperand &MO = MI->getOperand(OpNo); 244 assert( (MO.getType() == MachineOperand::MO_JumpTableIndex) && 245 "Expecting jump table index"); 246 247 // Hexagon_TODO: Do we need name mangling? 248 O << *GetJTISymbol(MO.getIndex()); 249 } 250 251 void HexagonAsmPrinter::printConstantPool(const MachineInstr *MI, int OpNo, 252 raw_ostream &O) { 253 const MachineOperand &MO = MI->getOperand(OpNo); 254 assert( (MO.getType() == MachineOperand::MO_ConstantPoolIndex) && 255 "Expecting constant pool index"); 256 257 // Hexagon_TODO: Do we need name mangling? 258 O << *GetCPISymbol(MO.getIndex()); 259 } 260 261 static MCInstPrinter *createHexagonMCInstPrinter(const Target &T, 262 unsigned SyntaxVariant, 263 const MCAsmInfo &MAI, 264 const MCInstrInfo &MII, 265 const MCRegisterInfo &MRI, 266 const MCSubtargetInfo &STI) { 267 if (SyntaxVariant == 0) 268 return(new HexagonInstPrinter(MAI, MII, MRI)); 269 else 270 return NULL; 271 } 272 273 extern "C" void LLVMInitializeHexagonAsmPrinter() { 274 RegisterAsmPrinter<HexagonAsmPrinter> X(TheHexagonTarget); 275 276 TargetRegistry::RegisterMCInstPrinter(TheHexagonTarget, 277 createHexagonMCInstPrinter); 278 } 279