X86AsmPrinter.cpp revision d416f086cc97976abd4f40adadb3956763ffe4b0
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 if (MI->getOperand(Op).isFrameIndex()) { 316 O << "[frame slot #" << MI->getOperand(Op).getFrameIndex(); 317 if (MI->getOperand(Op+3).getImmedValue()) 318 O << " + " << MI->getOperand(Op+3).getImmedValue(); 319 O << "]"; 320 return; 321 } else if (MI->getOperand(Op).isConstantPoolIndex()) { 322 O << "[.CPI" << CurrentFnName << "_" 323 << MI->getOperand(Op).getConstantPoolIndex(); 324 if (MI->getOperand(Op+3).getImmedValue()) 325 O << " + " << MI->getOperand(Op+3).getImmedValue(); 326 O << "]"; 327 return; 328 } 329 330 const MachineOperand &BaseReg = MI->getOperand(Op); 331 int ScaleVal = MI->getOperand(Op+1).getImmedValue(); 332 const MachineOperand &IndexReg = MI->getOperand(Op+2); 333 const MachineOperand &DispSpec = MI->getOperand(Op+3); 334 335 O << "["; 336 bool NeedPlus = false; 337 if (BaseReg.getReg()) { 338 printOp(BaseReg, true); 339 NeedPlus = true; 340 } 341 342 if (IndexReg.getReg()) { 343 if (NeedPlus) O << " + "; 344 if (ScaleVal != 1) 345 O << ScaleVal << "*"; 346 printOp(IndexReg); 347 NeedPlus = true; 348 } 349 350 if (DispSpec.isGlobalAddress()) { 351 if (NeedPlus) 352 O << " + "; 353 printOp(DispSpec, true); 354 } else { 355 int DispVal = DispSpec.getImmedValue(); 356 if (DispVal) { 357 if (NeedPlus) 358 if (DispVal > 0) 359 O << " + "; 360 else { 361 O << " - "; 362 DispVal = -DispVal; 363 } 364 O << DispVal; 365 } 366 } 367 O << "]"; 368} 369 370 371/// printMachineInstruction -- Print out a single X86 LLVM instruction 372/// MI in Intel syntax to the current output stream. 373/// 374void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) { 375 ++EmittedInsts; 376 377 // Call the autogenerated instruction printer routines. 378 printInstruction(MI); 379} 380 381bool X86IntelAsmPrinter::doInitialization(Module &M) { 382 AsmPrinter::doInitialization(M); 383 // Tell gas we are outputting Intel syntax (not AT&T syntax) assembly. 384 // 385 // Bug: gas in `intel_syntax noprefix' mode interprets the symbol `Sp' in an 386 // instruction as a reference to the register named sp, and if you try to 387 // reference a symbol `Sp' (e.g. `mov ECX, OFFSET Sp') then it gets lowercased 388 // before being looked up in the symbol table. This creates spurious 389 // `undefined symbol' errors when linking. Workaround: Do not use `noprefix' 390 // mode, and decorate all register names with percent signs. 391 O << "\t.intel_syntax\n"; 392 return false; 393} 394 395 396 397namespace { 398 struct X86ATTAsmPrinter : public X86SharedAsmPrinter { 399 X86ATTAsmPrinter(std::ostream &O, TargetMachine &TM) 400 : X86SharedAsmPrinter(O, TM) { } 401 402 virtual const char *getPassName() const { 403 return "X86 AT&T-Style Assembly Printer"; 404 } 405 406 /// printInstruction - This method is automatically generated by tablegen 407 /// from the instruction set description. This method returns true if the 408 /// machine instruction was sufficiently described to print it, otherwise it 409 /// returns false. 410 bool printInstruction(const MachineInstr *MI); 411 412 // This method is used by the tablegen'erated instruction printer. 413 void printOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT){ 414 printOp(MI->getOperand(OpNo)); 415 } 416 417 void printCallOperand(const MachineInstr *MI, unsigned OpNo, 418 MVT::ValueType VT) { 419 printOp(MI->getOperand(OpNo), true); // Don't print '$' prefix. 420 } 421 422 void printMemoryOperand(const MachineInstr *MI, unsigned OpNo, 423 MVT::ValueType VT) { 424 printMemReference(MI, OpNo); 425 } 426 427 void printMachineInstruction(const MachineInstr *MI); 428 void printOp(const MachineOperand &MO, bool isCallOperand = false); 429 void printMemReference(const MachineInstr *MI, unsigned Op); 430 bool runOnMachineFunction(MachineFunction &F); 431 }; 432} // end of anonymous namespace 433 434 435// Include the auto-generated portion of the assembly writer. 436#include "X86GenATTAsmWriter.inc" 437 438 439/// runOnMachineFunction - This uses the printMachineInstruction() 440/// method to print assembly for each instruction. 441/// 442bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 443 setupMachineFunction(MF); 444 O << "\n\n"; 445 446 // Print out constants referenced by the function 447 printConstantPool(MF.getConstantPool()); 448 449 // Print out labels for the function. 450 O << "\t.text\n"; 451 emitAlignment(4); 452 O << "\t.globl\t" << CurrentFnName << "\n"; 453 O << "\t.type\t" << CurrentFnName << ", @function\n"; 454 O << CurrentFnName << ":\n"; 455 456 // Print out code for the function. 457 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 458 I != E; ++I) { 459 // Print a label for the basic block. 460 O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t" 461 << CommentString << " " << I->getBasicBlock()->getName() << "\n"; 462 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 463 II != E; ++II) { 464 // Print the assembly for the instruction. 465 O << "\t"; 466 printMachineInstruction(II); 467 } 468 } 469 470 // We didn't modify anything. 471 return false; 472} 473 474void X86ATTAsmPrinter::printOp(const MachineOperand &MO, bool isCallOp) { 475 const MRegisterInfo &RI = *TM.getRegisterInfo(); 476 switch (MO.getType()) { 477 case MachineOperand::MO_VirtualRegister: 478 case MachineOperand::MO_MachineRegister: 479 assert(MRegisterInfo::isPhysicalRegister(MO.getReg()) && 480 "Virtual registers should not make it this far!"); 481 O << '%'; 482 for (const char *Name = RI.get(MO.getReg()).Name; *Name; ++Name) 483 O << (char)tolower(*Name); 484 return; 485 486 case MachineOperand::MO_SignExtendedImmed: 487 case MachineOperand::MO_UnextendedImmed: 488 O << '$' << (int)MO.getImmedValue(); 489 return; 490 case MachineOperand::MO_MachineBasicBlock: { 491 MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); 492 O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction()) 493 << "_" << MBBOp->getNumber () << "\t# " 494 << MBBOp->getBasicBlock ()->getName (); 495 return; 496 } 497 case MachineOperand::MO_PCRelativeDisp: 498 std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs"; 499 abort (); 500 return; 501 case MachineOperand::MO_GlobalAddress: { 502 if (!isCallOp) O << '$'; 503 O << Mang->getValueName(MO.getGlobal()); 504 int Offset = MO.getOffset(); 505 if (Offset > 0) 506 O << "+" << Offset; 507 else if (Offset < 0) 508 O << Offset; 509 return; 510 } 511 case MachineOperand::MO_ExternalSymbol: 512 if (!isCallOp) O << '$'; 513 O << MO.getSymbolName(); 514 return; 515 default: 516 O << "<unknown operand type>"; return; 517 } 518} 519 520void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){ 521 assert(isMem(MI, Op) && "Invalid memory reference!"); 522 523 if (MI->getOperand(Op).isFrameIndex()) { 524 O << "[frame slot #" << MI->getOperand(Op).getFrameIndex(); 525 if (MI->getOperand(Op+3).getImmedValue()) 526 O << " + " << MI->getOperand(Op+3).getImmedValue(); 527 O << "]"; 528 return; 529 } else if (MI->getOperand(Op).isConstantPoolIndex()) { 530 O << ".CPI" << CurrentFnName << "_" 531 << MI->getOperand(Op).getConstantPoolIndex(); 532 if (MI->getOperand(Op+3).getImmedValue()) 533 O << " + " << MI->getOperand(Op+3).getImmedValue(); 534 return; 535 } 536 537 const MachineOperand &BaseReg = MI->getOperand(Op); 538 int ScaleVal = MI->getOperand(Op+1).getImmedValue(); 539 const MachineOperand &IndexReg = MI->getOperand(Op+2); 540 const MachineOperand &DispSpec = MI->getOperand(Op+3); 541 542 if (DispSpec.isGlobalAddress()) { 543 printOp(DispSpec, true); 544 } else { 545 int DispVal = DispSpec.getImmedValue(); 546 if (DispVal) 547 O << DispVal; 548 } 549 550 if (IndexReg.getReg() || BaseReg.getReg()) { 551 O << "("; 552 if (BaseReg.getReg()) 553 printOp(BaseReg); 554 555 if (IndexReg.getReg()) { 556 O << ","; 557 printOp(IndexReg); 558 if (ScaleVal != 1) 559 O << "," << ScaleVal; 560 } 561 562 O << ")"; 563 } 564} 565 566 567/// printMachineInstruction -- Print out a single X86 LLVM instruction 568/// MI in Intel syntax to the current output stream. 569/// 570void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) { 571 ++EmittedInsts; 572 // Call the autogenerated instruction printer routines. 573 printInstruction(MI); 574} 575 576 577/// createX86CodePrinterPass - Returns a pass that prints the X86 assembly code 578/// for a MachineFunction to the given output stream, using the given target 579/// machine description. 580/// 581FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,TargetMachine &tm){ 582 switch (AsmWriterFlavor) { 583 default: assert(0 && "Unknown asm flavor!"); 584 case intel: 585 return new X86IntelAsmPrinter(o, tm); 586 case att: 587 return new X86ATTAsmPrinter(o, tm); 588 } 589} 590