LLVM API Documentation
00001 //===-- X86IntelAsmPrinter.cpp - Convert X86 LLVM code to Intel assembly --===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains a printer that converts from our internal representation 00011 // of machine-dependent LLVM code to Intel format assembly language. 00012 // This printer is the output mechanism used by `llc'. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #include "X86IntelAsmPrinter.h" 00017 #include "X86.h" 00018 #include "llvm/Constants.h" 00019 #include "llvm/Module.h" 00020 #include "llvm/Assembly/Writer.h" 00021 #include "llvm/Support/Mangler.h" 00022 #include "llvm/Target/TargetOptions.h" 00023 using namespace llvm; 00024 00025 X86IntelAsmPrinter::X86IntelAsmPrinter(std::ostream &O, X86TargetMachine &TM) 00026 : X86SharedAsmPrinter(O, TM) { 00027 } 00028 00029 /// runOnMachineFunction - This uses the printMachineInstruction() 00030 /// method to print assembly for each instruction. 00031 /// 00032 bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 00033 SetupMachineFunction(MF); 00034 O << "\n\n"; 00035 00036 // Print out constants referenced by the function 00037 EmitConstantPool(MF.getConstantPool()); 00038 00039 // Print out labels for the function. 00040 SwitchToTextSection("_text", MF.getFunction()); 00041 EmitAlignment(4); 00042 if (MF.getFunction()->getLinkage() == GlobalValue::ExternalLinkage) 00043 O << "\tpublic " << CurrentFnName << "\n"; 00044 O << CurrentFnName << "\tproc near\n"; 00045 00046 // Print out code for the function. 00047 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 00048 I != E; ++I) { 00049 // Print a label for the basic block if there are any predecessors. 00050 if (I->pred_begin() != I->pred_end()) { 00051 printBasicBlockLabel(I, true); 00052 O << '\n'; 00053 } 00054 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 00055 II != E; ++II) { 00056 // Print the assembly for the instruction. 00057 O << "\t"; 00058 printMachineInstruction(II); 00059 } 00060 } 00061 00062 O << CurrentFnName << "\tendp\n"; 00063 00064 // We didn't modify anything. 00065 return false; 00066 } 00067 00068 void X86IntelAsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op) { 00069 unsigned char value = MI->getOperand(Op).getImmedValue(); 00070 assert(value <= 7 && "Invalid ssecc argument!"); 00071 switch (value) { 00072 case 0: O << "eq"; break; 00073 case 1: O << "lt"; break; 00074 case 2: O << "le"; break; 00075 case 3: O << "unord"; break; 00076 case 4: O << "neq"; break; 00077 case 5: O << "nlt"; break; 00078 case 6: O << "nle"; break; 00079 case 7: O << "ord"; break; 00080 } 00081 } 00082 00083 void X86IntelAsmPrinter::printOp(const MachineOperand &MO, 00084 const char *Modifier) { 00085 const MRegisterInfo &RI = *TM.getRegisterInfo(); 00086 switch (MO.getType()) { 00087 case MachineOperand::MO_Register: 00088 if (MRegisterInfo::isPhysicalRegister(MO.getReg())) { 00089 unsigned Reg = MO.getReg(); 00090 if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) { 00091 MVT::ValueType VT = (strcmp(Modifier,"subreg16") == 0) 00092 ? MVT::i16 : MVT::i8; 00093 Reg = getX86SubSuperRegister(Reg, VT); 00094 } 00095 O << RI.get(Reg).Name; 00096 } else 00097 O << "reg" << MO.getReg(); 00098 return; 00099 00100 case MachineOperand::MO_Immediate: 00101 O << MO.getImmedValue(); 00102 return; 00103 case MachineOperand::MO_MachineBasicBlock: 00104 printBasicBlockLabel(MO.getMachineBasicBlock()); 00105 return; 00106 case MachineOperand::MO_ConstantPoolIndex: { 00107 bool isMemOp = Modifier && !strcmp(Modifier, "mem"); 00108 if (!isMemOp) O << "OFFSET "; 00109 O << "[" << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_" 00110 << MO.getConstantPoolIndex(); 00111 int Offset = MO.getOffset(); 00112 if (Offset > 0) 00113 O << " + " << Offset; 00114 else if (Offset < 0) 00115 O << Offset; 00116 O << "]"; 00117 return; 00118 } 00119 case MachineOperand::MO_GlobalAddress: { 00120 bool isCallOp = Modifier && !strcmp(Modifier, "call"); 00121 bool isMemOp = Modifier && !strcmp(Modifier, "mem"); 00122 if (!isMemOp && !isCallOp) O << "OFFSET "; 00123 O << Mang->getValueName(MO.getGlobal()); 00124 int Offset = MO.getOffset(); 00125 if (Offset > 0) 00126 O << " + " << Offset; 00127 else if (Offset < 0) 00128 O << Offset; 00129 return; 00130 } 00131 case MachineOperand::MO_ExternalSymbol: { 00132 bool isCallOp = Modifier && !strcmp(Modifier, "call"); 00133 if (!isCallOp) O << "OFFSET "; 00134 O << GlobalPrefix << MO.getSymbolName(); 00135 return; 00136 } 00137 default: 00138 O << "<unknown operand type>"; return; 00139 } 00140 } 00141 00142 void X86IntelAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){ 00143 assert(isMem(MI, Op) && "Invalid memory reference!"); 00144 00145 const MachineOperand &BaseReg = MI->getOperand(Op); 00146 int ScaleVal = MI->getOperand(Op+1).getImmedValue(); 00147 const MachineOperand &IndexReg = MI->getOperand(Op+2); 00148 const MachineOperand &DispSpec = MI->getOperand(Op+3); 00149 00150 if (BaseReg.isFrameIndex()) { 00151 O << "[frame slot #" << BaseReg.getFrameIndex(); 00152 if (DispSpec.getImmedValue()) 00153 O << " + " << DispSpec.getImmedValue(); 00154 O << "]"; 00155 return; 00156 } 00157 00158 O << "["; 00159 bool NeedPlus = false; 00160 if (BaseReg.getReg()) { 00161 printOp(BaseReg, "mem"); 00162 NeedPlus = true; 00163 } 00164 00165 if (IndexReg.getReg()) { 00166 if (NeedPlus) O << " + "; 00167 if (ScaleVal != 1) 00168 O << ScaleVal << "*"; 00169 printOp(IndexReg); 00170 NeedPlus = true; 00171 } 00172 00173 if (DispSpec.isGlobalAddress() || DispSpec.isConstantPoolIndex()) { 00174 if (NeedPlus) 00175 O << " + "; 00176 printOp(DispSpec, "mem"); 00177 } else { 00178 int DispVal = DispSpec.getImmedValue(); 00179 if (DispVal || (!BaseReg.getReg() && !IndexReg.getReg())) { 00180 if (NeedPlus) 00181 if (DispVal > 0) 00182 O << " + "; 00183 else { 00184 O << " - "; 00185 DispVal = -DispVal; 00186 } 00187 O << DispVal; 00188 } 00189 } 00190 O << "]"; 00191 } 00192 00193 void X86IntelAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) { 00194 O << "\"L" << getFunctionNumber() << "$pb\"\n"; 00195 O << "\"L" << getFunctionNumber() << "$pb\":"; 00196 } 00197 00198 bool X86IntelAsmPrinter::printAsmMRegister(const MachineOperand &MO, 00199 const char Mode) { 00200 const MRegisterInfo &RI = *TM.getRegisterInfo(); 00201 unsigned Reg = MO.getReg(); 00202 switch (Mode) { 00203 default: return true; // Unknown mode. 00204 case 'b': // Print QImode register 00205 Reg = getX86SubSuperRegister(Reg, MVT::i8); 00206 break; 00207 case 'h': // Print QImode high register 00208 Reg = getX86SubSuperRegister(Reg, MVT::i8, true); 00209 break; 00210 case 'w': // Print HImode register 00211 Reg = getX86SubSuperRegister(Reg, MVT::i16); 00212 break; 00213 case 'k': // Print SImode register 00214 Reg = getX86SubSuperRegister(Reg, MVT::i32); 00215 break; 00216 } 00217 00218 O << '%' << RI.get(Reg).Name; 00219 return false; 00220 } 00221 00222 /// PrintAsmOperand - Print out an operand for an inline asm expression. 00223 /// 00224 bool X86IntelAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 00225 unsigned AsmVariant, 00226 const char *ExtraCode) { 00227 // Does this asm operand have a single letter operand modifier? 00228 if (ExtraCode && ExtraCode[0]) { 00229 if (ExtraCode[1] != 0) return true; // Unknown modifier. 00230 00231 switch (ExtraCode[0]) { 00232 default: return true; // Unknown modifier. 00233 case 'b': // Print QImode register 00234 case 'h': // Print QImode high register 00235 case 'w': // Print HImode register 00236 case 'k': // Print SImode register 00237 return printAsmMRegister(MI->getOperand(OpNo), ExtraCode[0]); 00238 } 00239 } 00240 00241 printOperand(MI, OpNo); 00242 return false; 00243 } 00244 00245 bool X86IntelAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 00246 unsigned OpNo, 00247 unsigned AsmVariant, 00248 const char *ExtraCode) { 00249 if (ExtraCode && ExtraCode[0]) 00250 return true; // Unknown modifier. 00251 printMemReference(MI, OpNo); 00252 return false; 00253 } 00254 00255 /// printMachineInstruction -- Print out a single X86 LLVM instruction 00256 /// MI in Intel syntax to the current output stream. 00257 /// 00258 void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) { 00259 ++EmittedInsts; 00260 00261 // See if a truncate instruction can be turned into a nop. 00262 switch (MI->getOpcode()) { 00263 default: break; 00264 case X86::TRUNC_GR32_GR16: 00265 case X86::TRUNC_GR32_GR8: 00266 case X86::TRUNC_GR16_GR8: { 00267 const MachineOperand &MO0 = MI->getOperand(0); 00268 const MachineOperand &MO1 = MI->getOperand(1); 00269 unsigned Reg0 = MO0.getReg(); 00270 unsigned Reg1 = MO1.getReg(); 00271 if (MI->getOpcode() == X86::TRUNC_GR32_GR16) 00272 Reg1 = getX86SubSuperRegister(Reg1, MVT::i16); 00273 else 00274 Reg1 = getX86SubSuperRegister(Reg1, MVT::i8); 00275 O << CommentString << " TRUNCATE "; 00276 if (Reg0 != Reg1) 00277 O << "\n\t"; 00278 break; 00279 } 00280 } 00281 00282 // Call the autogenerated instruction printer routines. 00283 printInstruction(MI); 00284 } 00285 00286 bool X86IntelAsmPrinter::doInitialization(Module &M) { 00287 GlobalPrefix = "_"; 00288 CommentString = ";"; 00289 00290 X86SharedAsmPrinter::doInitialization(M); 00291 00292 PrivateGlobalPrefix = "$"; 00293 AlignDirective = "\talign\t"; 00294 ZeroDirective = "\tdb\t"; 00295 ZeroDirectiveSuffix = " dup(0)"; 00296 AsciiDirective = "\tdb\t"; 00297 AscizDirective = 0; 00298 Data8bitsDirective = "\tdb\t"; 00299 Data16bitsDirective = "\tdw\t"; 00300 Data32bitsDirective = "\tdd\t"; 00301 Data64bitsDirective = "\tdq\t"; 00302 HasDotTypeDotSizeDirective = false; 00303 Mang->markCharUnacceptable('.'); 00304 00305 DefaultTextSection = "_text"; 00306 DefaultDataSection = "_data"; 00307 SwitchToSectionDirective = ""; 00308 TextSectionStartSuffix = "\tsegment 'CODE'"; 00309 DataSectionStartSuffix = "\tsegment 'DATA'"; 00310 SectionEndDirectiveSuffix = "\tends\n"; 00311 00312 O << "\t.686\n\t.model flat\n\n"; 00313 00314 // Emit declarations for external functions. 00315 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 00316 if (I->isExternal()) 00317 O << "\textern " << Mang->getValueName(I) << ":near\n"; 00318 00319 // Emit declarations for external globals. Note that VC++ always declares 00320 // external globals to have type byte, and if that's good enough for VC++... 00321 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 00322 I != E; ++I) { 00323 if (I->isExternal()) 00324 O << "\textern " << Mang->getValueName(I) << ":byte\n"; 00325 } 00326 00327 return false; 00328 } 00329 00330 bool X86IntelAsmPrinter::doFinalization(Module &M) { 00331 const TargetData *TD = TM.getTargetData(); 00332 00333 // Print out module-level global variables here. 00334 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 00335 I != E; ++I) { 00336 if (I->isExternal()) continue; // External global require no code 00337 00338 // Check to see if this is a special global used by LLVM, if so, emit it. 00339 if (EmitSpecialLLVMGlobal(I)) 00340 continue; 00341 00342 std::string name = Mang->getValueName(I); 00343 Constant *C = I->getInitializer(); 00344 unsigned Size = TD->getTypeSize(C->getType()); 00345 unsigned Align = getPreferredAlignmentLog(I); 00346 bool bCustomSegment = false; 00347 00348 switch (I->getLinkage()) { 00349 case GlobalValue::LinkOnceLinkage: 00350 case GlobalValue::WeakLinkage: 00351 SwitchToDataSection("", 0); 00352 O << name << "?\tsegment common 'COMMON'\n"; 00353 bCustomSegment = true; 00354 // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256 00355 // are also available. 00356 break; 00357 case GlobalValue::AppendingLinkage: 00358 SwitchToDataSection("", 0); 00359 O << name << "?\tsegment public 'DATA'\n"; 00360 bCustomSegment = true; 00361 // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256 00362 // are also available. 00363 break; 00364 case GlobalValue::ExternalLinkage: 00365 O << "\tpublic " << name << "\n"; 00366 // FALL THROUGH 00367 case GlobalValue::InternalLinkage: 00368 SwitchToDataSection(DefaultDataSection, I); 00369 break; 00370 default: 00371 assert(0 && "Unknown linkage type!"); 00372 } 00373 00374 if (!bCustomSegment) 00375 EmitAlignment(Align, I); 00376 00377 O << name << ":\t\t\t\t" << CommentString << " " << I->getName() << '\n'; 00378 00379 EmitGlobalConstant(C); 00380 00381 if (bCustomSegment) 00382 O << name << "?\tends\n"; 00383 } 00384 00385 // Bypass X86SharedAsmPrinter::doFinalization(). 00386 AsmPrinter::doFinalization(M); 00387 SwitchToDataSection("", 0); 00388 O << "\tend\n"; 00389 return false; // success 00390 } 00391 00392 void X86IntelAsmPrinter::EmitString(const ConstantArray *CVA) const { 00393 unsigned NumElts = CVA->getNumOperands(); 00394 if (NumElts) { 00395 // ML does not have escape sequences except '' for '. It also has a maximum 00396 // string length of 255. 00397 unsigned len = 0; 00398 bool inString = false; 00399 for (unsigned i = 0; i < NumElts; i++) { 00400 int n = cast<ConstantInt>(CVA->getOperand(i))->getRawValue() & 255; 00401 if (len == 0) 00402 O << "\tdb "; 00403 00404 if (n >= 32 && n <= 127) { 00405 if (!inString) { 00406 if (len > 0) { 00407 O << ",'"; 00408 len += 2; 00409 } else { 00410 O << "'"; 00411 len++; 00412 } 00413 inString = true; 00414 } 00415 if (n == '\'') { 00416 O << "'"; 00417 len++; 00418 } 00419 O << char(n); 00420 } else { 00421 if (inString) { 00422 O << "'"; 00423 len++; 00424 inString = false; 00425 } 00426 if (len > 0) { 00427 O << ","; 00428 len++; 00429 } 00430 O << n; 00431 len += 1 + (n > 9) + (n > 99); 00432 } 00433 00434 if (len > 60) { 00435 if (inString) { 00436 O << "'"; 00437 inString = false; 00438 } 00439 O << "\n"; 00440 len = 0; 00441 } 00442 } 00443 00444 if (len > 0) { 00445 if (inString) 00446 O << "'"; 00447 O << "\n"; 00448 } 00449 } 00450 } 00451 00452 // Include the auto-generated portion of the assembly writer. 00453 #include "X86GenAsmWriter1.inc"