X86AsmPrinter.cpp revision 0e0ed856977c2c105a2ad8f344bce8056f232ae4
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 } 148 149 emitAlignment(Align); 150 O << "\t.type " << name << ",@object\n"; 151 O << "\t.size " << name << "," << Size << "\n"; 152 O << name << ":\t\t\t\t# "; 153 WriteAsOperand(O, I, true, true, &M); 154 O << " = "; 155 WriteAsOperand(O, C, false, false, &M); 156 O << "\n"; 157 emitGlobalConstant(C); 158 } 159 } 160 161 AsmPrinter::doFinalization(M); 162 return false; // success 163} 164 165namespace { 166 struct X86IntelAsmPrinter : public X86SharedAsmPrinter { 167 X86IntelAsmPrinter(std::ostream &O, TargetMachine &TM) 168 : X86SharedAsmPrinter(O, TM) { } 169 170 virtual const char *getPassName() const { 171 return "X86 Intel-Style Assembly Printer"; 172 } 173 174 /// printInstruction - This method is automatically generated by tablegen 175 /// from the instruction set description. This method returns true if the 176 /// machine instruction was sufficiently described to print it, otherwise it 177 /// returns false. 178 bool printInstruction(const MachineInstr *MI); 179 180 // This method is used by the tablegen'erated instruction printer. 181 void printOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT){ 182 const MachineOperand &MO = MI->getOperand(OpNo); 183 if (MO.getType() == MachineOperand::MO_MachineRegister) { 184 assert(MRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physref??"); 185 // Bug Workaround: See note in Printer::doInitialization about %. 186 O << "%" << TM.getRegisterInfo()->get(MO.getReg()).Name; 187 } else { 188 printOp(MO); 189 } 190 } 191 192 void printCallOperand(const MachineInstr *MI, unsigned OpNo, 193 MVT::ValueType VT) { 194 printOp(MI->getOperand(OpNo), true); // Don't print "OFFSET". 195 } 196 197 void printMemoryOperand(const MachineInstr *MI, unsigned OpNo, 198 MVT::ValueType VT) { 199 switch (VT) { 200 default: assert(0 && "Unknown arg size!"); 201 case MVT::i8: O << "BYTE PTR "; break; 202 case MVT::i16: O << "WORD PTR "; break; 203 case MVT::i32: 204 case MVT::f32: O << "DWORD PTR "; break; 205 case MVT::i64: 206 case MVT::f64: O << "QWORD PTR "; break; 207 case MVT::f80: O << "XWORD PTR "; break; 208 } 209 printMemReference(MI, OpNo); 210 } 211 212 void printMachineInstruction(const MachineInstr *MI); 213 void printOp(const MachineOperand &MO, bool elideOffsetKeyword = false); 214 void printMemReference(const MachineInstr *MI, unsigned Op); 215 bool runOnMachineFunction(MachineFunction &F); 216 bool doInitialization(Module &M); 217 }; 218} // end of anonymous namespace 219 220 221// Include the auto-generated portion of the assembly writer. 222#include "X86GenIntelAsmWriter.inc" 223 224 225/// runOnMachineFunction - This uses the printMachineInstruction() 226/// method to print assembly for each instruction. 227/// 228bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 229 setupMachineFunction(MF); 230 O << "\n\n"; 231 232 // Print out constants referenced by the function 233 printConstantPool(MF.getConstantPool()); 234 235 // Print out labels for the function. 236 O << "\t.text\n"; 237 emitAlignment(4); 238 O << "\t.globl\t" << CurrentFnName << "\n"; 239 O << "\t.type\t" << CurrentFnName << ", @function\n"; 240 O << CurrentFnName << ":\n"; 241 242 // Print out code for the function. 243 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 244 I != E; ++I) { 245 // Print a label for the basic block. 246 O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t" 247 << CommentString << " " << I->getBasicBlock()->getName() << "\n"; 248 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 249 II != E; ++II) { 250 // Print the assembly for the instruction. 251 O << "\t"; 252 printMachineInstruction(II); 253 } 254 } 255 256 // We didn't modify anything. 257 return false; 258} 259 260void X86IntelAsmPrinter::printOp(const MachineOperand &MO, 261 bool elideOffsetKeyword /* = false */) { 262 const MRegisterInfo &RI = *TM.getRegisterInfo(); 263 switch (MO.getType()) { 264 case MachineOperand::MO_VirtualRegister: 265 if (Value *V = MO.getVRegValueOrNull()) { 266 O << "<" << V->getName() << ">"; 267 return; 268 } 269 // FALLTHROUGH 270 case MachineOperand::MO_MachineRegister: 271 if (MRegisterInfo::isPhysicalRegister(MO.getReg())) 272 // Bug Workaround: See note in Printer::doInitialization about %. 273 O << "%" << RI.get(MO.getReg()).Name; 274 else 275 O << "%reg" << MO.getReg(); 276 return; 277 278 case MachineOperand::MO_SignExtendedImmed: 279 case MachineOperand::MO_UnextendedImmed: 280 O << (int)MO.getImmedValue(); 281 return; 282 case MachineOperand::MO_MachineBasicBlock: { 283 MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); 284 O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction()) 285 << "_" << MBBOp->getNumber () << "\t# " 286 << MBBOp->getBasicBlock ()->getName (); 287 return; 288 } 289 case MachineOperand::MO_PCRelativeDisp: 290 std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs"; 291 abort (); 292 return; 293 case MachineOperand::MO_GlobalAddress: { 294 if (!elideOffsetKeyword) 295 O << "OFFSET "; 296 O << Mang->getValueName(MO.getGlobal()); 297 int Offset = MO.getOffset(); 298 if (Offset > 0) 299 O << " + " << Offset; 300 else if (Offset < 0) 301 O << " - " << -Offset; 302 return; 303 } 304 case MachineOperand::MO_ExternalSymbol: 305 O << MO.getSymbolName(); 306 return; 307 default: 308 O << "<unknown operand type>"; return; 309 } 310} 311 312void X86IntelAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){ 313 assert(isMem(MI, Op) && "Invalid memory reference!"); 314 315 const MachineOperand &BaseReg = MI->getOperand(Op); 316 int ScaleVal = MI->getOperand(Op+1).getImmedValue(); 317 const MachineOperand &IndexReg = MI->getOperand(Op+2); 318 const MachineOperand &DispSpec = MI->getOperand(Op+3); 319 320 if (BaseReg.isFrameIndex()) { 321 O << "[frame slot #" << BaseReg.getFrameIndex(); 322 if (DispSpec.getImmedValue()) 323 O << " + " << DispSpec.getImmedValue(); 324 O << "]"; 325 return; 326 } else if (BaseReg.isConstantPoolIndex()) { 327 O << "[.CPI" << CurrentFnName << "_" 328 << BaseReg.getConstantPoolIndex(); 329 330 if (IndexReg.getReg()) { 331 O << " + "; 332 if (ScaleVal != 1) 333 O << ScaleVal << "*"; 334 printOp(IndexReg); 335 } 336 337 if (DispSpec.getImmedValue()) 338 O << " + " << DispSpec.getImmedValue(); 339 O << "]"; 340 return; 341 } 342 343 O << "["; 344 bool NeedPlus = false; 345 if (BaseReg.getReg()) { 346 printOp(BaseReg, true); 347 NeedPlus = true; 348 } 349 350 if (IndexReg.getReg()) { 351 if (NeedPlus) O << " + "; 352 if (ScaleVal != 1) 353 O << ScaleVal << "*"; 354 printOp(IndexReg); 355 NeedPlus = true; 356 } 357 358 if (DispSpec.isGlobalAddress()) { 359 if (NeedPlus) 360 O << " + "; 361 printOp(DispSpec, true); 362 } else { 363 int DispVal = DispSpec.getImmedValue(); 364 if (DispVal) { 365 if (NeedPlus) 366 if (DispVal > 0) 367 O << " + "; 368 else { 369 O << " - "; 370 DispVal = -DispVal; 371 } 372 O << DispVal; 373 } 374 } 375 O << "]"; 376} 377 378 379/// printMachineInstruction -- Print out a single X86 LLVM instruction 380/// MI in Intel syntax to the current output stream. 381/// 382void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) { 383 ++EmittedInsts; 384 385 // Call the autogenerated instruction printer routines. 386 printInstruction(MI); 387} 388 389bool X86IntelAsmPrinter::doInitialization(Module &M) { 390 AsmPrinter::doInitialization(M); 391 // Tell gas we are outputting Intel syntax (not AT&T syntax) assembly. 392 // 393 // Bug: gas in `intel_syntax noprefix' mode interprets the symbol `Sp' in an 394 // instruction as a reference to the register named sp, and if you try to 395 // reference a symbol `Sp' (e.g. `mov ECX, OFFSET Sp') then it gets lowercased 396 // before being looked up in the symbol table. This creates spurious 397 // `undefined symbol' errors when linking. Workaround: Do not use `noprefix' 398 // mode, and decorate all register names with percent signs. 399 O << "\t.intel_syntax\n"; 400 return false; 401} 402 403 404 405namespace { 406 struct X86ATTAsmPrinter : public X86SharedAsmPrinter { 407 X86ATTAsmPrinter(std::ostream &O, TargetMachine &TM) 408 : X86SharedAsmPrinter(O, TM) { } 409 410 virtual const char *getPassName() const { 411 return "X86 AT&T-Style Assembly Printer"; 412 } 413 414 /// printInstruction - This method is automatically generated by tablegen 415 /// from the instruction set description. This method returns true if the 416 /// machine instruction was sufficiently described to print it, otherwise it 417 /// returns false. 418 bool printInstruction(const MachineInstr *MI); 419 420 // This method is used by the tablegen'erated instruction printer. 421 void printOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT){ 422 printOp(MI->getOperand(OpNo)); 423 } 424 425 void printCallOperand(const MachineInstr *MI, unsigned OpNo, 426 MVT::ValueType VT) { 427 printOp(MI->getOperand(OpNo), true); // Don't print '$' prefix. 428 } 429 430 void printMemoryOperand(const MachineInstr *MI, unsigned OpNo, 431 MVT::ValueType VT) { 432 printMemReference(MI, OpNo); 433 } 434 435 void printMachineInstruction(const MachineInstr *MI); 436 void printOp(const MachineOperand &MO, bool isCallOperand = false); 437 void printMemReference(const MachineInstr *MI, unsigned Op); 438 bool runOnMachineFunction(MachineFunction &F); 439 }; 440} // end of anonymous namespace 441 442 443// Include the auto-generated portion of the assembly writer. 444#include "X86GenATTAsmWriter.inc" 445 446 447/// runOnMachineFunction - This uses the printMachineInstruction() 448/// method to print assembly for each instruction. 449/// 450bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 451 setupMachineFunction(MF); 452 O << "\n\n"; 453 454 // Print out constants referenced by the function 455 printConstantPool(MF.getConstantPool()); 456 457 // Print out labels for the function. 458 O << "\t.text\n"; 459 emitAlignment(4); 460 O << "\t.globl\t" << CurrentFnName << "\n"; 461 O << "\t.type\t" << CurrentFnName << ", @function\n"; 462 O << CurrentFnName << ":\n"; 463 464 // Print out code for the function. 465 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 466 I != E; ++I) { 467 // Print a label for the basic block. 468 O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t" 469 << CommentString << " " << I->getBasicBlock()->getName() << "\n"; 470 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 471 II != E; ++II) { 472 // Print the assembly for the instruction. 473 O << "\t"; 474 printMachineInstruction(II); 475 } 476 } 477 478 // We didn't modify anything. 479 return false; 480} 481 482void X86ATTAsmPrinter::printOp(const MachineOperand &MO, bool isCallOp) { 483 const MRegisterInfo &RI = *TM.getRegisterInfo(); 484 switch (MO.getType()) { 485 case MachineOperand::MO_VirtualRegister: 486 case MachineOperand::MO_MachineRegister: 487 assert(MRegisterInfo::isPhysicalRegister(MO.getReg()) && 488 "Virtual registers should not make it this far!"); 489 O << '%'; 490 for (const char *Name = RI.get(MO.getReg()).Name; *Name; ++Name) 491 O << (char)tolower(*Name); 492 return; 493 494 case MachineOperand::MO_SignExtendedImmed: 495 case MachineOperand::MO_UnextendedImmed: 496 O << '$' << (int)MO.getImmedValue(); 497 return; 498 case MachineOperand::MO_MachineBasicBlock: { 499 MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); 500 O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction()) 501 << "_" << MBBOp->getNumber () << "\t# " 502 << MBBOp->getBasicBlock ()->getName (); 503 return; 504 } 505 case MachineOperand::MO_PCRelativeDisp: 506 std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs"; 507 abort (); 508 return; 509 case MachineOperand::MO_GlobalAddress: { 510 if (!isCallOp) O << '$'; 511 O << Mang->getValueName(MO.getGlobal()); 512 int Offset = MO.getOffset(); 513 if (Offset > 0) 514 O << "+" << Offset; 515 else if (Offset < 0) 516 O << Offset; 517 return; 518 } 519 case MachineOperand::MO_ExternalSymbol: 520 if (!isCallOp) O << '$'; 521 O << MO.getSymbolName(); 522 return; 523 default: 524 O << "<unknown operand type>"; return; 525 } 526} 527 528void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){ 529 assert(isMem(MI, Op) && "Invalid memory reference!"); 530 531 const MachineOperand &BaseReg = MI->getOperand(Op); 532 int ScaleVal = MI->getOperand(Op+1).getImmedValue(); 533 const MachineOperand &IndexReg = MI->getOperand(Op+2); 534 const MachineOperand &DispSpec = MI->getOperand(Op+3); 535 536 if (BaseReg.isFrameIndex()) { 537 O << "[frame slot #" << BaseReg.getFrameIndex(); 538 if (DispSpec.getImmedValue()) 539 O << " + " << DispSpec.getImmedValue(); 540 O << "]"; 541 return; 542 } else if (BaseReg.isConstantPoolIndex()) { 543 O << ".CPI" << CurrentFnName << "_" 544 << BaseReg.getConstantPoolIndex(); 545 if (DispSpec.getImmedValue()) 546 O << "+" << DispSpec.getImmedValue(); 547 if (IndexReg.getReg()) { 548 O << "(,"; 549 printOp(IndexReg); 550 if (ScaleVal != 1) 551 O << "," << ScaleVal; 552 O << ")"; 553 } 554 return; 555 } 556 557 if (DispSpec.isGlobalAddress()) { 558 printOp(DispSpec, true); 559 } else { 560 int DispVal = DispSpec.getImmedValue(); 561 if (DispVal) 562 O << DispVal; 563 } 564 565 if (IndexReg.getReg() || BaseReg.getReg()) { 566 O << "("; 567 if (BaseReg.getReg()) 568 printOp(BaseReg); 569 570 if (IndexReg.getReg()) { 571 O << ","; 572 printOp(IndexReg); 573 if (ScaleVal != 1) 574 O << "," << ScaleVal; 575 } 576 577 O << ")"; 578 } 579} 580 581 582/// printMachineInstruction -- Print out a single X86 LLVM instruction 583/// MI in Intel syntax to the current output stream. 584/// 585void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) { 586 ++EmittedInsts; 587 // Call the autogenerated instruction printer routines. 588 printInstruction(MI); 589} 590 591 592/// createX86CodePrinterPass - Returns a pass that prints the X86 assembly code 593/// for a MachineFunction to the given output stream, using the given target 594/// machine description. 595/// 596FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,TargetMachine &tm){ 597 switch (AsmWriterFlavor) { 598 default: assert(0 && "Unknown asm flavor!"); 599 case intel: 600 return new X86IntelAsmPrinter(o, tm); 601 case att: 602 return new X86ATTAsmPrinter(o, tm); 603 } 604} 605