LLVM API Documentation

AsmPrinter.cpp

Go to the documentation of this file.
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 }