X86AsmPrinter.cpp revision 8581ee85b46bc5440a8aae53a0b752771f7b83f4
1//===-- X86AsmPrinter.cpp - Convert X86 LLVM code to Intel assembly -------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by the LLVM research group and is distributed under 6// the University of Illinois Open Source 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 Intel-format assembly language. This 12// printer is the output mechanism used by `llc' and `lli -print-machineinstrs' 13// on X86. 14// 15//===----------------------------------------------------------------------===// 16 17#include "X86.h" 18#include "X86InstrInfo.h" 19#include "X86TargetMachine.h" 20#include "llvm/Constants.h" 21#include "llvm/DerivedTypes.h" 22#include "llvm/Module.h" 23#include "llvm/Assembly/Writer.h" 24#include "llvm/CodeGen/AsmPrinter.h" 25#include "llvm/CodeGen/MachineCodeEmitter.h" 26#include "llvm/CodeGen/MachineConstantPool.h" 27#include "llvm/CodeGen/MachineFunctionPass.h" 28#include "llvm/CodeGen/MachineInstr.h" 29#include "llvm/CodeGen/ValueTypes.h" 30#include "llvm/Target/TargetMachine.h" 31#include "llvm/Support/Mangler.h" 32#include "Support/Statistic.h" 33#include "Support/StringExtras.h" 34#include "Support/CommandLine.h" 35using namespace llvm; 36 37namespace { 38 Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); 39 40 struct GasBugWorkaroundEmitter : public MachineCodeEmitter { 41 GasBugWorkaroundEmitter(std::ostream& o) 42 : O(o), OldFlags(O.flags()), firstByte(true) { 43 O << std::hex; 44 } 45 46 ~GasBugWorkaroundEmitter() { 47 O.flags(OldFlags); 48 } 49 50 virtual void emitByte(unsigned char B) { 51 if (!firstByte) O << "\n\t"; 52 firstByte = false; 53 O << ".byte 0x" << (unsigned) B; 54 } 55 56 // These should never be called 57 virtual void emitWord(unsigned W) { assert(0); } 58 virtual uint64_t getGlobalValueAddress(GlobalValue *V) { abort(); } 59 virtual uint64_t getGlobalValueAddress(const std::string &Name) { abort(); } 60 virtual uint64_t getConstantPoolEntryAddress(unsigned Index) { abort(); } 61 virtual uint64_t getCurrentPCValue() { abort(); } 62 virtual uint64_t forceCompilationOf(Function *F) { abort(); } 63 64 private: 65 std::ostream& O; 66 std::ios::fmtflags OldFlags; 67 bool firstByte; 68 }; 69 70 struct X86AsmPrinter : public AsmPrinter { 71 X86AsmPrinter(std::ostream &O, TargetMachine &TM) : AsmPrinter(O, TM) { } 72 73 virtual const char *getPassName() const { 74 return "X86 Assembly Printer"; 75 } 76 77 /// printInstruction - This method is automatically generated by tablegen 78 /// from the instruction set description. This method returns true if the 79 /// machine instruction was sufficiently described to print it, otherwise it 80 /// returns false. 81 bool printInstruction(const MachineInstr *MI); 82 83 // This method is used by the tablegen'erated instruction printer. 84 void printOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT){ 85 const MachineOperand &MO = MI->getOperand(OpNo); 86 if (MO.getType() == MachineOperand::MO_MachineRegister) { 87 assert(MRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physref??"); 88 // Bug Workaround: See note in Printer::doInitialization about %. 89 O << "%" << TM.getRegisterInfo()->get(MO.getReg()).Name; 90 } else { 91 printOp(MO); 92 } 93 } 94 95 void printCallOperand(const MachineInstr *MI, unsigned OpNo, 96 MVT::ValueType VT) { 97 printOp(MI->getOperand(OpNo), true); // Don't print "OFFSET". 98 } 99 100 void printMemoryOperand(const MachineInstr *MI, unsigned OpNo, 101 MVT::ValueType VT) { 102 switch (VT) { 103 default: assert(0 && "Unknown arg size!"); 104 case MVT::i8: O << "BYTE PTR "; break; 105 case MVT::i16: O << "WORD PTR "; break; 106 case MVT::i32: 107 case MVT::f32: O << "DWORD PTR "; break; 108 case MVT::i64: 109 case MVT::f64: O << "QWORD PTR "; break; 110 case MVT::f80: O << "XWORD PTR "; break; 111 } 112 printMemReference(MI, OpNo); 113 } 114 115 void printMachineInstruction(const MachineInstr *MI); 116 void printOp(const MachineOperand &MO, bool elideOffsetKeyword = false); 117 void printMemReference(const MachineInstr *MI, unsigned Op); 118 void printConstantPool(MachineConstantPool *MCP); 119 bool runOnMachineFunction(MachineFunction &F); 120 bool doInitialization(Module &M); 121 bool doFinalization(Module &M); 122 }; 123} // end of anonymous namespace 124 125/// createX86CodePrinterPass - Returns a pass that prints the X86 126/// assembly code for a MachineFunction to the given output stream, 127/// using the given target machine description. This should work 128/// regardless of whether the function is in SSA form. 129/// 130FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,TargetMachine &tm){ 131 return new X86AsmPrinter(o, tm); 132} 133 134 135// Include the auto-generated portion of the assembly writer. 136#include "X86GenAsmWriter.inc" 137 138 139/// printConstantPool - Print to the current output stream assembly 140/// representations of the constants in the constant pool MCP. This is 141/// used to print out constants which have been "spilled to memory" by 142/// the code generator. 143/// 144void X86AsmPrinter::printConstantPool(MachineConstantPool *MCP) { 145 const std::vector<Constant*> &CP = MCP->getConstants(); 146 const TargetData &TD = TM.getTargetData(); 147 148 if (CP.empty()) return; 149 150 for (unsigned i = 0, e = CP.size(); i != e; ++i) { 151 O << "\t.section .rodata\n"; 152 O << "\t.align " << (unsigned)TD.getTypeAlignment(CP[i]->getType()) 153 << "\n"; 154 O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t#" 155 << *CP[i] << "\n"; 156 emitGlobalConstant(CP[i]); 157 } 158} 159 160/// runOnMachineFunction - This uses the printMachineInstruction() 161/// method to print assembly for each instruction. 162/// 163bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) { 164 setupMachineFunction(MF); 165 O << "\n\n"; 166 167 // Print out constants referenced by the function 168 printConstantPool(MF.getConstantPool()); 169 170 // Print out labels for the function. 171 O << "\t.text\n"; 172 O << "\t.align 16\n"; 173 O << "\t.globl\t" << CurrentFnName << "\n"; 174 O << "\t.type\t" << CurrentFnName << ", @function\n"; 175 O << CurrentFnName << ":\n"; 176 177 // Print out code for the function. 178 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 179 I != E; ++I) { 180 // Print a label for the basic block. 181 O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t# " 182 << I->getBasicBlock()->getName() << "\n"; 183 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 184 II != E; ++II) { 185 // Print the assembly for the instruction. 186 O << "\t"; 187 printMachineInstruction(II); 188 } 189 } 190 191 // We didn't modify anything. 192 return false; 193} 194 195static bool isScale(const MachineOperand &MO) { 196 return MO.isImmediate() && 197 (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 || 198 MO.getImmedValue() == 4 || MO.getImmedValue() == 8); 199} 200 201static bool isMem(const MachineInstr *MI, unsigned Op) { 202 if (MI->getOperand(Op).isFrameIndex()) return true; 203 if (MI->getOperand(Op).isConstantPoolIndex()) return true; 204 return Op+4 <= MI->getNumOperands() && 205 MI->getOperand(Op ).isRegister() && isScale(MI->getOperand(Op+1)) && 206 MI->getOperand(Op+2).isRegister() && MI->getOperand(Op+3).isImmediate(); 207} 208 209 210 211void X86AsmPrinter::printOp(const MachineOperand &MO, 212 bool elideOffsetKeyword /* = false */) { 213 const MRegisterInfo &RI = *TM.getRegisterInfo(); 214 switch (MO.getType()) { 215 case MachineOperand::MO_VirtualRegister: 216 if (Value *V = MO.getVRegValueOrNull()) { 217 O << "<" << V->getName() << ">"; 218 return; 219 } 220 // FALLTHROUGH 221 case MachineOperand::MO_MachineRegister: 222 if (MRegisterInfo::isPhysicalRegister(MO.getReg())) 223 // Bug Workaround: See note in Printer::doInitialization about %. 224 O << "%" << RI.get(MO.getReg()).Name; 225 else 226 O << "%reg" << MO.getReg(); 227 return; 228 229 case MachineOperand::MO_SignExtendedImmed: 230 case MachineOperand::MO_UnextendedImmed: 231 O << (int)MO.getImmedValue(); 232 return; 233 case MachineOperand::MO_MachineBasicBlock: { 234 MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); 235 O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction()) 236 << "_" << MBBOp->getNumber () << "\t# " 237 << MBBOp->getBasicBlock ()->getName (); 238 return; 239 } 240 case MachineOperand::MO_PCRelativeDisp: 241 std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs"; 242 abort (); 243 return; 244 case MachineOperand::MO_GlobalAddress: 245 if (!elideOffsetKeyword) 246 O << "OFFSET "; 247 O << Mang->getValueName(MO.getGlobal()); 248 return; 249 case MachineOperand::MO_ExternalSymbol: 250 O << MO.getSymbolName(); 251 return; 252 default: 253 O << "<unknown operand type>"; return; 254 } 255} 256 257void X86AsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op) { 258 assert(isMem(MI, Op) && "Invalid memory reference!"); 259 260 if (MI->getOperand(Op).isFrameIndex()) { 261 O << "[frame slot #" << MI->getOperand(Op).getFrameIndex(); 262 if (MI->getOperand(Op+3).getImmedValue()) 263 O << " + " << MI->getOperand(Op+3).getImmedValue(); 264 O << "]"; 265 return; 266 } else if (MI->getOperand(Op).isConstantPoolIndex()) { 267 O << "[.CPI" << CurrentFnName << "_" 268 << MI->getOperand(Op).getConstantPoolIndex(); 269 if (MI->getOperand(Op+3).getImmedValue()) 270 O << " + " << MI->getOperand(Op+3).getImmedValue(); 271 O << "]"; 272 return; 273 } 274 275 const MachineOperand &BaseReg = MI->getOperand(Op); 276 int ScaleVal = MI->getOperand(Op+1).getImmedValue(); 277 const MachineOperand &IndexReg = MI->getOperand(Op+2); 278 int DispVal = MI->getOperand(Op+3).getImmedValue(); 279 280 O << "["; 281 bool NeedPlus = false; 282 if (BaseReg.getReg()) { 283 printOp(BaseReg); 284 NeedPlus = true; 285 } 286 287 if (IndexReg.getReg()) { 288 if (NeedPlus) O << " + "; 289 if (ScaleVal != 1) 290 O << ScaleVal << "*"; 291 printOp(IndexReg); 292 NeedPlus = true; 293 } 294 295 if (DispVal) { 296 if (NeedPlus) 297 if (DispVal > 0) 298 O << " + "; 299 else { 300 O << " - "; 301 DispVal = -DispVal; 302 } 303 O << DispVal; 304 } 305 O << "]"; 306} 307 308 309/// printMachineInstruction -- Print out a single X86 LLVM instruction 310/// MI in Intel syntax to the current output stream. 311/// 312void X86AsmPrinter::printMachineInstruction(const MachineInstr *MI) { 313 ++EmittedInsts; 314 315 // gas bugs: 316 // 317 // The 80-bit FP store-pop instruction "fstp XWORD PTR [...]" is misassembled 318 // by gas in intel_syntax mode as its 32-bit equivalent "fstp DWORD PTR 319 // [...]". Workaround: Output the raw opcode bytes instead of the instruction. 320 // 321 // The 80-bit FP load instruction "fld XWORD PTR [...]" is misassembled by gas 322 // in intel_syntax mode as its 32-bit equivalent "fld DWORD PTR 323 // [...]". Workaround: Output the raw opcode bytes instead of the instruction. 324 // 325 // gas intel_syntax mode treats "fild QWORD PTR [...]" as an invalid opcode, 326 // saying "64 bit operations are only supported in 64 bit modes." libopcodes 327 // disassembles it as "fild DWORD PTR [...]", which is wrong. Workaround: 328 // Output the raw opcode bytes instead of the instruction. 329 // 330 // gas intel_syntax mode treats "fistp QWORD PTR [...]" as an invalid opcode, 331 // saying "64 bit operations are only supported in 64 bit modes." libopcodes 332 // disassembles it as "fistpll DWORD PTR [...]", which is wrong. Workaround: 333 // Output the raw opcode bytes instead of the instruction. 334 switch (MI->getOpcode()) { 335 case X86::FSTP80m: 336 case X86::FLD80m: 337 case X86::FILD64m: 338 case X86::FISTP64m: 339 GasBugWorkaroundEmitter gwe(O); 340 X86::emitInstruction(gwe, (X86InstrInfo&)*TM.getInstrInfo(), *MI); 341 O << "\t# "; 342 } 343 344 // Call the autogenerated instruction printer routines. 345 bool Handled = printInstruction(MI); 346 if (!Handled) { 347 MI->dump(); 348 assert(0 && "Do not know how to print this instruction!"); 349 abort(); 350 } 351} 352 353bool X86AsmPrinter::doInitialization(Module &M) { 354 AsmPrinter::doInitialization(M); 355 // Tell gas we are outputting Intel syntax (not AT&T syntax) assembly. 356 // 357 // Bug: gas in `intel_syntax noprefix' mode interprets the symbol `Sp' in an 358 // instruction as a reference to the register named sp, and if you try to 359 // reference a symbol `Sp' (e.g. `mov ECX, OFFSET Sp') then it gets lowercased 360 // before being looked up in the symbol table. This creates spurious 361 // `undefined symbol' errors when linking. Workaround: Do not use `noprefix' 362 // mode, and decorate all register names with percent signs. 363 O << "\t.intel_syntax\n"; 364 return false; 365} 366 367// SwitchSection - Switch to the specified section of the executable if we are 368// not already in it! 369// 370static void SwitchSection(std::ostream &OS, std::string &CurSection, 371 const char *NewSection) { 372 if (CurSection != NewSection) { 373 CurSection = NewSection; 374 if (!CurSection.empty()) 375 OS << "\t" << NewSection << "\n"; 376 } 377} 378 379bool X86AsmPrinter::doFinalization(Module &M) { 380 const TargetData &TD = TM.getTargetData(); 381 std::string CurSection; 382 383 // Print out module-level global variables here. 384 for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I) 385 if (I->hasInitializer()) { // External global require no code 386 O << "\n\n"; 387 std::string name = Mang->getValueName(I); 388 Constant *C = I->getInitializer(); 389 unsigned Size = TD.getTypeSize(C->getType()); 390 unsigned Align = TD.getTypeAlignment(C->getType()); 391 392 if (C->isNullValue() && 393 (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || 394 I->hasWeakLinkage() /* FIXME: Verify correct */)) { 395 SwitchSection(O, CurSection, ".data"); 396 if (I->hasInternalLinkage()) 397 O << "\t.local " << name << "\n"; 398 399 O << "\t.comm " << name << "," << TD.getTypeSize(C->getType()) 400 << "," << (unsigned)TD.getTypeAlignment(C->getType()); 401 O << "\t\t# "; 402 WriteAsOperand(O, I, true, true, &M); 403 O << "\n"; 404 } else { 405 switch (I->getLinkage()) { 406 case GlobalValue::LinkOnceLinkage: 407 case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. 408 // Nonnull linkonce -> weak 409 O << "\t.weak " << name << "\n"; 410 SwitchSection(O, CurSection, ""); 411 O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n"; 412 break; 413 414 case GlobalValue::AppendingLinkage: 415 // FIXME: appending linkage variables should go into a section of 416 // their name or something. For now, just emit them as external. 417 case GlobalValue::ExternalLinkage: 418 // If external or appending, declare as a global symbol 419 O << "\t.globl " << name << "\n"; 420 // FALL THROUGH 421 case GlobalValue::InternalLinkage: 422 if (C->isNullValue()) 423 SwitchSection(O, CurSection, ".bss"); 424 else 425 SwitchSection(O, CurSection, ".data"); 426 break; 427 } 428 429 O << "\t.align " << Align << "\n"; 430 O << "\t.type " << name << ",@object\n"; 431 O << "\t.size " << name << "," << Size << "\n"; 432 O << name << ":\t\t\t\t# "; 433 WriteAsOperand(O, I, true, true, &M); 434 O << " = "; 435 WriteAsOperand(O, C, false, false, &M); 436 O << "\n"; 437 emitGlobalConstant(C); 438 } 439 } 440 441 AsmPrinter::doFinalization(M); 442 return false; // success 443} 444