X86AsmPrinter.cpp revision 551ccae044b0ff658fe629dd67edd5ffe75d10e8
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 "llvm/ADT/Statistic.h" 33#include "llvm/ADT/StringExtras.h" 34#include "llvm/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 emitAlignment(TD.getTypeAlignmentShift(CP[i]->getType())); 153 O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t" << CommentString 154 << *CP[i] << "\n"; 155 emitGlobalConstant(CP[i]); 156 } 157} 158 159/// runOnMachineFunction - This uses the printMachineInstruction() 160/// method to print assembly for each instruction. 161/// 162bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) { 163 setupMachineFunction(MF); 164 O << "\n\n"; 165 166 // Print out constants referenced by the function 167 printConstantPool(MF.getConstantPool()); 168 169 // Print out labels for the function. 170 O << "\t.text\n"; 171 emitAlignment(4); 172 O << "\t.globl\t" << CurrentFnName << "\n"; 173 O << "\t.type\t" << CurrentFnName << ", @function\n"; 174 O << CurrentFnName << ":\n"; 175 176 // Print out code for the function. 177 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 178 I != E; ++I) { 179 // Print a label for the basic block. 180 O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t" 181 << CommentString << " " << I->getBasicBlock()->getName() << "\n"; 182 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 183 II != E; ++II) { 184 // Print the assembly for the instruction. 185 O << "\t"; 186 printMachineInstruction(II); 187 } 188 } 189 190 // We didn't modify anything. 191 return false; 192} 193 194static bool isScale(const MachineOperand &MO) { 195 return MO.isImmediate() && 196 (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 || 197 MO.getImmedValue() == 4 || MO.getImmedValue() == 8); 198} 199 200static bool isMem(const MachineInstr *MI, unsigned Op) { 201 if (MI->getOperand(Op).isFrameIndex()) return true; 202 if (MI->getOperand(Op).isConstantPoolIndex()) return true; 203 return Op+4 <= MI->getNumOperands() && 204 MI->getOperand(Op ).isRegister() && isScale(MI->getOperand(Op+1)) && 205 MI->getOperand(Op+2).isRegister() && MI->getOperand(Op+3).isImmediate(); 206} 207 208 209 210void X86AsmPrinter::printOp(const MachineOperand &MO, 211 bool elideOffsetKeyword /* = false */) { 212 const MRegisterInfo &RI = *TM.getRegisterInfo(); 213 switch (MO.getType()) { 214 case MachineOperand::MO_VirtualRegister: 215 if (Value *V = MO.getVRegValueOrNull()) { 216 O << "<" << V->getName() << ">"; 217 return; 218 } 219 // FALLTHROUGH 220 case MachineOperand::MO_MachineRegister: 221 if (MRegisterInfo::isPhysicalRegister(MO.getReg())) 222 // Bug Workaround: See note in Printer::doInitialization about %. 223 O << "%" << RI.get(MO.getReg()).Name; 224 else 225 O << "%reg" << MO.getReg(); 226 return; 227 228 case MachineOperand::MO_SignExtendedImmed: 229 case MachineOperand::MO_UnextendedImmed: 230 O << (int)MO.getImmedValue(); 231 return; 232 case MachineOperand::MO_MachineBasicBlock: { 233 MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); 234 O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction()) 235 << "_" << MBBOp->getNumber () << "\t# " 236 << MBBOp->getBasicBlock ()->getName (); 237 return; 238 } 239 case MachineOperand::MO_PCRelativeDisp: 240 std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs"; 241 abort (); 242 return; 243 case MachineOperand::MO_GlobalAddress: 244 if (!elideOffsetKeyword) 245 O << "OFFSET "; 246 O << Mang->getValueName(MO.getGlobal()); 247 return; 248 case MachineOperand::MO_ExternalSymbol: 249 O << MO.getSymbolName(); 250 return; 251 default: 252 O << "<unknown operand type>"; return; 253 } 254} 255 256void X86AsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op) { 257 assert(isMem(MI, Op) && "Invalid memory reference!"); 258 259 if (MI->getOperand(Op).isFrameIndex()) { 260 O << "[frame slot #" << MI->getOperand(Op).getFrameIndex(); 261 if (MI->getOperand(Op+3).getImmedValue()) 262 O << " + " << MI->getOperand(Op+3).getImmedValue(); 263 O << "]"; 264 return; 265 } else if (MI->getOperand(Op).isConstantPoolIndex()) { 266 O << "[.CPI" << CurrentFnName << "_" 267 << MI->getOperand(Op).getConstantPoolIndex(); 268 if (MI->getOperand(Op+3).getImmedValue()) 269 O << " + " << MI->getOperand(Op+3).getImmedValue(); 270 O << "]"; 271 return; 272 } 273 274 const MachineOperand &BaseReg = MI->getOperand(Op); 275 int ScaleVal = MI->getOperand(Op+1).getImmedValue(); 276 const MachineOperand &IndexReg = MI->getOperand(Op+2); 277 int DispVal = MI->getOperand(Op+3).getImmedValue(); 278 279 O << "["; 280 bool NeedPlus = false; 281 if (BaseReg.getReg()) { 282 printOp(BaseReg); 283 NeedPlus = true; 284 } 285 286 if (IndexReg.getReg()) { 287 if (NeedPlus) O << " + "; 288 if (ScaleVal != 1) 289 O << ScaleVal << "*"; 290 printOp(IndexReg); 291 NeedPlus = true; 292 } 293 294 if (DispVal) { 295 if (NeedPlus) 296 if (DispVal > 0) 297 O << " + "; 298 else { 299 O << " - "; 300 DispVal = -DispVal; 301 } 302 O << DispVal; 303 } 304 O << "]"; 305} 306 307 308/// printMachineInstruction -- Print out a single X86 LLVM instruction 309/// MI in Intel syntax to the current output stream. 310/// 311void X86AsmPrinter::printMachineInstruction(const MachineInstr *MI) { 312 ++EmittedInsts; 313 314 // gas bugs: 315 // 316 // The 80-bit FP store-pop instruction "fstp XWORD PTR [...]" is misassembled 317 // by gas in intel_syntax mode as its 32-bit equivalent "fstp DWORD PTR 318 // [...]". Workaround: Output the raw opcode bytes instead of the instruction. 319 // 320 // The 80-bit FP load instruction "fld XWORD PTR [...]" is misassembled by gas 321 // in intel_syntax mode as its 32-bit equivalent "fld DWORD PTR 322 // [...]". Workaround: Output the raw opcode bytes instead of the instruction. 323 // 324 // gas intel_syntax mode treats "fild QWORD PTR [...]" as an invalid opcode, 325 // saying "64 bit operations are only supported in 64 bit modes." libopcodes 326 // disassembles it as "fild DWORD PTR [...]", which is wrong. Workaround: 327 // Output the raw opcode bytes instead of the instruction. 328 // 329 // gas intel_syntax mode treats "fistp QWORD PTR [...]" as an invalid opcode, 330 // saying "64 bit operations are only supported in 64 bit modes." libopcodes 331 // disassembles it as "fistpll DWORD PTR [...]", which is wrong. Workaround: 332 // Output the raw opcode bytes instead of the instruction. 333 switch (MI->getOpcode()) { 334 case X86::FSTP80m: 335 case X86::FLD80m: 336 case X86::FILD64m: 337 case X86::FISTP64m: 338 GasBugWorkaroundEmitter gwe(O); 339 X86::emitInstruction(gwe, (X86InstrInfo&)*TM.getInstrInfo(), *MI); 340 O << "\t# "; 341 } 342 343 // Call the autogenerated instruction printer routines. 344 bool Handled = printInstruction(MI); 345 if (!Handled) { 346 MI->dump(); 347 assert(0 && "Do not know how to print this instruction!"); 348 abort(); 349 } 350} 351 352bool X86AsmPrinter::doInitialization(Module &M) { 353 AsmPrinter::doInitialization(M); 354 // Tell gas we are outputting Intel syntax (not AT&T syntax) assembly. 355 // 356 // Bug: gas in `intel_syntax noprefix' mode interprets the symbol `Sp' in an 357 // instruction as a reference to the register named sp, and if you try to 358 // reference a symbol `Sp' (e.g. `mov ECX, OFFSET Sp') then it gets lowercased 359 // before being looked up in the symbol table. This creates spurious 360 // `undefined symbol' errors when linking. Workaround: Do not use `noprefix' 361 // mode, and decorate all register names with percent signs. 362 O << "\t.intel_syntax\n"; 363 return false; 364} 365 366// SwitchSection - Switch to the specified section of the executable if we are 367// not already in it! 368// 369static void SwitchSection(std::ostream &OS, std::string &CurSection, 370 const char *NewSection) { 371 if (CurSection != NewSection) { 372 CurSection = NewSection; 373 if (!CurSection.empty()) 374 OS << "\t" << NewSection << "\n"; 375 } 376} 377 378bool X86AsmPrinter::doFinalization(Module &M) { 379 const TargetData &TD = TM.getTargetData(); 380 std::string CurSection; 381 382 // Print out module-level global variables here. 383 for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I) 384 if (I->hasInitializer()) { // External global require no code 385 O << "\n\n"; 386 std::string name = Mang->getValueName(I); 387 Constant *C = I->getInitializer(); 388 unsigned Size = TD.getTypeSize(C->getType()); 389 unsigned Align = TD.getTypeAlignmentShift(C->getType()); 390 391 if (C->isNullValue() && 392 (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || 393 I->hasWeakLinkage() /* FIXME: Verify correct */)) { 394 SwitchSection(O, CurSection, ".data"); 395 if (I->hasInternalLinkage()) 396 O << "\t.local " << name << "\n"; 397 398 O << "\t.comm " << name << "," << TD.getTypeSize(C->getType()) 399 << "," << (1 << Align); 400 O << "\t\t# "; 401 WriteAsOperand(O, I, true, true, &M); 402 O << "\n"; 403 } else { 404 switch (I->getLinkage()) { 405 case GlobalValue::LinkOnceLinkage: 406 case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. 407 // Nonnull linkonce -> weak 408 O << "\t.weak " << name << "\n"; 409 SwitchSection(O, CurSection, ""); 410 O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n"; 411 break; 412 case GlobalValue::AppendingLinkage: 413 // FIXME: appending linkage variables should go into a section of 414 // their name or something. For now, just emit them as external. 415 case GlobalValue::ExternalLinkage: 416 // If external or appending, declare as a global symbol 417 O << "\t.globl " << name << "\n"; 418 // FALL THROUGH 419 case GlobalValue::InternalLinkage: 420 if (C->isNullValue()) 421 SwitchSection(O, CurSection, ".bss"); 422 else 423 SwitchSection(O, CurSection, ".data"); 424 break; 425 } 426 427 emitAlignment(Align); 428 O << "\t.type " << name << ",@object\n"; 429 O << "\t.size " << name << "," << Size << "\n"; 430 O << name << ":\t\t\t\t# "; 431 WriteAsOperand(O, I, true, true, &M); 432 O << " = "; 433 WriteAsOperand(O, C, false, false, &M); 434 O << "\n"; 435 emitGlobalConstant(C); 436 } 437 } 438 439 AsmPrinter::doFinalization(M); 440 return false; // success 441} 442