ARMAsmPrinter.cpp revision 0f3cc657387d44cd7c56e4ddea896a50ab9106b8
17bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===-- ARMAsmPrinter.cpp - ARM LLVM assembly writer ----------------------===// 27bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// 37bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// The LLVM Compiler Infrastructure 47bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 67bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// License. See LICENSE.TXT for details. 77bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// 87bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===----------------------------------------------------------------------===// 97bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// 107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// This file contains a printer that converts from our internal representation 117bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// of machine-dependent LLVM code to GAS-format ARM assembly language. 127bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// 137bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===----------------------------------------------------------------------===// 147bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1595b2c7da5e83670881270c1cd231a240be0556d9Chris Lattner#define DEBUG_TYPE "asm-printer" 167bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARM.h" 17a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMTargetMachine.h" 18a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMAddressingModes.h" 19a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMConstantPoolValue.h" 20a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMMachineFunctionInfo.h" 217bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Constants.h" 227bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Module.h" 237bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/AsmPrinter.h" 24a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/DwarfWriter.h" 2544c3b9fdd416c79f4b67cde1aecfced5921efd81Jim Laskey#include "llvm/CodeGen/MachineModuleInfo.h" 267bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFunctionPass.h" 27a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h" 28563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey#include "llvm/Target/TargetAsmInfo.h" 29b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola#include "llvm/Target/TargetData.h" 307bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Target/TargetMachine.h" 315be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng#include "llvm/Target/TargetOptions.h" 327bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/ADT/Statistic.h" 337bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/ADT/StringExtras.h" 34a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/Support/Compiler.h" 35a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/Support/Mangler.h" 367bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Support/MathExtras.h" 377bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <cctype> 387bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm; 397bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 4095b2c7da5e83670881270c1cd231a240be0556d9Chris LattnerSTATISTIC(EmittedInsts, "Number of machine instrs printed"); 417bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 4295b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace { 43563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey struct VISIBILITY_HIDDEN ARMAsmPrinter : public AsmPrinter { 44a0f3d17daac73c9c71aad497b298cbe82848f726Jim Laskey ARMAsmPrinter(std::ostream &O, TargetMachine &TM, const TargetAsmInfo *T) 45f2452c5f48e13cf3a9e620d22d5040a90133ddcaDale Johannesen : AsmPrinter(O, TM, T), DW(O, this, T), MMI(NULL), AFI(NULL), 46f2452c5f48e13cf3a9e620d22d5040a90133ddcaDale Johannesen InCPMode(false) { 47a8e2989ece6dc46df59b0768184028257f913843Evan Cheng Subtarget = &TM.getSubtarget<ARMSubtarget>(); 48563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey } 497bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 50a8e2989ece6dc46df59b0768184028257f913843Evan Cheng DwarfWriter DW; 51f2452c5f48e13cf3a9e620d22d5040a90133ddcaDale Johannesen MachineModuleInfo *MMI; 52a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 53a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can 54a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// make the right decision when printing asm code for different targets. 55a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const ARMSubtarget *Subtarget; 56a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 57a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// AFI - Keep a pointer to ARMFunctionInfo for the current 58a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// MachineFunction 59a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ARMFunctionInfo *AFI; 60a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 617bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola /// We name each basic block in a Function with a unique number, so 627bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola /// that we can consistently refer to them later. This is cleared 637bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola /// at the beginning of each call to runOnMachineFunction(). 647bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola /// 657bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola typedef std::map<const Value *, unsigned> ValueMapTy; 667bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola ValueMapTy NumberForBB; 677bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 68a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// Keeps the set of GlobalValues that require non-lazy-pointers for 69a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// indirect access. 70a8e2989ece6dc46df59b0768184028257f913843Evan Cheng std::set<std::string> GVNonLazyPtrs; 71a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 72a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// Keeps the set of external function GlobalAddresses that the asm 73a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// printer should generate stubs for. 74a8e2989ece6dc46df59b0768184028257f913843Evan Cheng std::set<std::string> FnStubs; 75a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 76a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// True if asm printer is printing a series of CONSTPOOL_ENTRY. 77a8e2989ece6dc46df59b0768184028257f913843Evan Cheng bool InCPMode; 78a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 797bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola virtual const char *getPassName() const { 807bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola return "ARM Assembly Printer"; 817bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola } 827bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 83a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printOperand(const MachineInstr *MI, int opNum, 84a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier = 0); 85a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printSOImmOperand(const MachineInstr *MI, int opNum); 86c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng void printSOImm2PartOperand(const MachineInstr *MI, int opNum); 87a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printSORegOperand(const MachineInstr *MI, int opNum); 88a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printAddrMode2Operand(const MachineInstr *MI, int OpNo); 89a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printAddrMode2OffsetOperand(const MachineInstr *MI, int OpNo); 90a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printAddrMode3Operand(const MachineInstr *MI, int OpNo); 91a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printAddrMode3OffsetOperand(const MachineInstr *MI, int OpNo); 92a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printAddrMode4Operand(const MachineInstr *MI, int OpNo, 93a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier = 0); 94a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printAddrMode5Operand(const MachineInstr *MI, int OpNo, 95a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier = 0); 96a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printAddrModePCOperand(const MachineInstr *MI, int OpNo, 97a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier = 0); 98a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printThumbAddrModeRROperand(const MachineInstr *MI, int OpNo); 99a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printThumbAddrModeRI5Operand(const MachineInstr *MI, int OpNo, 100a8e2989ece6dc46df59b0768184028257f913843Evan Cheng unsigned Scale); 101c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan Cheng void printThumbAddrModeS1Operand(const MachineInstr *MI, int OpNo); 102c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan Cheng void printThumbAddrModeS2Operand(const MachineInstr *MI, int OpNo); 103c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan Cheng void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNo); 104a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNo); 10542d712b3067ec14170f80d8adfc7e5ad5878132bEvan Cheng void printPredicateOperand(const MachineInstr *MI, int opNum); 106dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng void printSBitModifierOperand(const MachineInstr *MI, int opNum); 107a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printPCLabel(const MachineInstr *MI, int opNum); 108a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printRegisterList(const MachineInstr *MI, int opNum); 109a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printCPInstOperand(const MachineInstr *MI, int opNum, 110a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier); 111a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printJTBlockOperand(const MachineInstr *MI, int opNum); 112a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 113a8e2989ece6dc46df59b0768184028257f913843Evan Cheng virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 114a8e2989ece6dc46df59b0768184028257f913843Evan Cheng unsigned AsmVariant, const char *ExtraCode); 1157bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1160f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov void printModuleLevelGV(const GlobalVariable* GVar); 1177bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola bool printInstruction(const MachineInstr *MI); // autogenerated. 118a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printMachineInstruction(const MachineInstr *MI); 1197bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola bool runOnMachineFunction(MachineFunction &F); 1207bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola bool doInitialization(Module &M); 1217bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola bool doFinalization(Module &M); 122a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 1230f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov /// getSectionForFunction - Return the section that we should emit the 1240f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov /// specified function body into. 1250f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov virtual std::string getSectionForFunction(const Function &F) const; 1260f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov 127a8e2989ece6dc46df59b0768184028257f913843Evan Cheng virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 128a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printDataDirective(MCPV->getType()); 129a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 130a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ARMConstantPoolValue *ACPV = (ARMConstantPoolValue*)MCPV; 1311a92d941b3541f0c361caad499d0eb37a8339453Lauro Ramos Venancio GlobalValue *GV = ACPV->getGV(); 132c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix(); 133c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng if (!GV) 134c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng Name += ACPV->getSymbol(); 135a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ACPV->isNonLazyPointer()) { 136a8e2989ece6dc46df59b0768184028257f913843Evan Cheng GVNonLazyPtrs.insert(Name); 137c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen printSuffixedName(Name, "$non_lazy_ptr"); 138c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng } else if (ACPV->isStub()) { 139c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng FnStubs.insert(Name); 140c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen printSuffixedName(Name, "$stub"); 141a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else 142a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << Name; 1430ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")"; 14464f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio if (ACPV->getPCAdjustment() != 0) { 145a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "-(" << TAI->getPrivateGlobalPrefix() << "PC" 146a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << utostr(ACPV->getLabelId()) 14764f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio << "+" << (unsigned)ACPV->getPCAdjustment(); 14864f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio if (ACPV->mustAddCurrentAddress()) 14964f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio O << "-."; 15064f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio O << ")"; 15164f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio } 152a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\n"; 1531a92d941b3541f0c361caad499d0eb37a8339453Lauro Ramos Venancio 1541a92d941b3541f0c361caad499d0eb37a8339453Lauro Ramos Venancio // If the constant pool value is a extern weak symbol, remember to emit 1551a92d941b3541f0c361caad499d0eb37a8339453Lauro Ramos Venancio // the weak reference. 156c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng if (GV && GV->hasExternalWeakLinkage()) 1571a92d941b3541f0c361caad499d0eb37a8339453Lauro Ramos Venancio ExtWeakSymbols.insert(GV); 158a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 159a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 160a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void getAnalysisUsage(AnalysisUsage &AU) const { 161cd8bc05102e7963a5839cfdca7785390288bc745Gordon Henriksen AsmPrinter::getAnalysisUsage(AU); 162a8e2989ece6dc46df59b0768184028257f913843Evan Cheng AU.setPreservesAll(); 16344c3b9fdd416c79f4b67cde1aecfced5921efd81Jim Laskey AU.addRequired<MachineModuleInfo>(); 164a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 1657bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola }; 1667bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace 1677bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1687bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARMGenAsmWriter.inc" 1697bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1707bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// createARMCodePrinterPass - Returns a pass that prints the ARM 1717bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// assembly code for a MachineFunction to the given output stream, 1727bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// using the given target machine description. This should work 1737bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// regardless of whether the function is in SSA form. 1747bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// 1757bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaFunctionPass *llvm::createARMCodePrinterPass(std::ostream &o, 176a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ARMTargetMachine &tm) { 177a0f3d17daac73c9c71aad497b298cbe82848f726Jim Laskey return new ARMAsmPrinter(o, tm, tm.getTargetAsmInfo()); 1787bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 1797bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1800f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov// Substitute old hook with new one temporary 1810f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikovstd::string ARMAsmPrinter::getSectionForFunction(const Function &F) const { 1820f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov return TAI->SectionForGlobal(&F); 1830f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov} 1840f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov 185a8e2989ece6dc46df59b0768184028257f913843Evan Cheng/// runOnMachineFunction - This uses the printInstruction() 1867bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction. 1877bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// 1887bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 189a8e2989ece6dc46df59b0768184028257f913843Evan Cheng AFI = MF.getInfo<ARMFunctionInfo>(); 190a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 191a8e2989ece6dc46df59b0768184028257f913843Evan Cheng SetupMachineFunction(MF); 192a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\n"; 193a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 194a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // NOTE: we don't print out constant pools here, they are handled as 195a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // instructions. 1964b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola 197a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\n"; 1984b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola // Print out labels for the function. 1994b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola const Function *F = MF.getFunction(); 2004b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola switch (F->getLinkage()) { 2014b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola default: assert(0 && "Unknown linkage type!"); 2024b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola case Function::InternalLinkage: 203a8e2989ece6dc46df59b0768184028257f913843Evan Cheng SwitchToTextSection("\t.text", F); 2044b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola break; 2054b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola case Function::ExternalLinkage: 206a8e2989ece6dc46df59b0768184028257f913843Evan Cheng SwitchToTextSection("\t.text", F); 2074b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola O << "\t.globl\t" << CurrentFnName << "\n"; 2084b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola break; 2094b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola case Function::WeakLinkage: 2104b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola case Function::LinkOnceLinkage: 2115be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (Subtarget->isTargetDarwin()) { 212a8e2989ece6dc46df59b0768184028257f913843Evan Cheng SwitchToTextSection( 213a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F); 214a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.globl\t" << CurrentFnName << "\n"; 215a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.weak_definition\t" << CurrentFnName << "\n"; 216a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else { 217a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << TAI->getWeakRefDirective() << CurrentFnName << "\n"; 218a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 2194b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola break; 2204b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola } 221a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 2220a1817392d3ad7ec2681e6bf495f490c443ec0b7Lauro Ramos Venancio const char *VisibilityDirective = NULL; 223616cc663daf965695809213d8cf8e3686e5309c3Evan Cheng if (F->hasHiddenVisibility()) 2240a1817392d3ad7ec2681e6bf495f490c443ec0b7Lauro Ramos Venancio VisibilityDirective = TAI->getHiddenDirective(); 2250a1817392d3ad7ec2681e6bf495f490c443ec0b7Lauro Ramos Venancio else if (F->hasProtectedVisibility()) 2260a1817392d3ad7ec2681e6bf495f490c443ec0b7Lauro Ramos Venancio VisibilityDirective = TAI->getProtectedDirective(); 2270a1817392d3ad7ec2681e6bf495f490c443ec0b7Lauro Ramos Venancio 2280a1817392d3ad7ec2681e6bf495f490c443ec0b7Lauro Ramos Venancio if (VisibilityDirective) 2290a1817392d3ad7ec2681e6bf495f490c443ec0b7Lauro Ramos Venancio O << VisibilityDirective << CurrentFnName << "\n"; 230616cc663daf965695809213d8cf8e3686e5309c3Evan Cheng 231a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (AFI->isThumbFunction()) { 2323a4205367dc845d4cd804b47e061f8281777c9daChris Lattner EmitAlignment(1, F, AFI->getAlign()); 233a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.code\t16\n"; 2346f46e59d2a0e66f3646db9677258876960477f87Lauro Ramos Venancio O << "\t.thumb_func"; 2356f46e59d2a0e66f3646db9677258876960477f87Lauro Ramos Venancio if (Subtarget->isTargetDarwin()) 2366f46e59d2a0e66f3646db9677258876960477f87Lauro Ramos Venancio O << "\t" << CurrentFnName; 2376f46e59d2a0e66f3646db9677258876960477f87Lauro Ramos Venancio O << "\n"; 238a8e2989ece6dc46df59b0768184028257f913843Evan Cheng InCPMode = false; 239a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else 240a8e2989ece6dc46df59b0768184028257f913843Evan Cheng EmitAlignment(2, F); 241a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 2424b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola O << CurrentFnName << ":\n"; 243e8e5495474d67cd5151bd88e502be3f46ace7a85Lauro Ramos Venancio // Emit pre-function debug information. 244e8e5495474d67cd5151bd88e502be3f46ace7a85Lauro Ramos Venancio DW.BeginFunction(&MF); 2454b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola 246200e90c74bff0b533c87e2d781815fa61af7b4d6Bill Wendling if (Subtarget->isTargetDarwin()) { 247200e90c74bff0b533c87e2d781815fa61af7b4d6Bill Wendling // If the function is empty, then we need to emit *something*. Otherwise, 248200e90c74bff0b533c87e2d781815fa61af7b4d6Bill Wendling // the function's label might be associated with something that it wasn't 249200e90c74bff0b533c87e2d781815fa61af7b4d6Bill Wendling // meant to be associated with. We emit a noop in this situation. 250200e90c74bff0b533c87e2d781815fa61af7b4d6Bill Wendling MachineFunction::iterator I = MF.begin(); 251200e90c74bff0b533c87e2d781815fa61af7b4d6Bill Wendling 252200e90c74bff0b533c87e2d781815fa61af7b4d6Bill Wendling if (++I == MF.end() && MF.front().empty()) 253200e90c74bff0b533c87e2d781815fa61af7b4d6Bill Wendling O << "\tnop\n"; 254200e90c74bff0b533c87e2d781815fa61af7b4d6Bill Wendling } 255200e90c74bff0b533c87e2d781815fa61af7b4d6Bill Wendling 2564b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola // Print out code for the function. 2574b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 2584b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola I != E; ++I) { 2594b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola // Print a label for the basic block. 2604b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola if (I != MF.begin()) { 261fb8075d03f5c87bd57dcc9c5f2304f6b13c55aadEvan Cheng printBasicBlockLabel(I, true, true); 2624b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola O << '\n'; 2634b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola } 2644b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 2654b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola II != E; ++II) { 2664b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola // Print the assembly for the instruction. 267a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printMachineInstruction(II); 2683ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola } 2697cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola } 2707cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola 271a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (TAI->hasDotTypeDotSizeDirective()) 272a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n"; 2736e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola 274e8e5495474d67cd5151bd88e502be3f46ace7a85Lauro Ramos Venancio // Emit post-function debug information. 275e8e5495474d67cd5151bd88e502be3f46ace7a85Lauro Ramos Venancio DW.EndFunction(); 27632bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola 277a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return false; 27832bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola} 27932bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola 280a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum, 281a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier) { 282a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO = MI->getOperand(opNum); 2832f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola switch (MO.getType()) { 2842f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_Register: 2856f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman if (TargetRegisterInfo::isPhysicalRegister(MO.getReg())) 28674ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling O << TM.getRegisterInfo()->get(MO.getReg()).AsmName; 2872f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola else 2882f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola assert(0 && "not implemented"); 2892f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 290a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_Immediate: { 291a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!Modifier || strcmp(Modifier, "no_hash") != 0) 292a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "#"; 293a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 2949a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner O << (int)MO.getImm(); 2952f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 296a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 2972f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_MachineBasicBlock: 2988aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner printBasicBlockLabel(MO.getMBB()); 2992f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola return; 30084b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola case MachineOperand::MO_GlobalAddress: { 301a8e2989ece6dc46df59b0768184028257f913843Evan Cheng bool isCallOp = Modifier && !strcmp(Modifier, "call"); 30284b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola GlobalValue *GV = MO.getGlobal(); 30384b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola std::string Name = Mang->getValueName(GV); 3045cbf985dcbc89fba3208e7baf8b6f488b06d3ec9Reid Spencer bool isExt = (GV->isDeclaration() || GV->hasWeakLinkage() || 305a8e2989ece6dc46df59b0768184028257f913843Evan Cheng GV->hasLinkOnceLinkage()); 3065be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (isExt && isCallOp && Subtarget->isTargetDarwin() && 307a8e2989ece6dc46df59b0768184028257f913843Evan Cheng TM.getRelocationModel() != Reloc::Static) { 308c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen printSuffixedName(Name, "$stub"); 309a8e2989ece6dc46df59b0768184028257f913843Evan Cheng FnStubs.insert(Name); 310a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else 311a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << Name; 312388488d604a63fc25d5f6b2c598f7cc4499c9db5Chris Lattner 313388488d604a63fc25d5f6b2c598f7cc4499c9db5Chris Lattner if (MO.getOffset() > 0) 314388488d604a63fc25d5f6b2c598f7cc4499c9db5Chris Lattner O << '+' << MO.getOffset(); 315388488d604a63fc25d5f6b2c598f7cc4499c9db5Chris Lattner else if (MO.getOffset() < 0) 316388488d604a63fc25d5f6b2c598f7cc4499c9db5Chris Lattner O << MO.getOffset(); 317388488d604a63fc25d5f6b2c598f7cc4499c9db5Chris Lattner 3180ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio if (isCallOp && Subtarget->isTargetELF() && 3190ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio TM.getRelocationModel() == Reloc::PIC_) 3200ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio O << "(PLT)"; 321a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (GV->hasExternalWeakLinkage()) 32215404d060ba8b604c03b9223a0f2e2abcd0fddedRafael Espindola ExtWeakSymbols.insert(GV); 3232f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 324a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 325a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_ExternalSymbol: { 326a8e2989ece6dc46df59b0768184028257f913843Evan Cheng bool isCallOp = Modifier && !strcmp(Modifier, "call"); 327a8e2989ece6dc46df59b0768184028257f913843Evan Cheng std::string Name(TAI->getGlobalPrefix()); 328a8e2989ece6dc46df59b0768184028257f913843Evan Cheng Name += MO.getSymbolName(); 3295be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (isCallOp && Subtarget->isTargetDarwin() && 330a8e2989ece6dc46df59b0768184028257f913843Evan Cheng TM.getRelocationModel() != Reloc::Static) { 331c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen printSuffixedName(Name, "$stub"); 332a8e2989ece6dc46df59b0768184028257f913843Evan Cheng FnStubs.insert(Name); 333a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else 334a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << Name; 3350ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio if (isCallOp && Subtarget->isTargetELF() && 3360ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio TM.getRelocationModel() == Reloc::PIC_) 3370ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio O << "(PLT)"; 3382f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 339a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 3402f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_ConstantPoolIndex: 341347d39f1fd8ad825a7ec5b8a3dce816723a56d42Evan Cheng O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() 3428aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner << '_' << MO.getIndex(); 3432f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 344a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_JumpTableIndex: 345347d39f1fd8ad825a7ec5b8a3dce816723a56d42Evan Cheng O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() 3468aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner << '_' << MO.getIndex(); 347a8e2989ece6dc46df59b0768184028257f913843Evan Cheng break; 3482f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola default: 3492f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola O << "<unknown operand type>"; abort (); break; 3502f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola } 3517bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 3527bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 353c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Chengstatic void printSOImm(std::ostream &O, int64_t V, const TargetAsmInfo *TAI) { 354c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng assert(V < (1 << 12) && "Not a valid so_imm value!"); 355c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng unsigned Imm = ARM_AM::getSOImmValImm(V); 356c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng unsigned Rot = ARM_AM::getSOImmValRot(V); 357a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 358a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Print low-level immediate formation info, per 359a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // A5.1.3: "Data-processing operands - Immediate". 360a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (Rot) { 361a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "#" << Imm << ", " << Rot; 362a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Pretty printed version. 363a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ' ' << TAI->getCommentString() << ' ' << (int)ARM_AM::rotr32(Imm, Rot); 364a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else { 365a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "#" << Imm; 366a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 367a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 368a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 369c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit 370c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// immediate in bits 0-7. 371c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Chengvoid ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) { 372c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng const MachineOperand &MO = MI->getOperand(OpNum); 373c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng assert(MO.isImmediate() && "Not a valid so_imm value!"); 3749a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner printSOImm(O, MO.getImm(), TAI); 375c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng} 376c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng 377c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// printSOImm2PartOperand - SOImm is broken into two pieces using a mov 378c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// followed by a or to materialize. 379c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Chengvoid ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum) { 380c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng const MachineOperand &MO = MI->getOperand(OpNum); 381c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng assert(MO.isImmediate() && "Not a valid so_imm value!"); 3829a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImm()); 3839a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImm()); 384c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng printSOImm(O, ARM_AM::getSOImmVal(V1), TAI); 3855e148a37d3432f83ccc4dbebe08d4f1b4717034cEvan Cheng O << "\n\torr"; 3865e148a37d3432f83ccc4dbebe08d4f1b4717034cEvan Cheng printPredicateOperand(MI, 2); 3875e148a37d3432f83ccc4dbebe08d4f1b4717034cEvan Cheng O << " "; 388c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng printOperand(MI, 0); 389c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng O << ", "; 390c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng printOperand(MI, 0); 391c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng O << ", "; 392c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng printSOImm(O, ARM_AM::getSOImmVal(V2), TAI); 393c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng} 394c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng 395a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// so_reg is a 4-operand unit corresponding to register forms of the A5.1 396a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// "Addressing Mode 1 - Data-processing operands" forms. This includes: 397a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// REG 0 0 - e.g. R5 398a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// REG REG 0,SH_OPC - e.g. R5, ROR R3 399a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// REG 0 IMM,SH_OPC - e.g. R5, LSL #3 400a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op) { 401a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 402a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO2 = MI->getOperand(Op+1); 403a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO3 = MI->getOperand(Op+2); 404a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 4056f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg())); 40674ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling O << TM.getRegisterInfo()->get(MO1.getReg()).AsmName; 407a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 408a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Print the shift opc. 409a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ", " 4109a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm())) 411a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << " "; 412a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 413a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (MO2.getReg()) { 4146f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman assert(TargetRegisterInfo::isPhysicalRegister(MO2.getReg())); 41574ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling O << TM.getRegisterInfo()->get(MO2.getReg()).AsmName; 416a8e2989ece6dc46df59b0768184028257f913843Evan Cheng assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0); 417a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else { 418a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "#" << ARM_AM::getSORegOffset(MO3.getImm()); 419a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 420a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 421a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 422a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op) { 423a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 424a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO2 = MI->getOperand(Op+1); 425a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO3 = MI->getOperand(Op+2); 426a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 427a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!MO1.isRegister()) { // FIXME: This is for CP entries, but isn't right. 428a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printOperand(MI, Op); 429a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return; 430a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 431a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 43274ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName; 433a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 434a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!MO2.getReg()) { 435a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0. 436a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ", #" 437a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << (char)ARM_AM::getAM2Op(MO3.getImm()) 438a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << ARM_AM::getAM2Offset(MO3.getImm()); 439a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "]"; 440a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return; 441a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 442a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 443a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ", " 444a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << (char)ARM_AM::getAM2Op(MO3.getImm()) 44574ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling << TM.getRegisterInfo()->get(MO2.getReg()).AsmName; 446a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 447a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) 448a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ", " 4499a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm())) 450a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << " #" << ShImm; 451a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "]"; 452a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 453a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 454a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op){ 455a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 456a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO2 = MI->getOperand(Op+1); 457a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 458a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!MO1.getReg()) { 459bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm()); 460bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng assert(ImmOffs && "Malformed indexed load / store!"); 461bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng O << "#" 462bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng << (char)ARM_AM::getAM2Op(MO2.getImm()) 463bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng << ImmOffs; 464a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return; 465a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 466a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 467a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << (char)ARM_AM::getAM2Op(MO2.getImm()) 46874ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling << TM.getRegisterInfo()->get(MO1.getReg()).AsmName; 469a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 470a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm())) 471a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ", " 4729a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm())) 473a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << " #" << ShImm; 474a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 475a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 476a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op) { 477a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 478a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO2 = MI->getOperand(Op+1); 479a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO3 = MI->getOperand(Op+2); 480a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 4816f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg())); 48274ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName; 483a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 484a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (MO2.getReg()) { 485a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ", " 486a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << (char)ARM_AM::getAM3Op(MO3.getImm()) 48774ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling << TM.getRegisterInfo()->get(MO2.getReg()).AsmName 488a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << "]"; 489a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return; 490a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 491a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 492a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm())) 493a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ", #" 494a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << (char)ARM_AM::getAM3Op(MO3.getImm()) 495a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << ImmOffs; 496a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "]"; 497a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 498a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 499a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op){ 500a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 501a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO2 = MI->getOperand(Op+1); 502a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 503a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (MO1.getReg()) { 504a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << (char)ARM_AM::getAM3Op(MO2.getImm()) 50574ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling << TM.getRegisterInfo()->get(MO1.getReg()).AsmName; 506a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return; 507a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 508a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 509a8e2989ece6dc46df59b0768184028257f913843Evan Cheng unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm()); 510bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng assert(ImmOffs && "Malformed indexed load / store!"); 511a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "#" 512bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng << (char)ARM_AM::getAM3Op(MO2.getImm()) 513a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << ImmOffs; 514a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 515a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 516a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op, 517a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier) { 518a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 519a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO2 = MI->getOperand(Op+1); 520a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm()); 521a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (Modifier && strcmp(Modifier, "submode") == 0) { 522a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (MO1.getReg() == ARM::SP) { 523a8e2989ece6dc46df59b0768184028257f913843Evan Cheng bool isLDM = (MI->getOpcode() == ARM::LDM || 524a8e2989ece6dc46df59b0768184028257f913843Evan Cheng MI->getOpcode() == ARM::LDM_RET); 525a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ARM_AM::getAMSubModeAltStr(Mode, isLDM); 526a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else 527a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ARM_AM::getAMSubModeStr(Mode); 528a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else { 529a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printOperand(MI, Op); 530a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ARM_AM::getAM4WBFlag(MO2.getImm())) 531a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "!"; 532a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 533a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 534a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 535a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op, 536a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier) { 537a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 538a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO2 = MI->getOperand(Op+1); 539a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 540a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!MO1.isRegister()) { // FIXME: This is for CP entries, but isn't right. 541a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printOperand(MI, Op); 542a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return; 543a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 544a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 5456f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg())); 546a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 547a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (Modifier && strcmp(Modifier, "submode") == 0) { 548a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ARM_AM::AMSubMode Mode = ARM_AM::getAM5SubMode(MO2.getImm()); 549a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (MO1.getReg() == ARM::SP) { 550a8e2989ece6dc46df59b0768184028257f913843Evan Cheng bool isFLDM = (MI->getOpcode() == ARM::FLDMD || 551a8e2989ece6dc46df59b0768184028257f913843Evan Cheng MI->getOpcode() == ARM::FLDMS); 552a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ARM_AM::getAMSubModeAltStr(Mode, isFLDM); 553a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else 554a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ARM_AM::getAMSubModeStr(Mode); 555a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return; 556a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else if (Modifier && strcmp(Modifier, "base") == 0) { 557a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Used for FSTM{D|S} and LSTM{D|S} operations. 55874ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling O << TM.getRegisterInfo()->get(MO1.getReg()).AsmName; 559a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ARM_AM::getAM5WBFlag(MO2.getImm())) 560a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "!"; 561a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return; 562a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 563a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 56474ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName; 565a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 566a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) { 567a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ", #" 568a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << (char)ARM_AM::getAM5Op(MO2.getImm()) 569a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << ImmOffs*4; 570a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 571a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "]"; 572a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 573a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 574a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op, 575a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier) { 576a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (Modifier && strcmp(Modifier, "label") == 0) { 577a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printPCLabel(MI, Op+1); 578a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return; 579a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 580a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 581a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 5826f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg())); 58374ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling O << "[pc, +" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName << "]"; 584a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 585a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 586a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid 587a8e2989ece6dc46df59b0768184028257f913843Evan ChengARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op) { 588a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 589a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO2 = MI->getOperand(Op+1); 59074ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName; 59174ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling O << ", " << TM.getRegisterInfo()->get(MO2.getReg()).AsmName << "]"; 592a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 593a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 594a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid 595a8e2989ece6dc46df59b0768184028257f913843Evan ChengARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op, 596a8e2989ece6dc46df59b0768184028257f913843Evan Cheng unsigned Scale) { 597a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 598cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng const MachineOperand &MO2 = MI->getOperand(Op+1); 599cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng const MachineOperand &MO3 = MI->getOperand(Op+2); 600a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 601a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!MO1.isRegister()) { // FIXME: This is for CP entries, but isn't right. 602a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printOperand(MI, Op); 603a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return; 604a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 605a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 60674ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName; 607cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng if (MO3.getReg()) 60874ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling O << ", " << TM.getRegisterInfo()->get(MO3.getReg()).AsmName; 609cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng else if (unsigned ImmOffs = MO2.getImm()) { 610a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ", #" << ImmOffs; 611a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (Scale > 1) 612a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << " * " << Scale; 613a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 614a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "]"; 615a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 616a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 617a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid 618c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan ChengARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op) { 619cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng printThumbAddrModeRI5Operand(MI, Op, 1); 620a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 621a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid 622c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan ChengARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op) { 623cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng printThumbAddrModeRI5Operand(MI, Op, 2); 624a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 625a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid 626c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan ChengARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op) { 627cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng printThumbAddrModeRI5Operand(MI, Op, 4); 628a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 629a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 630a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op) { 631a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 632a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO2 = MI->getOperand(Op+1); 63374ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName; 634a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (unsigned ImmOffs = MO2.getImm()) 635a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ", #" << ImmOffs << " * 4"; 636a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "]"; 6377bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 6387bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 63942d712b3067ec14170f80d8adfc7e5ad5878132bEvan Chengvoid ARMAsmPrinter::printPredicateOperand(const MachineInstr *MI, int opNum) { 6409a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(opNum).getImm(); 64144bec52b1b7e9a3ac1efbae90db240b8c1ca2ad4Evan Cheng if (CC != ARMCC::AL) 64244bec52b1b7e9a3ac1efbae90db240b8c1ca2ad4Evan Cheng O << ARMCondCodeToString(CC); 6437bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 6447bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 645dfb2ebac29f92a533218bd576734913a89d1299dEvan Chengvoid ARMAsmPrinter::printSBitModifierOperand(const MachineInstr *MI, int opNum){ 646dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng unsigned Reg = MI->getOperand(opNum).getReg(); 647dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng if (Reg) { 648dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng assert(Reg == ARM::CPSR && "Expect ARM CPSR register!"); 649dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng O << 's'; 650dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng } 651dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng} 652dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng 653a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int opNum) { 6549a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner int Id = (int)MI->getOperand(opNum).getImm(); 655a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << TAI->getPrivateGlobalPrefix() << "PC" << Id; 656a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 657a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 658a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int opNum) { 659a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "{"; 660a8e2989ece6dc46df59b0768184028257f913843Evan Cheng for (unsigned i = opNum, e = MI->getNumOperands(); i != e; ++i) { 661a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printOperand(MI, i); 662a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (i != e-1) O << ", "; 663a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 664a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "}"; 665a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 666a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 667a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNo, 668a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier) { 669a8e2989ece6dc46df59b0768184028257f913843Evan Cheng assert(Modifier && "This operand only works with a modifier!"); 670a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the 671a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // data itself. 672a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!strcmp(Modifier, "label")) { 673a8e2989ece6dc46df59b0768184028257f913843Evan Cheng unsigned ID = MI->getOperand(OpNo).getImm(); 674347d39f1fd8ad825a7ec5b8a3dce816723a56d42Evan Cheng O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() 675347d39f1fd8ad825a7ec5b8a3dce816723a56d42Evan Cheng << '_' << ID << ":\n"; 676a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else { 677a8e2989ece6dc46df59b0768184028257f913843Evan Cheng assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE"); 6788aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner unsigned CPI = MI->getOperand(OpNo).getIndex(); 679a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 680a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineConstantPoolEntry &MCPE = // Chasing pointers is fun? 681a8e2989ece6dc46df59b0768184028257f913843Evan Cheng MI->getParent()->getParent()->getConstantPool()->getConstants()[CPI]; 682a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 683a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (MCPE.isMachineConstantPoolEntry()) 684a8e2989ece6dc46df59b0768184028257f913843Evan Cheng EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); 685305b8a5f62c9d027f3d8a870fc12fc2abf69aeeaLauro Ramos Venancio else { 686a8e2989ece6dc46df59b0768184028257f913843Evan Cheng EmitGlobalConstant(MCPE.Val.ConstVal); 687305b8a5f62c9d027f3d8a870fc12fc2abf69aeeaLauro Ramos Venancio // remember to emit the weak reference 688305b8a5f62c9d027f3d8a870fc12fc2abf69aeeaLauro Ramos Venancio if (const GlobalValue *GV = dyn_cast<GlobalValue>(MCPE.Val.ConstVal)) 689305b8a5f62c9d027f3d8a870fc12fc2abf69aeeaLauro Ramos Venancio if (GV->hasExternalWeakLinkage()) 690305b8a5f62c9d027f3d8a870fc12fc2abf69aeeaLauro Ramos Venancio ExtWeakSymbols.insert(GV); 691305b8a5f62c9d027f3d8a870fc12fc2abf69aeeaLauro Ramos Venancio } 692a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 693a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 694a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 695a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNo) { 696a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(OpNo); 697a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO2 = MI->getOperand(OpNo+1); // Unique Id 6988aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner unsigned JTI = MO1.getIndex(); 699347d39f1fd8ad825a7ec5b8a3dce816723a56d42Evan Cheng O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() 7009a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner << '_' << JTI << '_' << MO2.getImm() << ":\n"; 701a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 702a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *JTEntryDirective = TAI->getJumpTableDirective(); 703a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!JTEntryDirective) 704a8e2989ece6dc46df59b0768184028257f913843Evan Cheng JTEntryDirective = TAI->getData32bitsDirective(); 705a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 706a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineFunction *MF = MI->getParent()->getParent(); 7074542611bb9793e8376d7d5f33b4a1e2d11712894Dan Gohman const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 708a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 709a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 710a8e2989ece6dc46df59b0768184028257f913843Evan Cheng bool UseSet= TAI->getSetDirective() && TM.getRelocationModel() == Reloc::PIC_; 711a8e2989ece6dc46df59b0768184028257f913843Evan Cheng std::set<MachineBasicBlock*> JTSets; 712a8e2989ece6dc46df59b0768184028257f913843Evan Cheng for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 713a8e2989ece6dc46df59b0768184028257f913843Evan Cheng MachineBasicBlock *MBB = JTBBs[i]; 714a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (UseSet && JTSets.insert(MBB).second) 7159a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner printPICJumpTableSetLabel(JTI, MO2.getImm(), MBB); 716a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 717a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << JTEntryDirective << ' '; 718a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (UseSet) 719347d39f1fd8ad825a7ec5b8a3dce816723a56d42Evan Cheng O << TAI->getPrivateGlobalPrefix() << getFunctionNumber() 7209a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner << '_' << JTI << '_' << MO2.getImm() 721347d39f1fd8ad825a7ec5b8a3dce816723a56d42Evan Cheng << "_set_" << MBB->getNumber(); 722a8e2989ece6dc46df59b0768184028257f913843Evan Cheng else if (TM.getRelocationModel() == Reloc::PIC_) { 723fb8075d03f5c87bd57dcc9c5f2304f6b13c55aadEvan Cheng printBasicBlockLabel(MBB, false, false, false); 724a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // If the arch uses custom Jump Table directives, don't calc relative to JT 725a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!TAI->getJumpTableDirective()) 726a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" 7279a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner << getFunctionNumber() << '_' << JTI << '_' << MO2.getImm(); 728a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else 729fb8075d03f5c87bd57dcc9c5f2304f6b13c55aadEvan Cheng printBasicBlockLabel(MBB, false, false, false); 730d85ac4d07966a56b3101598f29393f4532acc50fEvan Cheng if (i != e-1) 731d85ac4d07966a56b3101598f29393f4532acc50fEvan Cheng O << '\n'; 732a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 733a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 734a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 735a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 736a8e2989ece6dc46df59b0768184028257f913843Evan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 737a8e2989ece6dc46df59b0768184028257f913843Evan Cheng unsigned AsmVariant, const char *ExtraCode){ 738a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Does this asm operand have a single letter operand modifier? 739a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ExtraCode && ExtraCode[0]) { 740a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ExtraCode[1] != 0) return true; // Unknown modifier. 741a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 742a8e2989ece6dc46df59b0768184028257f913843Evan Cheng switch (ExtraCode[0]) { 743a8e2989ece6dc46df59b0768184028257f913843Evan Cheng default: return true; // Unknown modifier. 74423a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng case 'c': // Don't print "$" before a global var name or constant. 745e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng case 'P': // Print a VFP double precision register. 74623a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng printOperand(MI, OpNo); 74723a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng return false; 748a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case 'Q': 749a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (TM.getTargetData()->isLittleEndian()) 750a8e2989ece6dc46df59b0768184028257f913843Evan Cheng break; 751a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Fallthrough 752a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case 'R': 753a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (TM.getTargetData()->isBigEndian()) 754a8e2989ece6dc46df59b0768184028257f913843Evan Cheng break; 755a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Fallthrough 756a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case 'H': // Write second word of DI / DF reference. 757a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Verify that this operand has two consecutive registers. 758a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!MI->getOperand(OpNo).isRegister() || 759a8e2989ece6dc46df59b0768184028257f913843Evan Cheng OpNo+1 == MI->getNumOperands() || 760a8e2989ece6dc46df59b0768184028257f913843Evan Cheng !MI->getOperand(OpNo+1).isRegister()) 761a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return true; 762a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ++OpNo; // Return the high-part. 763a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 764a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 765a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 766a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printOperand(MI, OpNo); 767a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return false; 768a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 769a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 770a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printMachineInstruction(const MachineInstr *MI) { 771a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ++EmittedInsts; 772a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 773c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng int Opc = MI->getOpcode(); 774c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng switch (Opc) { 775c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng case ARM::CONSTPOOL_ENTRY: 776a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!InCPMode && AFI->isThumbFunction()) { 777a8e2989ece6dc46df59b0768184028257f913843Evan Cheng EmitAlignment(2); 778a8e2989ece6dc46df59b0768184028257f913843Evan Cheng InCPMode = true; 779a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 780c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng break; 781c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng default: { 7823bf12d0460cc6dcd5ad9375be9a2b05535b002a6Evan Cheng if (InCPMode && AFI->isThumbFunction()) 783a8e2989ece6dc46df59b0768184028257f913843Evan Cheng InCPMode = false; 784c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng switch (Opc) { 785c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng case ARM::PICADD: 786c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng case ARM::PICLD: 787341dcccb4e1f190f4aee12e92c2b7c2cb68c520dEvan Cheng case ARM::PICLDZH: 788341dcccb4e1f190f4aee12e92c2b7c2cb68c520dEvan Cheng case ARM::PICLDZB: 789341dcccb4e1f190f4aee12e92c2b7c2cb68c520dEvan Cheng case ARM::PICLDH: 790341dcccb4e1f190f4aee12e92c2b7c2cb68c520dEvan Cheng case ARM::PICLDB: 791341dcccb4e1f190f4aee12e92c2b7c2cb68c520dEvan Cheng case ARM::PICLDSH: 792341dcccb4e1f190f4aee12e92c2b7c2cb68c520dEvan Cheng case ARM::PICLDSB: 793341dcccb4e1f190f4aee12e92c2b7c2cb68c520dEvan Cheng case ARM::PICSTR: 794341dcccb4e1f190f4aee12e92c2b7c2cb68c520dEvan Cheng case ARM::PICSTRH: 795341dcccb4e1f190f4aee12e92c2b7c2cb68c520dEvan Cheng case ARM::PICSTRB: 796c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng case ARM::tPICADD: 797c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng break; 798c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng default: 799c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng break; 800c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng } 801c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng }} 802a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 803a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Call the autogenerated instruction printer routines. 804a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printInstruction(MI); 805a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 806a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 8077bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::doInitialization(Module &M) { 808e8e5495474d67cd5151bd88e502be3f46ace7a85Lauro Ramos Venancio // Emit initial debug information. 809e8e5495474d67cd5151bd88e502be3f46ace7a85Lauro Ramos Venancio DW.BeginModule(&M); 810a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 811b8275a3f6f6497889653cb2452d82a46f92b4926Dan Gohman bool Result = AsmPrinter::doInitialization(M); 8125411835165429dc409012adc5efaf92c4938563fDale Johannesen 813f2452c5f48e13cf3a9e620d22d5040a90133ddcaDale Johannesen // AsmPrinter::doInitialization should have done this analysis. 814f2452c5f48e13cf3a9e620d22d5040a90133ddcaDale Johannesen MMI = getAnalysisToUpdate<MachineModuleInfo>(); 815f2452c5f48e13cf3a9e620d22d5040a90133ddcaDale Johannesen assert(MMI); 816f2452c5f48e13cf3a9e620d22d5040a90133ddcaDale Johannesen DW.SetModuleInfo(MMI); 817f2452c5f48e13cf3a9e620d22d5040a90133ddcaDale Johannesen 8185411835165429dc409012adc5efaf92c4938563fDale Johannesen // Darwin wants symbols to be quoted if they have complex names. 8195411835165429dc409012adc5efaf92c4938563fDale Johannesen if (Subtarget->isTargetDarwin()) 8205411835165429dc409012adc5efaf92c4938563fDale Johannesen Mang->setUseQuotes(true); 8215411835165429dc409012adc5efaf92c4938563fDale Johannesen 822b8275a3f6f6497889653cb2452d82a46f92b4926Dan Gohman return Result; 8237bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 8247bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 825ec321b4d64ee02a1b90021c09d9513618787c6e8Chris Lattner/// PrintUnmangledNameSafely - Print out the printable characters in the name. 826ec321b4d64ee02a1b90021c09d9513618787c6e8Chris Lattner/// Don't print things like \n or \0. 827ec321b4d64ee02a1b90021c09d9513618787c6e8Chris Lattnerstatic void PrintUnmangledNameSafely(const Value *V, std::ostream &OS) { 828ec321b4d64ee02a1b90021c09d9513618787c6e8Chris Lattner for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen(); 829ec321b4d64ee02a1b90021c09d9513618787c6e8Chris Lattner Name != E; ++Name) 830ec321b4d64ee02a1b90021c09d9513618787c6e8Chris Lattner if (isprint(*Name)) 831ec321b4d64ee02a1b90021c09d9513618787c6e8Chris Lattner OS << *Name; 832ec321b4d64ee02a1b90021c09d9513618787c6e8Chris Lattner} 833ec321b4d64ee02a1b90021c09d9513618787c6e8Chris Lattner 8340f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikovvoid ARMAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { 835b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola const TargetData *TD = TM.getTargetData(); 836b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola 8370f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov if (!GVar->hasInitializer()) // External global require no code 8380f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov return; 8390f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov 8400f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov // Check to see if this is a special global used by LLVM, if so, emit it. 8410f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov 8420f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov if (EmitSpecialLLVMGlobal(GVar)) { 8430f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov if (Subtarget->isTargetDarwin() && 8440f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov TM.getRelocationModel() == Reloc::Static) { 8450f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov if (GVar->getName() == "llvm.global_ctors") 8460f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov O << ".reference .constructors_used\n"; 8470f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov else if (GVar->getName() == "llvm.global_dtors") 8480f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov O << ".reference .destructors_used\n"; 849b267ca17d1351b28d597e7807b5ed398e92d65e4Evan Cheng } 8500f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov return; 8510f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov } 8520f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov 8530f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov std::string SectionName = TAI->SectionForGlobal(GVar); 8540f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov std::string name = Mang->getValueName(GVar); 8550f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov Constant *C = GVar->getInitializer(); 8560f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov const Type *Type = C->getType(); 8570f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov unsigned Size = TD->getABITypeSize(Type); 8580f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov unsigned Align = TD->getPreferredAlignmentLog(GVar); 859b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola 8600f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov const char *VisibilityDirective = NULL; 8610f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov if (GVar->hasHiddenVisibility()) 8620f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov VisibilityDirective = TAI->getHiddenDirective(); 8630f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov else if (GVar->hasProtectedVisibility()) 8640f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov VisibilityDirective = TAI->getProtectedDirective(); 865b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola 8660f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov if (VisibilityDirective) 8670f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov O << VisibilityDirective << name << "\n"; 8680a1817392d3ad7ec2681e6bf495f490c443ec0b7Lauro Ramos Venancio 8690f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov if (Subtarget->isTargetELF()) 8700f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov O << "\t.type " << name << ",%object\n"; 8710a1817392d3ad7ec2681e6bf495f490c443ec0b7Lauro Ramos Venancio 8720f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov SwitchToDataSection(SectionName.c_str()); 8735be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng 8740f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov if (C->isNullValue() && !GVar->hasSection() && !GVar->isThreadLocal()) { 8750f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov // FIXME: This seems to be pretty darwin-specific 8760f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov 8770f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov if (GVar->hasExternalLinkage()) { 8780f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov if (const char *Directive = TAI->getZeroFillDirective()) { 8790f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov O << "\t.globl\t" << name << "\n"; 8800f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov O << Directive << "__DATA, __common, " << name << ", " 8810f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov << Size << ", " << Align << "\n"; 8820f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov return; 883a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 8845be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng } 8851366626e08322aaecd60704d02a5d881b0826725Rafael Espindola 8860f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov if (GVar->hasInternalLinkage() || GVar->isWeakForLinker()) { 8870f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. 8880f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov 8890f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov if (TAI->getLCOMMDirective() != NULL) { 8900f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov if (GVar->hasInternalLinkage()) { 8910f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov O << TAI->getLCOMMDirective() << name << "," << Size; 8920f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov if (Subtarget->isTargetDarwin()) 8930f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov O << "," << Align; 8940f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov } else 8950f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov O << TAI->getCOMMDirective() << name << "," << Size; 8965be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng } else { 8970f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov if (GVar->hasInternalLinkage()) 8980f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov O << "\t.local\t" << name << "\n"; 8990f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov O << TAI->getCOMMDirective() << name << "," << Size; 9000f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov if (TAI->getCOMMDirectiveTakesAlignment()) 9010f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align); 9025be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng } 9030f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov O << "\t\t" << TAI->getCommentString() << " "; 9040f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov PrintUnmangledNameSafely(GVar, O); 9050f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov O << "\n"; 9060f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov return; 9075be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng } 9080f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov } 9090f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov 9100f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov switch (GVar->getLinkage()) { 9110f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov case GlobalValue::LinkOnceLinkage: 9120f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov case GlobalValue::WeakLinkage: 9130f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov if (Subtarget->isTargetDarwin()) { 9140f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov O << "\t.globl " << name << "\n" 9150f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov << "\t.weak_definition " << name << "\n"; 9160f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov } else { 9170f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov O << "\t.weak " << name << "\n"; 918a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 9190f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov break; 9200f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov case GlobalValue::AppendingLinkage: 9210f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov // FIXME: appending linkage variables should go into a section of 9220f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov // their name or something. For now, just emit them as external. 9230f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov case GlobalValue::ExternalLinkage: 9240f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov O << "\t.globl " << name << "\n"; 9250f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov // FALL THROUGH 9260f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov case GlobalValue::InternalLinkage: 9270f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov break; 9280f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov default: 9290f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov assert(0 && "Unknown linkage type!"); 9300f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov break; 9310f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov } 932b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola 9330f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov EmitAlignment(Align, GVar); 9340f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov O << name << ":\t\t\t\t" << TAI->getCommentString() << " "; 9350f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov PrintUnmangledNameSafely(GVar, O); 9360f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov O << "\n"; 9370f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov if (TAI->hasDotTypeDotSizeDirective()) 9380f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov O << "\t.size " << name << ", " << Size << "\n"; 9390f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov 9400f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov // If the initializer is a extern weak symbol, remember to emit the weak 9410f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov // reference! 9420f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov if (const GlobalValue *GV = dyn_cast<GlobalValue>(C)) 9430f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov if (GV->hasExternalWeakLinkage()) 944a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ExtWeakSymbols.insert(GV); 945a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 9460f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov EmitGlobalConstant(C); 9470f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov O << '\n'; 9480f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov} 9490f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov 9500f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov 9510f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikovbool ARMAsmPrinter::doFinalization(Module &M) { 9520f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 9530f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov I != E; ++I) 9540f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov printModuleLevelGV(I); 955a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 9565be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (Subtarget->isTargetDarwin()) { 9575be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng SwitchToDataSection(""); 9585be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng 959a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Output stubs for dynamically-linked functions 960a8e2989ece6dc46df59b0768184028257f913843Evan Cheng unsigned j = 1; 961a8e2989ece6dc46df59b0768184028257f913843Evan Cheng for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end(); 962a8e2989ece6dc46df59b0768184028257f913843Evan Cheng i != e; ++i, ++j) { 963a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (TM.getRelocationModel() == Reloc::PIC_) 964a8e2989ece6dc46df59b0768184028257f913843Evan Cheng SwitchToTextSection(".section __TEXT,__picsymbolstub4,symbol_stubs," 965a8e2989ece6dc46df59b0768184028257f913843Evan Cheng "none,16", 0); 966a8e2989ece6dc46df59b0768184028257f913843Evan Cheng else 967a8e2989ece6dc46df59b0768184028257f913843Evan Cheng SwitchToTextSection(".section __TEXT,__symbol_stub4,symbol_stubs," 968a8e2989ece6dc46df59b0768184028257f913843Evan Cheng "none,12", 0); 969a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 970a8e2989ece6dc46df59b0768184028257f913843Evan Cheng EmitAlignment(2); 971a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.code\t32\n"; 972a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 973c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen std::string p = *i; 974c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen printSuffixedName(p, "$stub"); 975c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen O << ":\n"; 976a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.indirect_symbol " << *i << "\n"; 977c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen O << "\tldr ip, "; 978c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen printSuffixedName(p, "$slp"); 979c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen O << "\n"; 980a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (TM.getRelocationModel() == Reloc::PIC_) { 981c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen printSuffixedName(p, "$scv"); 982c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen O << ":\n"; 983a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\tadd ip, pc, ip\n"; 984a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 985a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\tldr pc, [ip, #0]\n"; 986c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen printSuffixedName(p, "$slp"); 987c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen O << ":\n"; 988c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen O << "\t.long\t"; 989c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen printSuffixedName(p, "$lazy_ptr"); 990c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen if (TM.getRelocationModel() == Reloc::PIC_) { 991c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen O << "-("; 992c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen printSuffixedName(p, "$scv"); 993c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen O << "+8)\n"; 994c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen } else 995c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen O << "\n"; 996a8e2989ece6dc46df59b0768184028257f913843Evan Cheng SwitchToDataSection(".lazy_symbol_pointer", 0); 997c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen printSuffixedName(p, "$lazy_ptr"); 998c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen O << ":\n"; 999a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.indirect_symbol " << *i << "\n"; 1000a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.long\tdyld_stub_binding_helper\n"; 1001a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 1002a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\n"; 1003a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 1004a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Output non-lazy-pointers for external and common global variables. 1005cb406c25973b4e88a6c10ad839ef1beeb3664715Dan Gohman if (!GVNonLazyPtrs.empty()) 1006a8e2989ece6dc46df59b0768184028257f913843Evan Cheng SwitchToDataSection(".non_lazy_symbol_pointer", 0); 1007a8e2989ece6dc46df59b0768184028257f913843Evan Cheng for (std::set<std::string>::iterator i = GVNonLazyPtrs.begin(), 1008a8e2989ece6dc46df59b0768184028257f913843Evan Cheng e = GVNonLazyPtrs.end(); i != e; ++i) { 1009c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen std::string p = *i; 1010c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen printSuffixedName(p, "$non_lazy_ptr"); 1011c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen O << ":\n"; 1012a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.indirect_symbol " << *i << "\n"; 1013a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.long\t0\n"; 1014a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 1015a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 1016a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Emit initial debug information. 1017a8e2989ece6dc46df59b0768184028257f913843Evan Cheng DW.EndModule(); 1018a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 1019a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Funny Darwin hack: This flag tells the linker that no global symbols 1020a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // contain code that falls through to other global symbols (e.g. the obvious 1021a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // implementation of multiple entry points). If this doesn't occur, the 1022a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // linker can safely perform dead code stripping. Since LLVM never 1023a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // generates code that does this, it is always safe to set. 1024a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.subsections_via_symbols\n"; 1025e8e5495474d67cd5151bd88e502be3f46ace7a85Lauro Ramos Venancio } else { 1026e8e5495474d67cd5151bd88e502be3f46ace7a85Lauro Ramos Venancio // Emit final debug information for ELF. 1027e8e5495474d67cd5151bd88e502be3f46ace7a85Lauro Ramos Venancio DW.EndModule(); 1028b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola } 1029b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola 1030b8275a3f6f6497889653cb2452d82a46f92b4926Dan Gohman return AsmPrinter::doFinalization(M); 10317bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 1032