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