LLVM API Documentation
00001 //===-- AsmPrinter.cpp - Common AsmPrinter code ---------------------------===// 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 implements the AsmPrinter class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/CodeGen/AsmPrinter.h" 00015 #include "llvm/Assembly/Writer.h" 00016 #include "llvm/DerivedTypes.h" 00017 #include "llvm/Constants.h" 00018 #include "llvm/Module.h" 00019 #include "llvm/CodeGen/MachineConstantPool.h" 00020 #include "llvm/CodeGen/MachineJumpTableInfo.h" 00021 #include "llvm/Support/Mangler.h" 00022 #include "llvm/Support/MathExtras.h" 00023 #include "llvm/Target/TargetData.h" 00024 #include "llvm/Target/TargetMachine.h" 00025 #include <iostream> 00026 #include <cerrno> 00027 using namespace llvm; 00028 00029 AsmPrinter::AsmPrinter(std::ostream &o, TargetMachine &tm) 00030 : FunctionNumber(0), O(o), TM(tm), 00031 CommentString("#"), 00032 GlobalPrefix(""), 00033 PrivateGlobalPrefix("."), 00034 GlobalVarAddrPrefix(""), 00035 GlobalVarAddrSuffix(""), 00036 FunctionAddrPrefix(""), 00037 FunctionAddrSuffix(""), 00038 InlineAsmStart("#APP"), 00039 InlineAsmEnd("#NO_APP"), 00040 ZeroDirective("\t.zero\t"), 00041 ZeroDirectiveSuffix(0), 00042 AsciiDirective("\t.ascii\t"), 00043 AscizDirective("\t.asciz\t"), 00044 Data8bitsDirective("\t.byte\t"), 00045 Data16bitsDirective("\t.short\t"), 00046 Data32bitsDirective("\t.long\t"), 00047 Data64bitsDirective("\t.quad\t"), 00048 AlignDirective("\t.align\t"), 00049 AlignmentIsInBytes(true), 00050 SwitchToSectionDirective("\t.section\t"), 00051 TextSectionStartSuffix(""), 00052 DataSectionStartSuffix(""), 00053 SectionEndDirectiveSuffix(0), 00054 ConstantPoolSection("\t.section .rodata\n"), 00055 JumpTableDataSection("\t.section .rodata\n"), 00056 JumpTableTextSection("\t.text\n"), 00057 StaticCtorsSection("\t.section .ctors,\"aw\",@progbits"), 00058 StaticDtorsSection("\t.section .dtors,\"aw\",@progbits"), 00059 FourByteConstantSection(0), 00060 EightByteConstantSection(0), 00061 SixteenByteConstantSection(0), 00062 LCOMMDirective(0), 00063 COMMDirective("\t.comm\t"), 00064 COMMDirectiveTakesAlignment(true), 00065 HasDotTypeDotSizeDirective(true) { 00066 } 00067 00068 00069 /// SwitchToTextSection - Switch to the specified text section of the executable 00070 /// if we are not already in it! 00071 /// 00072 void AsmPrinter::SwitchToTextSection(const char *NewSection, 00073 const GlobalValue *GV) { 00074 std::string NS; 00075 if (GV && GV->hasSection()) 00076 NS = SwitchToSectionDirective + GV->getSection(); 00077 else 00078 NS = NewSection; 00079 00080 // If we're already in this section, we're done. 00081 if (CurrentSection == NS) return; 00082 00083 // Close the current section, if applicable. 00084 if (SectionEndDirectiveSuffix && !CurrentSection.empty()) 00085 O << CurrentSection << SectionEndDirectiveSuffix << "\n"; 00086 00087 CurrentSection = NS; 00088 00089 if (!CurrentSection.empty()) 00090 O << CurrentSection << TextSectionStartSuffix << '\n'; 00091 } 00092 00093 /// SwitchToDataSection - Switch to the specified data section of the executable 00094 /// if we are not already in it! 00095 /// 00096 void AsmPrinter::SwitchToDataSection(const char *NewSection, 00097 const GlobalValue *GV) { 00098 std::string NS; 00099 if (GV && GV->hasSection()) 00100 NS = SwitchToSectionDirective + GV->getSection(); 00101 else 00102 NS = NewSection; 00103 00104 // If we're already in this section, we're done. 00105 if (CurrentSection == NS) return; 00106 00107 // Close the current section, if applicable. 00108 if (SectionEndDirectiveSuffix && !CurrentSection.empty()) 00109 O << CurrentSection << SectionEndDirectiveSuffix << "\n"; 00110 00111 CurrentSection = NS; 00112 00113 if (!CurrentSection.empty()) 00114 O << CurrentSection << DataSectionStartSuffix << '\n'; 00115 } 00116 00117 00118 bool AsmPrinter::doInitialization(Module &M) { 00119 Mang = new Mangler(M, GlobalPrefix); 00120 00121 if (!M.getModuleInlineAsm().empty()) 00122 O << CommentString << " Start of file scope inline assembly\n" 00123 << M.getModuleInlineAsm() 00124 << "\n" << CommentString << " End of file scope inline assembly\n"; 00125 00126 SwitchToDataSection("", 0); // Reset back to no section. 00127 00128 if (MachineDebugInfo *DebugInfo = getAnalysisToUpdate<MachineDebugInfo>()) { 00129 DebugInfo->AnalyzeModule(M); 00130 } 00131 00132 return false; 00133 } 00134 00135 bool AsmPrinter::doFinalization(Module &M) { 00136 delete Mang; Mang = 0; 00137 return false; 00138 } 00139 00140 void AsmPrinter::SetupMachineFunction(MachineFunction &MF) { 00141 // What's my mangled name? 00142 CurrentFnName = Mang->getValueName(MF.getFunction()); 00143 IncrementFunctionNumber(); 00144 } 00145 00146 /// EmitConstantPool - Print to the current output stream assembly 00147 /// representations of the constants in the constant pool MCP. This is 00148 /// used to print out constants which have been "spilled to memory" by 00149 /// the code generator. 00150 /// 00151 void AsmPrinter::EmitConstantPool(MachineConstantPool *MCP) { 00152 const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants(); 00153 if (CP.empty()) return; 00154 00155 // Some targets require 4-, 8-, and 16- byte constant literals to be placed 00156 // in special sections. 00157 std::vector<std::pair<MachineConstantPoolEntry,unsigned> > FourByteCPs; 00158 std::vector<std::pair<MachineConstantPoolEntry,unsigned> > EightByteCPs; 00159 std::vector<std::pair<MachineConstantPoolEntry,unsigned> > SixteenByteCPs; 00160 std::vector<std::pair<MachineConstantPoolEntry,unsigned> > OtherCPs; 00161 for (unsigned i = 0, e = CP.size(); i != e; ++i) { 00162 MachineConstantPoolEntry CPE = CP[i]; 00163 const Constant *CV = CPE.Val; 00164 const Type *Ty = CV->getType(); 00165 if (FourByteConstantSection && 00166 TM.getTargetData()->getTypeSize(Ty) == 4) 00167 FourByteCPs.push_back(std::make_pair(CPE, i)); 00168 else if (EightByteConstantSection && 00169 TM.getTargetData()->getTypeSize(Ty) == 8) 00170 EightByteCPs.push_back(std::make_pair(CPE, i)); 00171 else if (SixteenByteConstantSection && 00172 TM.getTargetData()->getTypeSize(Ty) == 16) 00173 SixteenByteCPs.push_back(std::make_pair(CPE, i)); 00174 else 00175 OtherCPs.push_back(std::make_pair(CPE, i)); 00176 } 00177 00178 unsigned Alignment = MCP->getConstantPoolAlignment(); 00179 EmitConstantPool(Alignment, FourByteConstantSection, FourByteCPs); 00180 EmitConstantPool(Alignment, EightByteConstantSection, EightByteCPs); 00181 EmitConstantPool(Alignment, SixteenByteConstantSection, SixteenByteCPs); 00182 EmitConstantPool(Alignment, ConstantPoolSection, OtherCPs); 00183 } 00184 00185 void AsmPrinter::EmitConstantPool(unsigned Alignment, const char *Section, 00186 std::vector<std::pair<MachineConstantPoolEntry,unsigned> > &CP) { 00187 if (CP.empty()) return; 00188 00189 SwitchToDataSection(Section, 0); 00190 EmitAlignment(Alignment); 00191 for (unsigned i = 0, e = CP.size(); i != e; ++i) { 00192 O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << '_' 00193 << CP[i].second << ":\t\t\t\t\t" << CommentString << " "; 00194 WriteTypeSymbolic(O, CP[i].first.Val->getType(), 0) << '\n'; 00195 EmitGlobalConstant(CP[i].first.Val); 00196 if (i != e-1) { 00197 unsigned EntSize = 00198 TM.getTargetData()->getTypeSize(CP[i].first.Val->getType()); 00199 unsigned ValEnd = CP[i].first.Offset + EntSize; 00200 // Emit inter-object padding for alignment. 00201 EmitZeros(CP[i+1].first.Offset-ValEnd); 00202 } 00203 } 00204 } 00205 00206 /// EmitJumpTableInfo - Print assembly representations of the jump tables used 00207 /// by the current function to the current output stream. 00208 /// 00209 void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI) { 00210 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 00211 if (JT.empty()) return; 00212 const TargetData *TD = TM.getTargetData(); 00213 const char *PtrDataDirective = Data32bitsDirective; 00214 00215 // Pick the directive to use to print the jump table entries, and switch to 00216 // the appropriate section. 00217 if (TM.getRelocationModel() == Reloc::PIC_) { 00218 SwitchToTextSection(JumpTableTextSection, 0); 00219 } else { 00220 SwitchToDataSection(JumpTableDataSection, 0); 00221 if (TD->getPointerSize() == 8) 00222 PtrDataDirective = Data64bitsDirective; 00223 } 00224 EmitAlignment(Log2_32(TD->getPointerAlignment())); 00225 00226 for (unsigned i = 0, e = JT.size(); i != e; ++i) { 00227 O << PrivateGlobalPrefix << "JTI" << getFunctionNumber() << '_' << i 00228 << ":\n"; 00229 const std::vector<MachineBasicBlock*> &JTBBs = JT[i].MBBs; 00230 for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) { 00231 O << PtrDataDirective << ' '; 00232 printBasicBlockLabel(JTBBs[ii], false, false); 00233 if (TM.getRelocationModel() == Reloc::PIC_) { 00234 O << '-' << PrivateGlobalPrefix << "JTI" << getFunctionNumber() 00235 << '_' << i; 00236 } 00237 O << '\n'; 00238 } 00239 } 00240 } 00241 00242 /// EmitSpecialLLVMGlobal - Check to see if the specified global is a 00243 /// special global used by LLVM. If so, emit it and return true, otherwise 00244 /// do nothing and return false. 00245 bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { 00246 // Ignore debug and non-emitted data. 00247 if (GV->getSection() == "llvm.metadata") return true; 00248 00249 if (!GV->hasAppendingLinkage()) return false; 00250 00251 assert(GV->hasInitializer() && "Not a special LLVM global!"); 00252 00253 if (GV->getName() == "llvm.used") 00254 return true; // No need to emit this at all. 00255 00256 if (GV->getName() == "llvm.global_ctors" && GV->use_empty()) { 00257 SwitchToDataSection(StaticCtorsSection, 0); 00258 EmitAlignment(2, 0); 00259 EmitXXStructorList(GV->getInitializer()); 00260 return true; 00261 } 00262 00263 if (GV->getName() == "llvm.global_dtors" && GV->use_empty()) { 00264 SwitchToDataSection(StaticDtorsSection, 0); 00265 EmitAlignment(2, 0); 00266 EmitXXStructorList(GV->getInitializer()); 00267 return true; 00268 } 00269 00270 return false; 00271 } 00272 00273 /// EmitXXStructorList - Emit the ctor or dtor list. This just prints out the 00274 /// function pointers, ignoring the init priority. 00275 void AsmPrinter::EmitXXStructorList(Constant *List) { 00276 // Should be an array of '{ int, void ()* }' structs. The first value is the 00277 // init priority, which we ignore. 00278 if (!isa<ConstantArray>(List)) return; 00279 ConstantArray *InitList = cast<ConstantArray>(List); 00280 for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) 00281 if (ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i))){ 00282 if (CS->getNumOperands() != 2) return; // Not array of 2-element structs. 00283 00284 if (CS->getOperand(1)->isNullValue()) 00285 return; // Found a null terminator, exit printing. 00286 // Emit the function pointer. 00287 EmitGlobalConstant(CS->getOperand(1)); 00288 } 00289 } 00290 00291 /// getPreferredAlignmentLog - Return the preferred alignment of the 00292 /// specified global, returned in log form. This includes an explicitly 00293 /// requested alignment (if the global has one). 00294 unsigned AsmPrinter::getPreferredAlignmentLog(const GlobalVariable *GV) const { 00295 const Type *ElemType = GV->getType()->getElementType(); 00296 unsigned Alignment = TM.getTargetData()->getTypeAlignmentShift(ElemType); 00297 if (GV->getAlignment() > (1U << Alignment)) 00298 Alignment = Log2_32(GV->getAlignment()); 00299 00300 if (GV->hasInitializer()) { 00301 // Always round up alignment of global doubles to 8 bytes. 00302 if (GV->getType()->getElementType() == Type::DoubleTy && Alignment < 3) 00303 Alignment = 3; 00304 if (Alignment < 4) { 00305 // If the global is not external, see if it is large. If so, give it a 00306 // larger alignment. 00307 if (TM.getTargetData()->getTypeSize(ElemType) > 128) 00308 Alignment = 4; // 16-byte alignment. 00309 } 00310 } 00311 return Alignment; 00312 } 00313 00314 // EmitAlignment - Emit an alignment directive to the specified power of two. 00315 void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV) const { 00316 if (GV && GV->getAlignment()) 00317 NumBits = Log2_32(GV->getAlignment()); 00318 if (NumBits == 0) return; // No need to emit alignment. 00319 if (AlignmentIsInBytes) NumBits = 1 << NumBits; 00320 O << AlignDirective << NumBits << "\n"; 00321 } 00322 00323 /// EmitZeros - Emit a block of zeros. 00324 /// 00325 void AsmPrinter::EmitZeros(uint64_t NumZeros) const { 00326 if (NumZeros) { 00327 if (ZeroDirective) { 00328 O << ZeroDirective << NumZeros; 00329 if (ZeroDirectiveSuffix) 00330 O << ZeroDirectiveSuffix; 00331 O << "\n"; 00332 } else { 00333 for (; NumZeros; --NumZeros) 00334 O << Data8bitsDirective << "0\n"; 00335 } 00336 } 00337 } 00338 00339 // Print out the specified constant, without a storage class. Only the 00340 // constants valid in constant expressions can occur here. 00341 void AsmPrinter::EmitConstantValueOnly(const Constant *CV) { 00342 if (CV->isNullValue() || isa<UndefValue>(CV)) 00343 O << "0"; 00344 else if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV)) { 00345 assert(CB == ConstantBool::True); 00346 O << "1"; 00347 } else if (const ConstantSInt *CI = dyn_cast<ConstantSInt>(CV)) 00348 if (((CI->getValue() << 32) >> 32) == CI->getValue()) 00349 O << CI->getValue(); 00350 else 00351 O << (uint64_t)CI->getValue(); 00352 else if (const ConstantUInt *CI = dyn_cast<ConstantUInt>(CV)) 00353 O << CI->getValue(); 00354 else if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) { 00355 // This is a constant address for a global variable or function. Use the 00356 // name of the variable or function as the address value, possibly 00357 // decorating it with GlobalVarAddrPrefix/Suffix or 00358 // FunctionAddrPrefix/Suffix (these all default to "" ) 00359 if (isa<Function>(GV)) 00360 O << FunctionAddrPrefix << Mang->getValueName(GV) << FunctionAddrSuffix; 00361 else 00362 O << GlobalVarAddrPrefix << Mang->getValueName(GV) << GlobalVarAddrSuffix; 00363 } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) { 00364 const TargetData *TD = TM.getTargetData(); 00365 switch(CE->getOpcode()) { 00366 case Instruction::GetElementPtr: { 00367 // generate a symbolic expression for the byte address 00368 const Constant *ptrVal = CE->getOperand(0); 00369 std::vector<Value*> idxVec(CE->op_begin()+1, CE->op_end()); 00370 if (int64_t Offset = TD->getIndexedOffset(ptrVal->getType(), idxVec)) { 00371 if (Offset) 00372 O << "("; 00373 EmitConstantValueOnly(ptrVal); 00374 if (Offset > 0) 00375 O << ") + " << Offset; 00376 else if (Offset < 0) 00377 O << ") - " << -Offset; 00378 } else { 00379 EmitConstantValueOnly(ptrVal); 00380 } 00381 break; 00382 } 00383 case Instruction::Cast: { 00384 // Support only non-converting or widening casts for now, that is, ones 00385 // that do not involve a change in value. This assertion is really gross, 00386 // and may not even be a complete check. 00387 Constant *Op = CE->getOperand(0); 00388 const Type *OpTy = Op->getType(), *Ty = CE->getType(); 00389 00390 // Remember, kids, pointers can be losslessly converted back and forth 00391 // into 32-bit or wider integers, regardless of signedness. :-P 00392 assert(((isa<PointerType>(OpTy) 00393 && (Ty == Type::LongTy || Ty == Type::ULongTy 00394 || Ty == Type::IntTy || Ty == Type::UIntTy)) 00395 || (isa<PointerType>(Ty) 00396 && (OpTy == Type::LongTy || OpTy == Type::ULongTy 00397 || OpTy == Type::IntTy || OpTy == Type::UIntTy)) 00398 || (((TD->getTypeSize(Ty) >= TD->getTypeSize(OpTy)) 00399 && OpTy->isLosslesslyConvertibleTo(Ty)))) 00400 && "FIXME: Don't yet support this kind of constant cast expr"); 00401 EmitConstantValueOnly(Op); 00402 break; 00403 } 00404 case Instruction::Add: 00405 O << "("; 00406 EmitConstantValueOnly(CE->getOperand(0)); 00407 O << ") + ("; 00408 EmitConstantValueOnly(CE->getOperand(1)); 00409 O << ")"; 00410 break; 00411 default: 00412 assert(0 && "Unsupported operator!"); 00413 } 00414 } else { 00415 assert(0 && "Unknown constant value!"); 00416 } 00417 } 00418 00419 /// toOctal - Convert the low order bits of X into an octal digit. 00420 /// 00421 static inline char toOctal(int X) { 00422 return (X&7)+'0'; 00423 } 00424 00425 /// printAsCString - Print the specified array as a C compatible string, only if 00426 /// the predicate isString is true. 00427 /// 00428 static void printAsCString(std::ostream &O, const ConstantArray *CVA, 00429 unsigned LastElt) { 00430 assert(CVA->isString() && "Array is not string compatible!"); 00431 00432 O << "\""; 00433 for (unsigned i = 0; i != LastElt; ++i) { 00434 unsigned char C = 00435 (unsigned char)cast<ConstantInt>(CVA->getOperand(i))->getRawValue(); 00436 00437 if (C == '"') { 00438 O << "\\\""; 00439 } else if (C == '\\') { 00440 O << "\\\\"; 00441 } else if (isprint(C)) { 00442 O << C; 00443 } else { 00444 switch(C) { 00445 case '\b': O << "\\b"; break; 00446 case '\f': O << "\\f"; break; 00447 case '\n': O << "\\n"; break; 00448 case '\r': O << "\\r"; break; 00449 case '\t': O << "\\t"; break; 00450 default: 00451 O << '\\'; 00452 O << toOctal(C >> 6); 00453 O << toOctal(C >> 3); 00454 O << toOctal(C >> 0); 00455 break; 00456 } 00457 } 00458 } 00459 O << "\""; 00460 } 00461 00462 /// EmitString - Emit a zero-byte-terminated string constant. 00463 /// 00464 void AsmPrinter::EmitString(const ConstantArray *CVA) const { 00465 unsigned NumElts = CVA->getNumOperands(); 00466 if (AscizDirective && NumElts && 00467 cast<ConstantInt>(CVA->getOperand(NumElts-1))->getRawValue() == 0) { 00468 O << AscizDirective; 00469 printAsCString(O, CVA, NumElts-1); 00470 } else { 00471 O << AsciiDirective; 00472 printAsCString(O, CVA, NumElts); 00473 } 00474 O << "\n"; 00475 } 00476 00477 /// EmitGlobalConstant - Print a general LLVM constant to the .s file. 00478 /// 00479 void AsmPrinter::EmitGlobalConstant(const Constant *CV) { 00480 const TargetData *TD = TM.getTargetData(); 00481 00482 if (CV->isNullValue() || isa<UndefValue>(CV)) { 00483 EmitZeros(TD->getTypeSize(CV->getType())); 00484 return; 00485 } else if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) { 00486 if (CVA->isString()) { 00487 EmitString(CVA); 00488 } else { // Not a string. Print the values in successive locations 00489 for (unsigned i = 0, e = CVA->getNumOperands(); i != e; ++i) 00490 EmitGlobalConstant(CVA->getOperand(i)); 00491 } 00492 return; 00493 } else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) { 00494 // Print the fields in successive locations. Pad to align if needed! 00495 const StructLayout *cvsLayout = TD->getStructLayout(CVS->getType()); 00496 uint64_t sizeSoFar = 0; 00497 for (unsigned i = 0, e = CVS->getNumOperands(); i != e; ++i) { 00498 const Constant* field = CVS->getOperand(i); 00499 00500 // Check if padding is needed and insert one or more 0s. 00501 uint64_t fieldSize = TD->getTypeSize(field->getType()); 00502 uint64_t padSize = ((i == e-1? cvsLayout->StructSize 00503 : cvsLayout->MemberOffsets[i+1]) 00504 - cvsLayout->MemberOffsets[i]) - fieldSize; 00505 sizeSoFar += fieldSize + padSize; 00506 00507 // Now print the actual field value 00508 EmitGlobalConstant(field); 00509 00510 // Insert the field padding unless it's zero bytes... 00511 EmitZeros(padSize); 00512 } 00513 assert(sizeSoFar == cvsLayout->StructSize && 00514 "Layout of constant struct may be incorrect!"); 00515 return; 00516 } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) { 00517 // FP Constants are printed as integer constants to avoid losing 00518 // precision... 00519 double Val = CFP->getValue(); 00520 if (CFP->getType() == Type::DoubleTy) { 00521 if (Data64bitsDirective) 00522 O << Data64bitsDirective << DoubleToBits(Val) << "\t" << CommentString 00523 << " double value: " << Val << "\n"; 00524 else if (TD->isBigEndian()) { 00525 O << Data32bitsDirective << unsigned(DoubleToBits(Val) >> 32) 00526 << "\t" << CommentString << " double most significant word " 00527 << Val << "\n"; 00528 O << Data32bitsDirective << unsigned(DoubleToBits(Val)) 00529 << "\t" << CommentString << " double least significant word " 00530 << Val << "\n"; 00531 } else { 00532 O << Data32bitsDirective << unsigned(DoubleToBits(Val)) 00533 << "\t" << CommentString << " double least significant word " << Val 00534 << "\n"; 00535 O << Data32bitsDirective << unsigned(DoubleToBits(Val) >> 32) 00536 << "\t" << CommentString << " double most significant word " << Val 00537 << "\n"; 00538 } 00539 return; 00540 } else { 00541 O << Data32bitsDirective << FloatToBits(Val) << "\t" << CommentString 00542 << " float " << Val << "\n"; 00543 return; 00544 } 00545 } else if (CV->getType() == Type::ULongTy || CV->getType() == Type::LongTy) { 00546 if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { 00547 uint64_t Val = CI->getRawValue(); 00548 00549 if (Data64bitsDirective) 00550 O << Data64bitsDirective << Val << "\n"; 00551 else if (TD->isBigEndian()) { 00552 O << Data32bitsDirective << unsigned(Val >> 32) 00553 << "\t" << CommentString << " Double-word most significant word " 00554 << Val << "\n"; 00555 O << Data32bitsDirective << unsigned(Val) 00556 << "\t" << CommentString << " Double-word least significant word " 00557 << Val << "\n"; 00558 } else { 00559 O << Data32bitsDirective << unsigned(Val) 00560 << "\t" << CommentString << " Double-word least significant word " 00561 << Val << "\n"; 00562 O << Data32bitsDirective << unsigned(Val >> 32) 00563 << "\t" << CommentString << " Double-word most significant word " 00564 << Val << "\n"; 00565 } 00566 return; 00567 } 00568 } else if (const ConstantPacked *CP = dyn_cast<ConstantPacked>(CV)) { 00569 const PackedType *PTy = CP->getType(); 00570 00571 for (unsigned I = 0, E = PTy->getNumElements(); I < E; ++I) 00572 EmitGlobalConstant(CP->getOperand(I)); 00573 00574 return; 00575 } 00576 00577 const Type *type = CV->getType(); 00578 switch (type->getTypeID()) { 00579 case Type::BoolTyID: 00580 case Type::UByteTyID: case Type::SByteTyID: 00581 O << Data8bitsDirective; 00582 break; 00583 case Type::UShortTyID: case Type::ShortTyID: 00584 O << Data16bitsDirective; 00585 break; 00586 case Type::PointerTyID: 00587 if (TD->getPointerSize() == 8) { 00588 assert(Data64bitsDirective && 00589 "Target cannot handle 64-bit pointer exprs!"); 00590 O << Data64bitsDirective; 00591 break; 00592 } 00593 //Fall through for pointer size == int size 00594 case Type::UIntTyID: case Type::IntTyID: 00595 O << Data32bitsDirective; 00596 break; 00597 case Type::ULongTyID: case Type::LongTyID: 00598 assert(Data64bitsDirective &&"Target cannot handle 64-bit constant exprs!"); 00599 O << Data64bitsDirective; 00600 break; 00601 case Type::FloatTyID: case Type::DoubleTyID: 00602 assert (0 && "Should have already output floating point constant."); 00603 default: 00604 assert (0 && "Can't handle printing this type of thing"); 00605 break; 00606 } 00607 EmitConstantValueOnly(CV); 00608 O << "\n"; 00609 } 00610 00611 /// printInlineAsm - This method formats and prints the specified machine 00612 /// instruction that is an inline asm. 00613 void AsmPrinter::printInlineAsm(const MachineInstr *MI) const { 00614 O << InlineAsmStart << "\n\t"; 00615 unsigned NumOperands = MI->getNumOperands(); 00616 00617 // Count the number of register definitions. 00618 unsigned NumDefs = 0; 00619 for (; MI->getOperand(NumDefs).isDef(); ++NumDefs) 00620 assert(NumDefs != NumOperands-1 && "No asm string?"); 00621 00622 assert(MI->getOperand(NumDefs).isExternalSymbol() && "No asm string?"); 00623 00624 // Disassemble the AsmStr, printing out the literal pieces, the operands, etc. 00625 const char *AsmStr = MI->getOperand(NumDefs).getSymbolName(); 00626 00627 // The variant of the current asmprinter: FIXME: change. 00628 int AsmPrinterVariant = 0; 00629 00630 int CurVariant = -1; // The number of the {.|.|.} region we are in. 00631 const char *LastEmitted = AsmStr; // One past the last character emitted. 00632 00633 while (*LastEmitted) { 00634 switch (*LastEmitted) { 00635 default: { 00636 // Not a special case, emit the string section literally. 00637 const char *LiteralEnd = LastEmitted+1; 00638 while (*LiteralEnd && *LiteralEnd != '{' && *LiteralEnd != '|' && 00639 *LiteralEnd != '}' && *LiteralEnd != '$' && *LiteralEnd != '\n') 00640 ++LiteralEnd; 00641 if (CurVariant == -1 || CurVariant == AsmPrinterVariant) 00642 O.write(LastEmitted, LiteralEnd-LastEmitted); 00643 LastEmitted = LiteralEnd; 00644 break; 00645 } 00646 case '\n': 00647 ++LastEmitted; // Consume newline character. 00648 O << "\n\t"; // Indent code with newline. 00649 break; 00650 case '$': { 00651 ++LastEmitted; // Consume '$' character. 00652 if (*LastEmitted == '$') { // $$ -> $ 00653 if (CurVariant == -1 || CurVariant == AsmPrinterVariant) 00654 O << '$'; 00655 ++LastEmitted; // Consume second '$' character. 00656 break; 00657 } 00658 00659 bool HasCurlyBraces = false; 00660 if (*LastEmitted == '{') { // ${variable} 00661 ++LastEmitted; // Consume '{' character. 00662 HasCurlyBraces = true; 00663 } 00664 00665 const char *IDStart = LastEmitted; 00666 char *IDEnd; 00667 long Val = strtol(IDStart, &IDEnd, 10); // We only accept numbers for IDs. 00668 if (!isdigit(*IDStart) || (Val == 0 && errno == EINVAL)) { 00669 std::cerr << "Bad $ operand number in inline asm string: '" 00670 << AsmStr << "'\n"; 00671 exit(1); 00672 } 00673 LastEmitted = IDEnd; 00674 00675 char Modifier[2] = { 0, 0 }; 00676 00677 if (HasCurlyBraces) { 00678 // If we have curly braces, check for a modifier character. This 00679 // supports syntax like ${0:u}, which correspond to "%u0" in GCC asm. 00680 if (*LastEmitted == ':') { 00681 ++LastEmitted; // Consume ':' character. 00682 if (*LastEmitted == 0) { 00683 std::cerr << "Bad ${:} expression in inline asm string: '" 00684 << AsmStr << "'\n"; 00685 exit(1); 00686 } 00687 00688 Modifier[0] = *LastEmitted; 00689 ++LastEmitted; // Consume modifier character. 00690 } 00691 00692 if (*LastEmitted != '}') { 00693 std::cerr << "Bad ${} expression in inline asm string: '" 00694 << AsmStr << "'\n"; 00695 exit(1); 00696 } 00697 ++LastEmitted; // Consume '}' character. 00698 } 00699 00700 if ((unsigned)Val >= NumOperands-1) { 00701 std::cerr << "Invalid $ operand number in inline asm string: '" 00702 << AsmStr << "'\n"; 00703 exit(1); 00704 } 00705 00706 // Okay, we finally have a value number. Ask the target to print this 00707 // operand! 00708 if (CurVariant == -1 || CurVariant == AsmPrinterVariant) { 00709 unsigned OpNo = 1; 00710 00711 bool Error = false; 00712 00713 // Scan to find the machine operand number for the operand. 00714 for (; Val; --Val) { 00715 if (OpNo >= MI->getNumOperands()) break; 00716 unsigned OpFlags = MI->getOperand(OpNo).getImmedValue(); 00717 OpNo += (OpFlags >> 3) + 1; 00718 } 00719 00720 if (OpNo >= MI->getNumOperands()) { 00721 Error = true; 00722 } else { 00723 unsigned OpFlags = MI->getOperand(OpNo).getImmedValue(); 00724 ++OpNo; // Skip over the ID number. 00725 00726 AsmPrinter *AP = const_cast<AsmPrinter*>(this); 00727 if ((OpFlags & 7) == 4 /*ADDR MODE*/) { 00728 Error = AP->PrintAsmMemoryOperand(MI, OpNo, AsmPrinterVariant, 00729 Modifier[0] ? Modifier : 0); 00730 } else { 00731 Error = AP->PrintAsmOperand(MI, OpNo, AsmPrinterVariant, 00732 Modifier[0] ? Modifier : 0); 00733 } 00734 } 00735 if (Error) { 00736 std::cerr << "Invalid operand found in inline asm: '" 00737 << AsmStr << "'\n"; 00738 MI->dump(); 00739 exit(1); 00740 } 00741 } 00742 break; 00743 } 00744 case '{': 00745 ++LastEmitted; // Consume '{' character. 00746 if (CurVariant != -1) { 00747 std::cerr << "Nested variants found in inline asm string: '" 00748 << AsmStr << "'\n"; 00749 exit(1); 00750 } 00751 CurVariant = 0; // We're in the first variant now. 00752 break; 00753 case '|': 00754 ++LastEmitted; // consume '|' character. 00755 if (CurVariant == -1) { 00756 std::cerr << "Found '|' character outside of variant in inline asm " 00757 << "string: '" << AsmStr << "'\n"; 00758 exit(1); 00759 } 00760 ++CurVariant; // We're in the next variant. 00761 break; 00762 case '}': 00763 ++LastEmitted; // consume '}' character. 00764 if (CurVariant == -1) { 00765 std::cerr << "Found '}' character outside of variant in inline asm " 00766 << "string: '" << AsmStr << "'\n"; 00767 exit(1); 00768 } 00769 CurVariant = -1; 00770 break; 00771 } 00772 } 00773 O << "\n\t" << InlineAsmEnd << "\n"; 00774 } 00775 00776 /// PrintAsmOperand - Print the specified operand of MI, an INLINEASM 00777 /// instruction, using the specified assembler variant. Targets should 00778 /// overried this to format as appropriate. 00779 bool AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 00780 unsigned AsmVariant, const char *ExtraCode) { 00781 // Target doesn't support this yet! 00782 return true; 00783 } 00784 00785 bool AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 00786 unsigned AsmVariant, 00787 const char *ExtraCode) { 00788 // Target doesn't support this yet! 00789 return true; 00790 } 00791 00792 /// printBasicBlockLabel - This method prints the label for the specified 00793 /// MachineBasicBlock 00794 void AsmPrinter::printBasicBlockLabel(const MachineBasicBlock *MBB, 00795 bool printColon, 00796 bool printComment) const { 00797 O << PrivateGlobalPrefix << "BB" << FunctionNumber << "_" 00798 << MBB->getNumber(); 00799 if (printColon) 00800 O << ':'; 00801 if (printComment) 00802 O << '\t' << CommentString << MBB->getBasicBlock()->getName(); 00803 }