X86AsmPrinter.cpp revision 5b3a4553c1da7e417a240379e2f510c77532c5c1
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 and AT&T format assembly 12// language. This printer is the output mechanism used by `llc' and `lli 13// -print-machineinstrs' on X86. 14// 15//===----------------------------------------------------------------------===// 16 17#include "X86.h" 18#include "X86TargetMachine.h" 19#include "llvm/Module.h" 20#include "llvm/Type.h" 21#include "llvm/Assembly/Writer.h" 22#include "llvm/CodeGen/AsmPrinter.h" 23#include "llvm/CodeGen/MachineConstantPool.h" 24#include "llvm/CodeGen/MachineFunctionPass.h" 25#include "llvm/CodeGen/ValueTypes.h" 26#include "llvm/Target/TargetMachine.h" 27#include "llvm/Support/Mangler.h" 28#include "llvm/ADT/Statistic.h" 29#include "llvm/Support/CommandLine.h" 30using namespace llvm; 31 32namespace { 33 Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); 34 enum AsmWriterFlavor { att, intel }; 35 36 cl::opt<AsmWriterFlavor> 37 AsmWriterFlavor("x86-asm-syntax", 38 cl::desc("Choose style of code to emit from X86 backend:"), 39 cl::values( 40 clEnumVal(att, " Emit AT&T-style assembly"), 41 clEnumVal(intel, " Emit Intel-style assembly"), 42 clEnumValEnd), 43 cl::init(att)); 44 45 struct X86SharedAsmPrinter : public AsmPrinter { 46 X86SharedAsmPrinter(std::ostream &O, TargetMachine &TM) 47 : AsmPrinter(O, TM), forCygwin(false) { } 48 49 bool doInitialization(Module &M); 50 void printConstantPool(MachineConstantPool *MCP); 51 bool doFinalization(Module &M); 52 bool forCygwin; 53 }; 54} 55 56static bool isScale(const MachineOperand &MO) { 57 return MO.isImmediate() && 58 (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 || 59 MO.getImmedValue() == 4 || MO.getImmedValue() == 8); 60} 61 62static bool isMem(const MachineInstr *MI, unsigned Op) { 63 if (MI->getOperand(Op).isFrameIndex()) return true; 64 if (MI->getOperand(Op).isConstantPoolIndex()) return true; 65 return Op+4 <= MI->getNumOperands() && 66 MI->getOperand(Op ).isRegister() && isScale(MI->getOperand(Op+1)) && 67 MI->getOperand(Op+2).isRegister() && (MI->getOperand(Op+3).isImmediate() || 68 MI->getOperand(Op+3).isGlobalAddress()); 69} 70 71// SwitchSection - Switch to the specified section of the executable if we are 72// not already in it! 73// 74static void SwitchSection(std::ostream &OS, std::string &CurSection, 75 const char *NewSection) { 76 if (CurSection != NewSection) { 77 CurSection = NewSection; 78 if (!CurSection.empty()) 79 OS << "\t" << NewSection << "\n"; 80 } 81} 82 83/// doInitialization - determine 84bool X86SharedAsmPrinter::doInitialization(Module& M) { 85 forCygwin = false; 86 const std::string& TT = M.getTargetTriple(); 87 if (TT.length() > 5) 88 forCygwin = TT.find("cygwin") != std::string::npos || 89 TT.find("mingw") != std::string::npos; 90 else if (TT.empty()) { 91#if defined(__CYGWIN__) || defined(__MINGW32__) 92 forCygwin = true; 93#else 94 forCygwin = false; 95#endif 96 } 97 if (forCygwin) 98 GlobalPrefix = "_"; 99 return AsmPrinter::doInitialization(M); 100} 101 102/// printConstantPool - Print to the current output stream assembly 103/// representations of the constants in the constant pool MCP. This is 104/// used to print out constants which have been "spilled to memory" by 105/// the code generator. 106/// 107void X86SharedAsmPrinter::printConstantPool(MachineConstantPool *MCP) { 108 const std::vector<Constant*> &CP = MCP->getConstants(); 109 const TargetData &TD = TM.getTargetData(); 110 111 if (CP.empty()) return; 112 113 for (unsigned i = 0, e = CP.size(); i != e; ++i) { 114 O << "\t.section .rodata\n"; 115 emitAlignment(TD.getTypeAlignmentShift(CP[i]->getType())); 116 O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t" << CommentString 117 << *CP[i] << "\n"; 118 emitGlobalConstant(CP[i]); 119 } 120} 121 122bool X86SharedAsmPrinter::doFinalization(Module &M) { 123 const TargetData &TD = TM.getTargetData(); 124 std::string CurSection; 125 126 // Print out module-level global variables here. 127 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) 128 if (I->hasInitializer()) { // External global require no code 129 O << "\n\n"; 130 std::string name = Mang->getValueName(I); 131 Constant *C = I->getInitializer(); 132 unsigned Size = TD.getTypeSize(C->getType()); 133 unsigned Align = TD.getTypeAlignmentShift(C->getType()); 134 135 if (C->isNullValue() && 136 (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || 137 I->hasWeakLinkage() /* FIXME: Verify correct */)) { 138 SwitchSection(O, CurSection, ".data"); 139 if (!forCygwin && I->hasInternalLinkage()) 140 O << "\t.local " << name << "\n"; 141 142 O << "\t.comm " << name << "," << TD.getTypeSize(C->getType()); 143 if (!forCygwin) 144 O << "," << (1 << Align); 145 O << "\t\t# "; 146 WriteAsOperand(O, I, true, true, &M); 147 O << "\n"; 148 } else { 149 switch (I->getLinkage()) { 150 case GlobalValue::LinkOnceLinkage: 151 case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. 152 // Nonnull linkonce -> weak 153 O << "\t.weak " << name << "\n"; 154 SwitchSection(O, CurSection, ""); 155 O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n"; 156 break; 157 case GlobalValue::AppendingLinkage: 158 // FIXME: appending linkage variables should go into a section of 159 // their name or something. For now, just emit them as external. 160 case GlobalValue::ExternalLinkage: 161 // If external or appending, declare as a global symbol 162 O << "\t.globl " << name << "\n"; 163 // FALL THROUGH 164 case GlobalValue::InternalLinkage: 165 if (C->isNullValue()) 166 SwitchSection(O, CurSection, ".bss"); 167 else 168 SwitchSection(O, CurSection, ".data"); 169 break; 170 case GlobalValue::GhostLinkage: 171 std::cerr << "GhostLinkage cannot appear in X86AsmPrinter!\n"; 172 abort(); 173 } 174 175 emitAlignment(Align); 176 if (!forCygwin) { 177 O << "\t.type " << name << ",@object\n"; 178 O << "\t.size " << name << "," << Size << "\n"; 179 } 180 O << name << ":\t\t\t\t# "; 181 WriteAsOperand(O, I, true, true, &M); 182 O << " = "; 183 WriteAsOperand(O, C, false, false, &M); 184 O << "\n"; 185 emitGlobalConstant(C); 186 } 187 } 188 189 AsmPrinter::doFinalization(M); 190 return false; // success 191} 192 193namespace { 194 struct X86IntelAsmPrinter : public X86SharedAsmPrinter { 195 X86IntelAsmPrinter(std::ostream &O, TargetMachine &TM) 196 : X86SharedAsmPrinter(O, TM) { } 197 198 virtual const char *getPassName() const { 199 return "X86 Intel-Style Assembly Printer"; 200 } 201 202 /// printInstruction - This method is automatically generated by tablegen 203 /// from the instruction set description. This method returns true if the 204 /// machine instruction was sufficiently described to print it, otherwise it 205 /// returns false. 206 bool printInstruction(const MachineInstr *MI); 207 208 // This method is used by the tablegen'erated instruction printer. 209 void printOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT){ 210 const MachineOperand &MO = MI->getOperand(OpNo); 211 if (MO.getType() == MachineOperand::MO_MachineRegister) { 212 assert(MRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physref??"); 213 // Bug Workaround: See note in Printer::doInitialization about %. 214 O << "%" << TM.getRegisterInfo()->get(MO.getReg()).Name; 215 } else { 216 printOp(MO); 217 } 218 } 219 220 void printCallOperand(const MachineInstr *MI, unsigned OpNo, 221 MVT::ValueType VT) { 222 printOp(MI->getOperand(OpNo), true); // Don't print "OFFSET". 223 } 224 225 void printMemoryOperand(const MachineInstr *MI, unsigned OpNo, 226 MVT::ValueType VT) { 227 switch (VT) { 228 default: assert(0 && "Unknown arg size!"); 229 case MVT::i8: O << "BYTE PTR "; break; 230 case MVT::i16: O << "WORD PTR "; break; 231 case MVT::i32: 232 case MVT::f32: O << "DWORD PTR "; break; 233 case MVT::i64: 234 case MVT::f64: O << "QWORD PTR "; break; 235 case MVT::f80: O << "XWORD PTR "; break; 236 } 237 printMemReference(MI, OpNo); 238 } 239 240 void printMachineInstruction(const MachineInstr *MI); 241 void printOp(const MachineOperand &MO, bool elideOffsetKeyword = false); 242 void printMemReference(const MachineInstr *MI, unsigned Op); 243 bool runOnMachineFunction(MachineFunction &F); 244 bool doInitialization(Module &M); 245 }; 246} // end of anonymous namespace 247 248 249// Include the auto-generated portion of the assembly writer. 250#include "X86GenAsmWriter1.inc" 251 252 253/// runOnMachineFunction - This uses the printMachineInstruction() 254/// method to print assembly for each instruction. 255/// 256bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 257 setupMachineFunction(MF); 258 O << "\n\n"; 259 260 // Print out constants referenced by the function 261 printConstantPool(MF.getConstantPool()); 262 263 // Print out labels for the function. 264 O << "\t.text\n"; 265 emitAlignment(4); 266 O << "\t.globl\t" << CurrentFnName << "\n"; 267 if (!forCygwin) 268 O << "\t.type\t" << CurrentFnName << ", @function\n"; 269 O << CurrentFnName << ":\n"; 270 271 // Print out code for the function. 272 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 273 I != E; ++I) { 274 // Print a label for the basic block if there are any predecessors. 275 if (I->pred_begin() != I->pred_end()) 276 O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t" 277 << CommentString << " " << I->getBasicBlock()->getName() << "\n"; 278 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 279 II != E; ++II) { 280 // Print the assembly for the instruction. 281 O << "\t"; 282 printMachineInstruction(II); 283 } 284 } 285 286 // We didn't modify anything. 287 return false; 288} 289 290void X86IntelAsmPrinter::printOp(const MachineOperand &MO, 291 bool elideOffsetKeyword /* = false */) { 292 const MRegisterInfo &RI = *TM.getRegisterInfo(); 293 switch (MO.getType()) { 294 case MachineOperand::MO_VirtualRegister: 295 if (Value *V = MO.getVRegValueOrNull()) { 296 O << "<" << V->getName() << ">"; 297 return; 298 } 299 // FALLTHROUGH 300 case MachineOperand::MO_MachineRegister: 301 if (MRegisterInfo::isPhysicalRegister(MO.getReg())) 302 // Bug Workaround: See note in Printer::doInitialization about %. 303 O << "%" << RI.get(MO.getReg()).Name; 304 else 305 O << "%reg" << MO.getReg(); 306 return; 307 308 case MachineOperand::MO_SignExtendedImmed: 309 case MachineOperand::MO_UnextendedImmed: 310 O << (int)MO.getImmedValue(); 311 return; 312 case MachineOperand::MO_MachineBasicBlock: { 313 MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); 314 O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction()) 315 << "_" << MBBOp->getNumber () << "\t# " 316 << MBBOp->getBasicBlock ()->getName (); 317 return; 318 } 319 case MachineOperand::MO_PCRelativeDisp: 320 std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs"; 321 abort (); 322 return; 323 case MachineOperand::MO_GlobalAddress: { 324 if (!elideOffsetKeyword) 325 O << "OFFSET "; 326 O << Mang->getValueName(MO.getGlobal()); 327 int Offset = MO.getOffset(); 328 if (Offset > 0) 329 O << " + " << Offset; 330 else if (Offset < 0) 331 O << " - " << -Offset; 332 return; 333 } 334 case MachineOperand::MO_ExternalSymbol: 335 O << GlobalPrefix << MO.getSymbolName(); 336 return; 337 default: 338 O << "<unknown operand type>"; return; 339 } 340} 341 342void X86IntelAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){ 343 assert(isMem(MI, Op) && "Invalid memory reference!"); 344 345 const MachineOperand &BaseReg = MI->getOperand(Op); 346 int ScaleVal = MI->getOperand(Op+1).getImmedValue(); 347 const MachineOperand &IndexReg = MI->getOperand(Op+2); 348 const MachineOperand &DispSpec = MI->getOperand(Op+3); 349 350 if (BaseReg.isFrameIndex()) { 351 O << "[frame slot #" << BaseReg.getFrameIndex(); 352 if (DispSpec.getImmedValue()) 353 O << " + " << DispSpec.getImmedValue(); 354 O << "]"; 355 return; 356 } else if (BaseReg.isConstantPoolIndex()) { 357 O << "[.CPI" << CurrentFnName << "_" 358 << BaseReg.getConstantPoolIndex(); 359 360 if (IndexReg.getReg()) { 361 O << " + "; 362 if (ScaleVal != 1) 363 O << ScaleVal << "*"; 364 printOp(IndexReg); 365 } 366 367 if (DispSpec.getImmedValue()) 368 O << " + " << DispSpec.getImmedValue(); 369 O << "]"; 370 return; 371 } 372 373 O << "["; 374 bool NeedPlus = false; 375 if (BaseReg.getReg()) { 376 printOp(BaseReg, true); 377 NeedPlus = true; 378 } 379 380 if (IndexReg.getReg()) { 381 if (NeedPlus) O << " + "; 382 if (ScaleVal != 1) 383 O << ScaleVal << "*"; 384 printOp(IndexReg); 385 NeedPlus = true; 386 } 387 388 if (DispSpec.isGlobalAddress()) { 389 if (NeedPlus) 390 O << " + "; 391 printOp(DispSpec, true); 392 } else { 393 int DispVal = DispSpec.getImmedValue(); 394 if (DispVal || (!BaseReg.getReg() && !IndexReg.getReg())) { 395 if (NeedPlus) 396 if (DispVal > 0) 397 O << " + "; 398 else { 399 O << " - "; 400 DispVal = -DispVal; 401 } 402 O << DispVal; 403 } 404 } 405 O << "]"; 406} 407 408 409/// printMachineInstruction -- Print out a single X86 LLVM instruction 410/// MI in Intel syntax to the current output stream. 411/// 412void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) { 413 ++EmittedInsts; 414 415 // Call the autogenerated instruction printer routines. 416 printInstruction(MI); 417} 418 419bool X86IntelAsmPrinter::doInitialization(Module &M) { 420 AsmPrinter::doInitialization(M); 421 // Tell gas we are outputting Intel syntax (not AT&T syntax) assembly. 422 // 423 // Bug: gas in `intel_syntax noprefix' mode interprets the symbol `Sp' in an 424 // instruction as a reference to the register named sp, and if you try to 425 // reference a symbol `Sp' (e.g. `mov ECX, OFFSET Sp') then it gets lowercased 426 // before being looked up in the symbol table. This creates spurious 427 // `undefined symbol' errors when linking. Workaround: Do not use `noprefix' 428 // mode, and decorate all register names with percent signs. 429 O << "\t.intel_syntax\n"; 430 return false; 431} 432 433 434 435namespace { 436 struct X86ATTAsmPrinter : public X86SharedAsmPrinter { 437 X86ATTAsmPrinter(std::ostream &O, TargetMachine &TM) 438 : X86SharedAsmPrinter(O, TM) { } 439 440 virtual const char *getPassName() const { 441 return "X86 AT&T-Style Assembly Printer"; 442 } 443 444 /// printInstruction - This method is automatically generated by tablegen 445 /// from the instruction set description. This method returns true if the 446 /// machine instruction was sufficiently described to print it, otherwise it 447 /// returns false. 448 bool printInstruction(const MachineInstr *MI); 449 450 // This method is used by the tablegen'erated instruction printer. 451 void printOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT){ 452 printOp(MI->getOperand(OpNo)); 453 } 454 455 void printCallOperand(const MachineInstr *MI, unsigned OpNo, 456 MVT::ValueType VT) { 457 printOp(MI->getOperand(OpNo), true); // Don't print '$' prefix. 458 } 459 460 void printMemoryOperand(const MachineInstr *MI, unsigned OpNo, 461 MVT::ValueType VT) { 462 printMemReference(MI, OpNo); 463 } 464 465 void printMachineInstruction(const MachineInstr *MI); 466 void printOp(const MachineOperand &MO, bool isCallOperand = false); 467 void printMemReference(const MachineInstr *MI, unsigned Op); 468 bool runOnMachineFunction(MachineFunction &F); 469 }; 470} // end of anonymous namespace 471 472 473// Include the auto-generated portion of the assembly writer. 474#include "X86GenAsmWriter.inc" 475 476 477/// runOnMachineFunction - This uses the printMachineInstruction() 478/// method to print assembly for each instruction. 479/// 480bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 481 setupMachineFunction(MF); 482 O << "\n\n"; 483 484 // Print out constants referenced by the function 485 printConstantPool(MF.getConstantPool()); 486 487 // Print out labels for the function. 488 O << "\t.text\n"; 489 emitAlignment(4); 490 O << "\t.globl\t" << CurrentFnName << "\n"; 491 if (!forCygwin) 492 O << "\t.type\t" << CurrentFnName << ", @function\n"; 493 O << CurrentFnName << ":\n"; 494 495 // Print out code for the function. 496 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 497 I != E; ++I) { 498 // Print a label for the basic block. 499 if (I->pred_begin() != I->pred_end()) 500 O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t" 501 << CommentString << " " << I->getBasicBlock()->getName() << "\n"; 502 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 503 II != E; ++II) { 504 // Print the assembly for the instruction. 505 O << "\t"; 506 printMachineInstruction(II); 507 } 508 } 509 510 // We didn't modify anything. 511 return false; 512} 513 514void X86ATTAsmPrinter::printOp(const MachineOperand &MO, bool isCallOp) { 515 const MRegisterInfo &RI = *TM.getRegisterInfo(); 516 switch (MO.getType()) { 517 case MachineOperand::MO_VirtualRegister: 518 case MachineOperand::MO_MachineRegister: 519 assert(MRegisterInfo::isPhysicalRegister(MO.getReg()) && 520 "Virtual registers should not make it this far!"); 521 O << '%'; 522 for (const char *Name = RI.get(MO.getReg()).Name; *Name; ++Name) 523 O << (char)tolower(*Name); 524 return; 525 526 case MachineOperand::MO_SignExtendedImmed: 527 case MachineOperand::MO_UnextendedImmed: 528 O << '$' << (int)MO.getImmedValue(); 529 return; 530 case MachineOperand::MO_MachineBasicBlock: { 531 MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); 532 O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction()) 533 << "_" << MBBOp->getNumber () << "\t# " 534 << MBBOp->getBasicBlock ()->getName (); 535 return; 536 } 537 case MachineOperand::MO_PCRelativeDisp: 538 std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs"; 539 abort (); 540 return; 541 case MachineOperand::MO_GlobalAddress: { 542 if (!isCallOp) O << '$'; 543 O << Mang->getValueName(MO.getGlobal()); 544 int Offset = MO.getOffset(); 545 if (Offset > 0) 546 O << "+" << Offset; 547 else if (Offset < 0) 548 O << Offset; 549 return; 550 } 551 case MachineOperand::MO_ExternalSymbol: 552 if (!isCallOp) O << '$'; 553 O << GlobalPrefix << MO.getSymbolName(); 554 return; 555 default: 556 O << "<unknown operand type>"; return; 557 } 558} 559 560void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){ 561 assert(isMem(MI, Op) && "Invalid memory reference!"); 562 563 const MachineOperand &BaseReg = MI->getOperand(Op); 564 int ScaleVal = MI->getOperand(Op+1).getImmedValue(); 565 const MachineOperand &IndexReg = MI->getOperand(Op+2); 566 const MachineOperand &DispSpec = MI->getOperand(Op+3); 567 568 if (BaseReg.isFrameIndex()) { 569 O << "[frame slot #" << BaseReg.getFrameIndex(); 570 if (DispSpec.getImmedValue()) 571 O << " + " << DispSpec.getImmedValue(); 572 O << "]"; 573 return; 574 } else if (BaseReg.isConstantPoolIndex()) { 575 O << ".CPI" << CurrentFnName << "_" 576 << BaseReg.getConstantPoolIndex(); 577 if (DispSpec.getImmedValue()) 578 O << "+" << DispSpec.getImmedValue(); 579 if (IndexReg.getReg()) { 580 O << "(,"; 581 printOp(IndexReg); 582 if (ScaleVal != 1) 583 O << "," << ScaleVal; 584 O << ")"; 585 } 586 return; 587 } 588 589 if (DispSpec.isGlobalAddress()) { 590 printOp(DispSpec, true); 591 } else { 592 int DispVal = DispSpec.getImmedValue(); 593 if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) 594 O << DispVal; 595 } 596 597 if (IndexReg.getReg() || BaseReg.getReg()) { 598 O << "("; 599 if (BaseReg.getReg()) 600 printOp(BaseReg); 601 602 if (IndexReg.getReg()) { 603 O << ","; 604 printOp(IndexReg); 605 if (ScaleVal != 1) 606 O << "," << ScaleVal; 607 } 608 609 O << ")"; 610 } 611} 612 613 614/// printMachineInstruction -- Print out a single X86 LLVM instruction 615/// MI in Intel syntax to the current output stream. 616/// 617void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) { 618 ++EmittedInsts; 619 // Call the autogenerated instruction printer routines. 620 printInstruction(MI); 621} 622 623 624/// createX86CodePrinterPass - Returns a pass that prints the X86 assembly code 625/// for a MachineFunction to the given output stream, using the given target 626/// machine description. 627/// 628FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,TargetMachine &tm){ 629 switch (AsmWriterFlavor) { 630 default: 631 assert(0 && "Unknown asm flavor!"); 632 case intel: 633 return new X86IntelAsmPrinter(o, tm); 634 case att: 635 return new X86ATTAsmPrinter(o, tm); 636 } 637} 638