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