LLVM API Documentation

ARMAsmPrinter.cpp

Go to the documentation of this file.
00001 //===-- ARMAsmPrinter.cpp - ARM LLVM assembly writer ----------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // 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 GAS-format ARM assembly language.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #define DEBUG_TYPE "asm-printer"
00016 #include "ARM.h"
00017 #include "ARMTargetMachine.h"
00018 #include "ARMAddressingModes.h"
00019 #include "ARMConstantPoolValue.h"
00020 #include "ARMMachineFunctionInfo.h"
00021 #include "llvm/Constants.h"
00022 #include "llvm/Module.h"
00023 #include "llvm/CodeGen/AsmPrinter.h"
00024 #include "llvm/CodeGen/DwarfWriter.h"
00025 #include "llvm/CodeGen/MachineModuleInfo.h"
00026 #include "llvm/CodeGen/MachineFunctionPass.h"
00027 #include "llvm/CodeGen/MachineJumpTableInfo.h"
00028 #include "llvm/Target/TargetAsmInfo.h"
00029 #include "llvm/Target/TargetData.h"
00030 #include "llvm/Target/TargetMachine.h"
00031 #include "llvm/Target/TargetOptions.h"
00032 #include "llvm/ADT/Statistic.h"
00033 #include "llvm/ADT/StringExtras.h"
00034 #include "llvm/ADT/StringSet.h"
00035 #include "llvm/Support/Compiler.h"
00036 #include "llvm/Support/Mangler.h"
00037 #include "llvm/Support/MathExtras.h"
00038 #include "llvm/Support/raw_ostream.h"
00039 #include <cctype>
00040 using namespace llvm;
00041 
00042 STATISTIC(EmittedInsts, "Number of machine instrs printed");
00043 
00044 namespace {
00045   struct VISIBILITY_HIDDEN ARMAsmPrinter : public AsmPrinter {
00046     ARMAsmPrinter(raw_ostream &O, TargetMachine &TM, const TargetAsmInfo *T)
00047       : AsmPrinter(O, TM, T), DW(0), MMI(NULL), AFI(NULL), MCP(NULL),
00048         InCPMode(false) {
00049       Subtarget = &TM.getSubtarget<ARMSubtarget>();
00050     }
00051 
00052     DwarfWriter *DW;
00053     MachineModuleInfo *MMI;
00054 
00055     /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
00056     /// make the right decision when printing asm code for different targets.
00057     const ARMSubtarget *Subtarget;
00058 
00059     /// AFI - Keep a pointer to ARMFunctionInfo for the current
00060     /// MachineFunction.
00061     ARMFunctionInfo *AFI;
00062 
00063     /// MCP - Keep a pointer to constantpool entries of the current
00064     /// MachineFunction.
00065     const MachineConstantPool *MCP;
00066 
00067     /// We name each basic block in a Function with a unique number, so
00068     /// that we can consistently refer to them later. This is cleared
00069     /// at the beginning of each call to runOnMachineFunction().
00070     ///
00071     typedef std::map<const Value *, unsigned> ValueMapTy;
00072     ValueMapTy NumberForBB;
00073 
00074     /// GVNonLazyPtrs - Keeps the set of GlobalValues that require
00075     /// non-lazy-pointers for indirect access.
00076     StringSet<> GVNonLazyPtrs;
00077 
00078     /// HiddenGVNonLazyPtrs - Keeps the set of GlobalValues with hidden
00079     /// visibility that require non-lazy-pointers for indirect access.
00080     StringSet<> HiddenGVNonLazyPtrs;
00081 
00082     /// FnStubs - Keeps the set of external function GlobalAddresses that the
00083     /// asm printer should generate stubs for.
00084     StringSet<> FnStubs;
00085 
00086     /// True if asm printer is printing a series of CONSTPOOL_ENTRY.
00087     bool InCPMode;
00088     
00089     virtual const char *getPassName() const {
00090       return "ARM Assembly Printer";
00091     }
00092 
00093     void printOperand(const MachineInstr *MI, int opNum,
00094                       const char *Modifier = 0);
00095     void printSOImmOperand(const MachineInstr *MI, int opNum);
00096     void printSOImm2PartOperand(const MachineInstr *MI, int opNum);
00097     void printSORegOperand(const MachineInstr *MI, int opNum);
00098     void printAddrMode2Operand(const MachineInstr *MI, int OpNo);
00099     void printAddrMode2OffsetOperand(const MachineInstr *MI, int OpNo);
00100     void printAddrMode3Operand(const MachineInstr *MI, int OpNo);
00101     void printAddrMode3OffsetOperand(const MachineInstr *MI, int OpNo);
00102     void printAddrMode4Operand(const MachineInstr *MI, int OpNo,
00103                                const char *Modifier = 0);
00104     void printAddrMode5Operand(const MachineInstr *MI, int OpNo,
00105                                const char *Modifier = 0);
00106     void printAddrModePCOperand(const MachineInstr *MI, int OpNo,
00107                                 const char *Modifier = 0);
00108     void printThumbAddrModeRROperand(const MachineInstr *MI, int OpNo);
00109     void printThumbAddrModeRI5Operand(const MachineInstr *MI, int OpNo,
00110                                       unsigned Scale);
00111     void printThumbAddrModeS1Operand(const MachineInstr *MI, int OpNo);
00112     void printThumbAddrModeS2Operand(const MachineInstr *MI, int OpNo);
00113     void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNo);
00114     void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNo);
00115     void printPredicateOperand(const MachineInstr *MI, int opNum);
00116     void printSBitModifierOperand(const MachineInstr *MI, int opNum);
00117     void printPCLabel(const MachineInstr *MI, int opNum);
00118     void printRegisterList(const MachineInstr *MI, int opNum);
00119     void printCPInstOperand(const MachineInstr *MI, int opNum,
00120                             const char *Modifier);
00121     void printJTBlockOperand(const MachineInstr *MI, int opNum);
00122 
00123     virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
00124                                  unsigned AsmVariant, const char *ExtraCode);
00125 
00126     void printModuleLevelGV(const GlobalVariable* GVar);
00127     bool printInstruction(const MachineInstr *MI);  // autogenerated.
00128     void printMachineInstruction(const MachineInstr *MI);
00129     bool runOnMachineFunction(MachineFunction &F);
00130     bool doInitialization(Module &M);
00131     bool doFinalization(Module &M);
00132 
00133     /// EmitMachineConstantPoolValue - Print a machine constantpool value to
00134     /// the .s file.
00135     virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
00136       printDataDirective(MCPV->getType());
00137 
00138       ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
00139       GlobalValue *GV = ACPV->getGV();
00140       std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix();
00141       if (!GV)
00142         Name += ACPV->getSymbol();
00143       if (ACPV->isNonLazyPointer()) {
00144         if (GV->hasHiddenVisibility())
00145           HiddenGVNonLazyPtrs.insert(Name);
00146         else
00147           GVNonLazyPtrs.insert(Name);
00148         printSuffixedName(Name, "$non_lazy_ptr");
00149       } else if (ACPV->isStub()) {
00150         FnStubs.insert(Name);
00151         printSuffixedName(Name, "$stub");
00152       } else
00153         O << Name;
00154       if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
00155       if (ACPV->getPCAdjustment() != 0) {
00156         O << "-(" << TAI->getPrivateGlobalPrefix() << "PC"
00157           << utostr(ACPV->getLabelId())
00158           << "+" << (unsigned)ACPV->getPCAdjustment();
00159          if (ACPV->mustAddCurrentAddress())
00160            O << "-.";
00161          O << ")";
00162       }
00163       O << "\n";
00164 
00165       // If the constant pool value is a extern weak symbol, remember to emit
00166       // the weak reference.
00167       if (GV && GV->hasExternalWeakLinkage())
00168         ExtWeakSymbols.insert(GV);
00169     }
00170     
00171     void getAnalysisUsage(AnalysisUsage &AU) const {
00172       AsmPrinter::getAnalysisUsage(AU);
00173       AU.setPreservesAll();
00174       AU.addRequired<MachineModuleInfo>();
00175       AU.addRequired<DwarfWriter>();
00176     }
00177   };
00178 } // end of anonymous namespace
00179 
00180 #include "ARMGenAsmWriter.inc"
00181 
00182 /// runOnMachineFunction - This uses the printInstruction()
00183 /// method to print assembly for each instruction.
00184 ///
00185 bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
00186   AFI = MF.getInfo<ARMFunctionInfo>();
00187   MCP = MF.getConstantPool();
00188 
00189   SetupMachineFunction(MF);
00190   O << "\n";
00191 
00192   // NOTE: we don't print out constant pools here, they are handled as
00193   // instructions.
00194 
00195   O << "\n";
00196   // Print out labels for the function.
00197   const Function *F = MF.getFunction();
00198   switch (F->getLinkage()) {
00199   default: assert(0 && "Unknown linkage type!");
00200   case Function::PrivateLinkage:
00201   case Function::InternalLinkage:
00202     SwitchToTextSection("\t.text", F);
00203     break;
00204   case Function::ExternalLinkage:
00205     SwitchToTextSection("\t.text", F);
00206     O << "\t.globl\t" << CurrentFnName << "\n";
00207     break;
00208   case Function::WeakLinkage:
00209   case Function::LinkOnceLinkage:
00210     if (Subtarget->isTargetDarwin()) {
00211       SwitchToTextSection(
00212                 ".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F);
00213       O << "\t.globl\t" << CurrentFnName << "\n";
00214       O << "\t.weak_definition\t" << CurrentFnName << "\n";
00215     } else {
00216       O << TAI->getWeakRefDirective() << CurrentFnName << "\n";
00217     }
00218     break;
00219   }
00220 
00221   printVisibility(CurrentFnName, F->getVisibility());
00222 
00223   if (AFI->isThumbFunction()) {
00224     EmitAlignment(1, F, AFI->getAlign());
00225     O << "\t.code\t16\n";
00226     O << "\t.thumb_func";
00227     if (Subtarget->isTargetDarwin())
00228       O << "\t" << CurrentFnName;
00229     O << "\n";
00230     InCPMode = false;
00231   } else
00232     EmitAlignment(2, F);
00233 
00234   O << CurrentFnName << ":\n";
00235   // Emit pre-function debug information.
00236   DW->BeginFunction(&MF);
00237 
00238   if (Subtarget->isTargetDarwin()) {
00239     // If the function is empty, then we need to emit *something*. Otherwise,
00240     // the function's label might be associated with something that it wasn't
00241     // meant to be associated with. We emit a noop in this situation.
00242     MachineFunction::iterator I = MF.begin();
00243 
00244     if (++I == MF.end() && MF.front().empty())
00245       O << "\tnop\n";
00246   }
00247 
00248   // Print out code for the function.
00249   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
00250        I != E; ++I) {
00251     // Print a label for the basic block.
00252     if (I != MF.begin()) {
00253       printBasicBlockLabel(I, true, true);
00254       O << '\n';
00255     }
00256     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
00257          II != E; ++II) {
00258       // Print the assembly for the instruction.
00259       printMachineInstruction(II);
00260     }
00261   }
00262 
00263   if (TAI->hasDotTypeDotSizeDirective())
00264     O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n";
00265 
00266   // Emit post-function debug information.
00267   DW->EndFunction(&MF);
00268 
00269   O.flush();
00270 
00271   return false;
00272 }
00273 
00274 void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
00275                                  const char *Modifier) {
00276   const MachineOperand &MO = MI->getOperand(opNum);
00277   switch (MO.getType()) {
00278   case MachineOperand::MO_Register:
00279     if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
00280       O << TM.getRegisterInfo()->get(MO.getReg()).AsmName;
00281     else
00282       assert(0 && "not implemented");
00283     break;
00284   case MachineOperand::MO_Immediate: {
00285     if (!Modifier || strcmp(Modifier, "no_hash") != 0)
00286       O << "#";
00287 
00288     O << (int)MO.getImm();
00289     break;
00290   }
00291   case MachineOperand::MO_MachineBasicBlock:
00292     printBasicBlockLabel(MO.getMBB());
00293     return;
00294   case MachineOperand::MO_GlobalAddress: {
00295     bool isCallOp = Modifier && !strcmp(Modifier, "call");
00296     GlobalValue *GV = MO.getGlobal();
00297     std::string Name = Mang->getValueName(GV);
00298     bool isExt = (GV->isDeclaration() || GV->hasWeakLinkage() ||
00299                   GV->hasLinkOnceLinkage());
00300     if (isExt && isCallOp && Subtarget->isTargetDarwin() &&
00301         TM.getRelocationModel() != Reloc::Static) {
00302       printSuffixedName(Name, "$stub");
00303       FnStubs.insert(Name);
00304     } else
00305       O << Name;
00306 
00307     printOffset(MO.getOffset());
00308 
00309     if (isCallOp && Subtarget->isTargetELF() &&
00310         TM.getRelocationModel() == Reloc::PIC_)
00311       O << "(PLT)";
00312     if (GV->hasExternalWeakLinkage())
00313       ExtWeakSymbols.insert(GV);
00314     break;
00315   }
00316   case MachineOperand::MO_ExternalSymbol: {
00317     bool isCallOp = Modifier && !strcmp(Modifier, "call");
00318     std::string Name(TAI->getGlobalPrefix());
00319     Name += MO.getSymbolName();
00320     if (isCallOp && Subtarget->isTargetDarwin() &&
00321         TM.getRelocationModel() != Reloc::Static) {
00322       printSuffixedName(Name, "$stub");
00323       FnStubs.insert(Name);
00324     } else
00325       O << Name;
00326     if (isCallOp && Subtarget->isTargetELF() &&
00327         TM.getRelocationModel() == Reloc::PIC_)
00328       O << "(PLT)";
00329     break;
00330   }
00331   case MachineOperand::MO_ConstantPoolIndex:
00332     O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
00333       << '_' << MO.getIndex();
00334     break;
00335   case MachineOperand::MO_JumpTableIndex:
00336     O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
00337       << '_' << MO.getIndex();
00338     break;
00339   default:
00340     O << "<unknown operand type>"; abort (); break;
00341   }
00342 }
00343 
00344 static void printSOImm(raw_ostream &O, int64_t V, const TargetAsmInfo *TAI) {
00345   assert(V < (1 << 12) && "Not a valid so_imm value!");
00346   unsigned Imm = ARM_AM::getSOImmValImm(V);
00347   unsigned Rot = ARM_AM::getSOImmValRot(V);
00348 
00349   // Print low-level immediate formation info, per
00350   // A5.1.3: "Data-processing operands - Immediate".
00351   if (Rot) {
00352     O << "#" << Imm << ", " << Rot;
00353     // Pretty printed version.
00354     O << ' ' << TAI->getCommentString() << ' ' << (int)ARM_AM::rotr32(Imm, Rot);
00355   } else {
00356     O << "#" << Imm;
00357   }
00358 }
00359 
00360 /// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
00361 /// immediate in bits 0-7.
00362 void ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) {
00363   const MachineOperand &MO = MI->getOperand(OpNum);
00364   assert(MO.isImm() && "Not a valid so_imm value!");
00365   printSOImm(O, MO.getImm(), TAI);
00366 }
00367 
00368 /// printSOImm2PartOperand - SOImm is broken into two pieces using a 'mov'
00369 /// followed by an 'orr' to materialize.
00370 void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum) {
00371   const MachineOperand &MO = MI->getOperand(OpNum);
00372   assert(MO.isImm() && "Not a valid so_imm value!");
00373   unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImm());
00374   unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImm());
00375   printSOImm(O, ARM_AM::getSOImmVal(V1), TAI);
00376   O << "\n\torr";
00377   printPredicateOperand(MI, 2);
00378   O << " ";
00379   printOperand(MI, 0); 
00380   O << ", ";
00381   printOperand(MI, 0); 
00382   O << ", ";
00383   printSOImm(O, ARM_AM::getSOImmVal(V2), TAI);
00384 }
00385 
00386 // so_reg is a 4-operand unit corresponding to register forms of the A5.1
00387 // "Addressing Mode 1 - Data-processing operands" forms.  This includes:
00388 //    REG 0   0    - e.g. R5
00389 //    REG REG 0,SH_OPC     - e.g. R5, ROR R3
00390 //    REG 0   IMM,SH_OPC  - e.g. R5, LSL #3
00391 void ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op) {
00392   const MachineOperand &MO1 = MI->getOperand(Op);
00393   const MachineOperand &MO2 = MI->getOperand(Op+1);
00394   const MachineOperand &MO3 = MI->getOperand(Op+2);
00395 
00396   assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
00397   O << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
00398 
00399   // Print the shift opc.
00400   O << ", "
00401     << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()))
00402     << " ";
00403 
00404   if (MO2.getReg()) {
00405     assert(TargetRegisterInfo::isPhysicalRegister(MO2.getReg()));
00406     O << TM.getRegisterInfo()->get(MO2.getReg()).AsmName;
00407     assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
00408   } else {
00409     O << "#" << ARM_AM::getSORegOffset(MO3.getImm());
00410   }
00411 }
00412 
00413 void ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op) {
00414   const MachineOperand &MO1 = MI->getOperand(Op);
00415   const MachineOperand &MO2 = MI->getOperand(Op+1);
00416   const MachineOperand &MO3 = MI->getOperand(Op+2);
00417 
00418   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
00419     printOperand(MI, Op);
00420     return;
00421   }
00422 
00423   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
00424 
00425   if (!MO2.getReg()) {
00426     if (ARM_AM::getAM2Offset(MO3.getImm()))  // Don't print +0.
00427       O << ", #"
00428         << (char)ARM_AM::getAM2Op(MO3.getImm())
00429         << ARM_AM::getAM2Offset(MO3.getImm());
00430     O << "]";
00431     return;
00432   }
00433 
00434   O << ", "
00435     << (char)ARM_AM::getAM2Op(MO3.getImm())
00436     << TM.getRegisterInfo()->get(MO2.getReg()).AsmName;
00437   
00438   if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
00439     O << ", "
00440       << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
00441       << " #" << ShImm;
00442   O << "]";
00443 }
00444 
00445 void ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op){
00446   const MachineOperand &MO1 = MI->getOperand(Op);
00447   const MachineOperand &MO2 = MI->getOperand(Op+1);
00448 
00449   if (!MO1.getReg()) {
00450     unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
00451     assert(ImmOffs && "Malformed indexed load / store!");
00452     O << "#"
00453       << (char)ARM_AM::getAM2Op(MO2.getImm())
00454       << ImmOffs;
00455     return;
00456   }
00457 
00458   O << (char)ARM_AM::getAM2Op(MO2.getImm())
00459     << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
00460   
00461   if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
00462     O << ", "
00463       << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm()))
00464       << " #" << ShImm;
00465 }
00466 
00467 void ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op) {
00468   const MachineOperand &MO1 = MI->getOperand(Op);
00469   const MachineOperand &MO2 = MI->getOperand(Op+1);
00470   const MachineOperand &MO3 = MI->getOperand(Op+2);
00471   
00472   assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
00473   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
00474 
00475   if (MO2.getReg()) {
00476     O << ", "
00477       << (char)ARM_AM::getAM3Op(MO3.getImm())
00478       << TM.getRegisterInfo()->get(MO2.getReg()).AsmName
00479       << "]";
00480     return;
00481   }
00482   
00483   if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
00484     O << ", #"
00485       << (char)ARM_AM::getAM3Op(MO3.getImm())
00486       << ImmOffs;
00487   O << "]";
00488 }
00489 
00490 void ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op){
00491   const MachineOperand &MO1 = MI->getOperand(Op);
00492   const MachineOperand &MO2 = MI->getOperand(Op+1);
00493 
00494   if (MO1.getReg()) {
00495     O << (char)ARM_AM::getAM3Op(MO2.getImm())
00496       << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
00497     return;
00498   }
00499 
00500   unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
00501   assert(ImmOffs && "Malformed indexed load / store!");
00502   O << "#"
00503     << (char)ARM_AM::getAM3Op(MO2.getImm())
00504     << ImmOffs;
00505 }
00506   
00507 void ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op,
00508                                           const char *Modifier) {
00509   const MachineOperand &MO1 = MI->getOperand(Op);
00510   const MachineOperand &MO2 = MI->getOperand(Op+1);
00511   ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
00512   if (Modifier && strcmp(Modifier, "submode") == 0) {
00513     if (MO1.getReg() == ARM::SP) {
00514       bool isLDM = (MI->getOpcode() == ARM::LDM ||
00515                     MI->getOpcode() == ARM::LDM_RET);
00516       O << ARM_AM::getAMSubModeAltStr(Mode, isLDM);
00517     } else
00518       O << ARM_AM::getAMSubModeStr(Mode);
00519   } else {
00520     printOperand(MI, Op);
00521     if (ARM_AM::getAM4WBFlag(MO2.getImm()))
00522       O << "!";
00523   }
00524 }
00525 
00526 void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
00527                                           const char *Modifier) {
00528   const MachineOperand &MO1 = MI->getOperand(Op);
00529   const MachineOperand &MO2 = MI->getOperand(Op+1);
00530 
00531   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
00532     printOperand(MI, Op);
00533     return;
00534   }
00535   
00536   assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
00537 
00538   if (Modifier && strcmp(Modifier, "submode") == 0) {
00539     ARM_AM::AMSubMode Mode = ARM_AM::getAM5SubMode(MO2.getImm());
00540     if (MO1.getReg() == ARM::SP) {
00541       bool isFLDM = (MI->getOpcode() == ARM::FLDMD ||
00542                      MI->getOpcode() == ARM::FLDMS);
00543       O << ARM_AM::getAMSubModeAltStr(Mode, isFLDM);
00544     } else
00545       O << ARM_AM::getAMSubModeStr(Mode);
00546     return;
00547   } else if (Modifier && strcmp(Modifier, "base") == 0) {
00548     // Used for FSTM{D|S} and LSTM{D|S} operations.
00549     O << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
00550     if (ARM_AM::getAM5WBFlag(MO2.getImm()))
00551       O << "!";
00552     return;
00553   }
00554   
00555   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
00556   
00557   if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
00558     O << ", #"
00559       << (char)ARM_AM::getAM5Op(MO2.getImm())
00560       << ImmOffs*4;
00561   }
00562   O << "]";
00563 }
00564 
00565 void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
00566                                            const char *Modifier) {
00567   if (Modifier && strcmp(Modifier, "label") == 0) {
00568     printPCLabel(MI, Op+1);
00569     return;
00570   }
00571 
00572   const MachineOperand &MO1 = MI->getOperand(Op);
00573   assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
00574   O << "[pc, +" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName << "]";
00575 }
00576 
00577 void
00578 ARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op) {
00579   const MachineOperand &MO1 = MI->getOperand(Op);
00580   const MachineOperand &MO2 = MI->getOperand(Op+1);
00581   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
00582   O << ", " << TM.getRegisterInfo()->get(MO2.getReg()).AsmName << "]";
00583 }
00584 
00585 void
00586 ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
00587                                             unsigned Scale) {
00588   const MachineOperand &MO1 = MI->getOperand(Op);
00589   const MachineOperand &MO2 = MI->getOperand(Op+1);
00590   const MachineOperand &MO3 = MI->getOperand(Op+2);
00591 
00592   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
00593     printOperand(MI, Op);
00594     return;
00595   }
00596 
00597   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
00598   if (MO3.getReg())
00599     O << ", " << TM.getRegisterInfo()->get(MO3.getReg()).AsmName;
00600   else if (unsigned ImmOffs = MO2.getImm()) {
00601     O << ", #" << ImmOffs;
00602     if (Scale > 1)
00603       O << " * " << Scale;
00604   }
00605   O << "]";
00606 }
00607 
00608 void
00609 ARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op) {
00610   printThumbAddrModeRI5Operand(MI, Op, 1);
00611 }
00612 void
00613 ARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op) {
00614   printThumbAddrModeRI5Operand(MI, Op, 2);
00615 }
00616 void
00617 ARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op) {
00618   printThumbAddrModeRI5Operand(MI, Op, 4);
00619 }
00620 
00621 void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op) {
00622   const MachineOperand &MO1 = MI->getOperand(Op);
00623   const MachineOperand &MO2 = MI->getOperand(Op+1);
00624   O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
00625   if (unsigned ImmOffs = MO2.getImm())
00626     O << ", #" << ImmOffs << " * 4";
00627   O << "]";
00628 }
00629 
00630 void ARMAsmPrinter::printPredicateOperand(const MachineInstr *MI, int opNum) {
00631   ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(opNum).getImm();
00632   if (CC != ARMCC::AL)
00633     O << ARMCondCodeToString(CC);
00634 }
00635 
00636 void ARMAsmPrinter::printSBitModifierOperand(const MachineInstr *MI, int opNum){
00637   unsigned Reg = MI->getOperand(opNum).getReg();
00638   if (Reg) {
00639     assert(Reg == ARM::CPSR && "Expect ARM CPSR register!");
00640     O << 's';
00641   }
00642 }
00643 
00644 void ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int opNum) {
00645   int Id = (int)MI->getOperand(opNum).getImm();
00646   O << TAI->getPrivateGlobalPrefix() << "PC" << Id;
00647 }
00648 
00649 void ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int opNum) {
00650   O << "{";
00651   for (unsigned i = opNum, e = MI->getNumOperands(); i != e; ++i) {
00652     printOperand(MI, i);
00653     if (i != e-1) O << ", ";
00654   }
00655   O << "}";
00656 }
00657 
00658 void ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNo,
00659                                        const char *Modifier) {
00660   assert(Modifier && "This operand only works with a modifier!");
00661   // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
00662   // data itself.
00663   if (!strcmp(Modifier, "label")) {
00664     unsigned ID = MI->getOperand(OpNo).getImm();
00665     O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
00666       << '_' << ID << ":\n";
00667   } else {
00668     assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
00669     unsigned CPI = MI->getOperand(OpNo).getIndex();
00670 
00671     const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI];
00672     
00673     if (MCPE.isMachineConstantPoolEntry()) {
00674       EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
00675     } else {
00676       EmitGlobalConstant(MCPE.Val.ConstVal);
00677       // remember to emit the weak reference
00678       if (const GlobalValue *GV = dyn_cast<GlobalValue>(MCPE.Val.ConstVal))
00679         if (GV->hasExternalWeakLinkage())
00680           ExtWeakSymbols.insert(GV);
00681     }
00682   }
00683 }
00684 
00685 void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNo) {
00686   const MachineOperand &MO1 = MI->getOperand(OpNo);
00687   const MachineOperand &MO2 = MI->getOperand(OpNo+1); // Unique Id
00688   unsigned JTI = MO1.getIndex();
00689   O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
00690     << '_' << JTI << '_' << MO2.getImm() << ":\n";
00691 
00692   const char *JTEntryDirective = TAI->getJumpTableDirective();
00693   if (!JTEntryDirective)
00694     JTEntryDirective = TAI->getData32bitsDirective();
00695 
00696   const MachineFunction *MF = MI->getParent()->getParent();
00697   const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
00698   const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
00699   const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
00700   bool UseSet= TAI->getSetDirective() && TM.getRelocationModel() == Reloc::PIC_;
00701   std::set<MachineBasicBlock*> JTSets;
00702   for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
00703     MachineBasicBlock *MBB = JTBBs[i];
00704     if (UseSet && JTSets.insert(MBB).second)
00705       printPICJumpTableSetLabel(JTI, MO2.getImm(), MBB);
00706 
00707     O << JTEntryDirective << ' ';
00708     if (UseSet)
00709       O << TAI->getPrivateGlobalPrefix() << getFunctionNumber()
00710         << '_' << JTI << '_' << MO2.getImm()
00711         << "_set_" << MBB->getNumber();
00712     else if (TM.getRelocationModel() == Reloc::PIC_) {
00713       printBasicBlockLabel(MBB, false, false, false);
00714       // If the arch uses custom Jump Table directives, don't calc relative to JT
00715       if (!TAI->getJumpTableDirective()) 
00716         O << '-' << TAI->getPrivateGlobalPrefix() << "JTI"
00717           << getFunctionNumber() << '_' << JTI << '_' << MO2.getImm();
00718     } else
00719       printBasicBlockLabel(MBB, false, false, false);
00720     if (i != e-1)
00721       O << '\n';
00722   }
00723 }
00724 
00725 
00726 bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
00727                                     unsigned AsmVariant, const char *ExtraCode){
00728   // Does this asm operand have a single letter operand modifier?
00729   if (ExtraCode && ExtraCode[0]) {
00730     if (ExtraCode[1] != 0) return true; // Unknown modifier.
00731     
00732     switch (ExtraCode[0]) {
00733     default: return true;  // Unknown modifier.
00734     case 'c': // Don't print "$" before a global var name or constant.
00735     case 'P': // Print a VFP double precision register.
00736       printOperand(MI, OpNo);
00737       return false;
00738     case 'Q':
00739       if (TM.getTargetData()->isLittleEndian())
00740         break;
00741       // Fallthrough
00742     case 'R':
00743       if (TM.getTargetData()->isBigEndian())
00744         break;
00745       // Fallthrough
00746     case 'H': // Write second word of DI / DF reference.  
00747       // Verify that this operand has two consecutive registers.
00748       if (!MI->getOperand(OpNo).isReg() ||
00749           OpNo+1 == MI->getNumOperands() ||
00750           !MI->getOperand(OpNo+1).isReg())
00751         return true;
00752       ++OpNo;   // Return the high-part.
00753     }
00754   }
00755   
00756   printOperand(MI, OpNo);
00757   return false;
00758 }
00759 
00760 void ARMAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
00761   ++EmittedInsts;
00762 
00763   int Opc = MI->getOpcode();
00764   switch (Opc) {
00765   case ARM::CONSTPOOL_ENTRY:
00766     if (!InCPMode && AFI->isThumbFunction()) {
00767       EmitAlignment(2);
00768       InCPMode = true;
00769     }
00770     break;
00771   default: {
00772     if (InCPMode && AFI->isThumbFunction())
00773       InCPMode = false;
00774   }}
00775 
00776   // Call the autogenerated instruction printer routines.
00777   printInstruction(MI);
00778 }
00779 
00780 bool ARMAsmPrinter::doInitialization(Module &M) {
00781 
00782   bool Result = AsmPrinter::doInitialization(M);
00783 
00784   // Emit initial debug information.
00785   MMI = getAnalysisIfAvailable<MachineModuleInfo>();
00786   assert(MMI);
00787   DW = getAnalysisIfAvailable<DwarfWriter>();
00788   assert(DW && "Dwarf Writer is not available");
00789   DW->BeginModule(&M, MMI, O, this, TAI);
00790 
00791   // Darwin wants symbols to be quoted if they have complex names.
00792   if (Subtarget->isTargetDarwin())
00793     Mang->setUseQuotes(true);
00794 
00795   return Result;
00796 }
00797 
00798 /// PrintUnmangledNameSafely - Print out the printable characters in the name.
00799 /// Don't print things like \n or \0.
00800 static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) {
00801   for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen();
00802        Name != E; ++Name)
00803     if (isprint(*Name))
00804       OS << *Name;
00805 }
00806 
00807 void ARMAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
00808   const TargetData *TD = TM.getTargetData();
00809 
00810   if (!GVar->hasInitializer())   // External global require no code
00811     return;
00812 
00813   // Check to see if this is a special global used by LLVM, if so, emit it.
00814 
00815   if (EmitSpecialLLVMGlobal(GVar)) {
00816     if (Subtarget->isTargetDarwin() &&
00817         TM.getRelocationModel() == Reloc::Static) {
00818       if (GVar->getName() == "llvm.global_ctors")
00819         O << ".reference .constructors_used\n";
00820       else if (GVar->getName() == "llvm.global_dtors")
00821         O << ".reference .destructors_used\n";
00822     }
00823     return;
00824   }
00825 
00826   std::string name = Mang->getValueName(GVar);
00827   Constant *C = GVar->getInitializer();
00828   const Type *Type = C->getType();
00829   unsigned Size = TD->getTypePaddedSize(Type);
00830   unsigned Align = TD->getPreferredAlignmentLog(GVar);
00831   bool isDarwin = Subtarget->isTargetDarwin();
00832 
00833   printVisibility(name, GVar->getVisibility());
00834 
00835   if (Subtarget->isTargetELF())
00836     O << "\t.type " << name << ",%object\n";
00837 
00838   if (C->isNullValue() && !GVar->hasSection() && !GVar->isThreadLocal()) {
00839     // FIXME: This seems to be pretty darwin-specific
00840 
00841     if (GVar->hasExternalLinkage()) {
00842       SwitchToSection(TAI->SectionForGlobal(GVar));
00843       if (const char *Directive = TAI->getZeroFillDirective()) {
00844         O << "\t.globl\t" << name << "\n";
00845         O << Directive << "__DATA, __common, " << name << ", "
00846           << Size << ", " << Align << "\n";
00847         return;
00848       }
00849     }
00850 
00851     if (GVar->hasLocalLinkage() || GVar->mayBeOverridden()) {
00852       if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
00853 
00854       if (isDarwin) {
00855         if (GVar->hasLocalLinkage()) {
00856           O << TAI->getLCOMMDirective()  << name << "," << Size
00857             << ',' << Align;
00858         } else if (GVar->hasCommonLinkage()) {
00859           O << TAI->getCOMMDirective()  << name << "," << Size
00860             << ',' << Align;
00861         } else {
00862           SwitchToSection(TAI->SectionForGlobal(GVar));
00863           O << "\t.globl " << name << '\n'
00864             << TAI->getWeakDefDirective() << name << '\n';
00865           EmitAlignment(Align, GVar);
00866           O << name << ":\t\t\t\t" << TAI->getCommentString() << ' ';
00867           PrintUnmangledNameSafely(GVar, O);
00868           O << '\n';
00869           EmitGlobalConstant(C);
00870           return;
00871         }
00872       } else if (TAI->getLCOMMDirective() != NULL) {
00873         if (GVar->hasLocalLinkage()) {
00874           O << TAI->getLCOMMDirective() << name << "," << Size;
00875         } else {
00876           O << TAI->getCOMMDirective()  << name << "," << Size;
00877           if (TAI->getCOMMDirectiveTakesAlignment())
00878             O << ',' << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
00879         }
00880       } else {
00881         SwitchToSection(TAI->SectionForGlobal(GVar));
00882         if (GVar->hasLocalLinkage())
00883           O << "\t.local\t" << name << "\n";
00884         O << TAI->getCOMMDirective()  << name << "," << Size;
00885         if (TAI->getCOMMDirectiveTakesAlignment())
00886           O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
00887       }
00888       O << "\t\t" << TAI->getCommentString() << " ";
00889       PrintUnmangledNameSafely(GVar, O);
00890       O << "\n";
00891       return;
00892     }
00893   }
00894 
00895   SwitchToSection(TAI->SectionForGlobal(GVar));
00896   switch (GVar->getLinkage()) {
00897    case GlobalValue::CommonLinkage:
00898    case GlobalValue::LinkOnceLinkage:
00899    case GlobalValue::WeakLinkage:
00900     if (isDarwin) {
00901       O << "\t.globl " << name << "\n"
00902         << "\t.weak_definition " << name << "\n";
00903     } else {
00904       O << "\t.weak " << name << "\n";
00905     }
00906     break;
00907    case GlobalValue::AppendingLinkage:
00908     // FIXME: appending linkage variables should go into a section of
00909     // their name or something.  For now, just emit them as external.
00910    case GlobalValue::ExternalLinkage:
00911     O << "\t.globl " << name << "\n";
00912     // FALL THROUGH
00913    case GlobalValue::PrivateLinkage:
00914    case GlobalValue::InternalLinkage:
00915     break;
00916    default:
00917     assert(0 && "Unknown linkage type!");
00918     break;
00919   }
00920 
00921   EmitAlignment(Align, GVar);
00922   O << name << ":\t\t\t\t" << TAI->getCommentString() << " ";
00923   PrintUnmangledNameSafely(GVar, O);
00924   O << "\n";
00925   if (TAI->hasDotTypeDotSizeDirective())
00926     O << "\t.size " << name << ", " << Size << "\n";
00927 
00928   // If the initializer is a extern weak symbol, remember to emit the weak
00929   // reference!
00930   if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
00931     if (GV->hasExternalWeakLinkage())
00932       ExtWeakSymbols.insert(GV);
00933 
00934   EmitGlobalConstant(C);
00935   O << '\n';
00936 }
00937 
00938 
00939 bool ARMAsmPrinter::doFinalization(Module &M) {
00940   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
00941        I != E; ++I)
00942     printModuleLevelGV(I);
00943 
00944   if (Subtarget->isTargetDarwin()) {
00945     SwitchToDataSection("");
00946 
00947     // Output stubs for dynamically-linked functions
00948     for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end();
00949          i != e; ++i) {
00950       if (TM.getRelocationModel() == Reloc::PIC_)
00951         SwitchToTextSection(".section __TEXT,__picsymbolstub4,symbol_stubs,"
00952                             "none,16", 0);
00953       else
00954         SwitchToTextSection(".section __TEXT,__symbol_stub4,symbol_stubs,"
00955                             "none,12", 0);
00956 
00957       EmitAlignment(2);
00958       O << "\t.code\t32\n";
00959 
00960       const char *p = i->getKeyData();
00961       printSuffixedName(p, "$stub");
00962       O << ":\n";
00963       O << "\t.indirect_symbol " << p << "\n";
00964       O << "\tldr ip, ";
00965       printSuffixedName(p, "$slp");
00966       O << "\n";
00967       if (TM.getRelocationModel() == Reloc::PIC_) {
00968         printSuffixedName(p, "$scv");
00969         O << ":\n";
00970         O << "\tadd ip, pc, ip\n";
00971       }
00972       O << "\tldr pc, [ip, #0]\n";
00973       printSuffixedName(p, "$slp");
00974       O << ":\n";
00975       O << "\t.long\t";
00976       printSuffixedName(p, "$lazy_ptr");
00977       if (TM.getRelocationModel() == Reloc::PIC_) {
00978         O << "-(";
00979         printSuffixedName(p, "$scv");
00980         O << "+8)\n";
00981       } else
00982         O << "\n";
00983       SwitchToDataSection(".lazy_symbol_pointer", 0);
00984       printSuffixedName(p, "$lazy_ptr");
00985       O << ":\n";
00986       O << "\t.indirect_symbol " << p << "\n";
00987       O << "\t.long\tdyld_stub_binding_helper\n";
00988     }
00989     O << "\n";
00990 
00991     // Output non-lazy-pointers for external and common global variables.
00992     if (!GVNonLazyPtrs.empty()) {
00993       SwitchToDataSection("\t.non_lazy_symbol_pointer", 0);
00994       for (StringSet<>::iterator i =  GVNonLazyPtrs.begin(),
00995              e = GVNonLazyPtrs.end(); i != e; ++i) {
00996         const char *p = i->getKeyData();
00997         printSuffixedName(p, "$non_lazy_ptr");
00998         O << ":\n";
00999         O << "\t.indirect_symbol " << p << "\n";
01000         O << "\t.long\t0\n";
01001       }
01002     }
01003 
01004     if (!HiddenGVNonLazyPtrs.empty()) {
01005       SwitchToSection(TAI->getDataSection());
01006       for (StringSet<>::iterator i = HiddenGVNonLazyPtrs.begin(),
01007              e = HiddenGVNonLazyPtrs.end(); i != e; ++i) {
01008         const char *p = i->getKeyData();
01009         EmitAlignment(2);
01010         printSuffixedName(p, "$non_lazy_ptr");
01011         O << ":\n";
01012         O << "\t.long " << p << "\n";
01013       }
01014     }
01015 
01016 
01017     // Emit initial debug information.
01018     DW->EndModule();
01019 
01020     // Funny Darwin hack: This flag tells the linker that no global symbols
01021     // contain code that falls through to other global symbols (e.g. the obvious
01022     // implementation of multiple entry points).  If this doesn't occur, the
01023     // linker can safely perform dead code stripping.  Since LLVM never
01024     // generates code that does this, it is always safe to set.
01025     O << "\t.subsections_via_symbols\n";
01026   } else {
01027     // Emit final debug information for ELF.
01028     DW->EndModule();
01029   }
01030 
01031   return AsmPrinter::doFinalization(M);
01032 }
01033 
01034 /// createARMCodePrinterPass - Returns a pass that prints the ARM
01035 /// assembly code for a MachineFunction to the given output stream,
01036 /// using the given target machine description.  This should work
01037 /// regardless of whether the function is in SSA form.
01038 ///
01039 FunctionPass *llvm::createARMCodePrinterPass(raw_ostream &o,
01040                                              ARMTargetMachine &tm) {
01041   return new ARMAsmPrinter(o, tm, tm.getTargetAsmInfo());
01042 }
01043 
01044 namespace {
01045   static struct Register {
01046     Register() {
01047       ARMTargetMachine::registerAsmPrinter(createARMCodePrinterPass);
01048     }
01049   } Registrator;
01050 }