ARMAsmPrinter.cpp revision 0ae4a3357a556261f25b1584a2d9914637c69e65
17bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===-- ARMAsmPrinter.cpp - ARM LLVM assembly writer ----------------------===// 27bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// 37bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// The LLVM Compiler Infrastructure 47bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// 57bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// This file was developed by the "Instituto Nokia de Tecnologia" and 67bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// is distributed under the University of Illinois Open Source 77bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// License. See LICENSE.TXT for details. 87bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// 97bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===----------------------------------------------------------------------===// 107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// 117bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// This file contains a printer that converts from our internal representation 127bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// of machine-dependent LLVM code to GAS-format ARM assembly language. 137bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// 147bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===----------------------------------------------------------------------===// 157bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1695b2c7da5e83670881270c1cd231a240be0556d9Chris Lattner#define DEBUG_TYPE "asm-printer" 177bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARM.h" 18a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMTargetMachine.h" 19a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMAddressingModes.h" 20a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMConstantPoolValue.h" 21a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMMachineFunctionInfo.h" 227bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Constants.h" 237bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Module.h" 247bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/AsmPrinter.h" 25a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/DwarfWriter.h" 2644c3b9fdd416c79f4b67cde1aecfced5921efd81Jim Laskey#include "llvm/CodeGen/MachineModuleInfo.h" 277bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFunctionPass.h" 28a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h" 29563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey#include "llvm/Target/TargetAsmInfo.h" 30b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola#include "llvm/Target/TargetData.h" 317bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Target/TargetMachine.h" 325be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng#include "llvm/Target/TargetOptions.h" 337bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/ADT/Statistic.h" 347bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/ADT/StringExtras.h" 35a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/Support/Compiler.h" 36a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/Support/Mangler.h" 377bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Support/MathExtras.h" 387bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <cctype> 397bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm; 407bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 4195b2c7da5e83670881270c1cd231a240be0556d9Chris LattnerSTATISTIC(EmittedInsts, "Number of machine instrs printed"); 427bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 4395b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace { 44563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey struct VISIBILITY_HIDDEN ARMAsmPrinter : public AsmPrinter { 45a0f3d17daac73c9c71aad497b298cbe82848f726Jim Laskey ARMAsmPrinter(std::ostream &O, TargetMachine &TM, const TargetAsmInfo *T) 46a8e2989ece6dc46df59b0768184028257f913843Evan Cheng : AsmPrinter(O, TM, T), DW(O, this, T), AFI(NULL), InCPMode(false) { 47a8e2989ece6dc46df59b0768184028257f913843Evan Cheng Subtarget = &TM.getSubtarget<ARMSubtarget>(); 48563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey } 497bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 50a8e2989ece6dc46df59b0768184028257f913843Evan Cheng DwarfWriter DW; 51a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 52a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can 53a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// make the right decision when printing asm code for different targets. 54a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const ARMSubtarget *Subtarget; 55a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 56a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// AFI - Keep a pointer to ARMFunctionInfo for the current 57a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// MachineFunction 58a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ARMFunctionInfo *AFI; 59a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 607bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola /// We name each basic block in a Function with a unique number, so 617bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola /// that we can consistently refer to them later. This is cleared 627bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola /// at the beginning of each call to runOnMachineFunction(). 637bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola /// 647bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola typedef std::map<const Value *, unsigned> ValueMapTy; 657bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola ValueMapTy NumberForBB; 667bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 67a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// Keeps the set of GlobalValues that require non-lazy-pointers for 68a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// indirect access. 69a8e2989ece6dc46df59b0768184028257f913843Evan Cheng std::set<std::string> GVNonLazyPtrs; 70a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 71a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// Keeps the set of external function GlobalAddresses that the asm 72a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// printer should generate stubs for. 73a8e2989ece6dc46df59b0768184028257f913843Evan Cheng std::set<std::string> FnStubs; 74a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 75a8e2989ece6dc46df59b0768184028257f913843Evan Cheng /// True if asm printer is printing a series of CONSTPOOL_ENTRY. 76a8e2989ece6dc46df59b0768184028257f913843Evan Cheng bool InCPMode; 77a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 787bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola virtual const char *getPassName() const { 797bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola return "ARM Assembly Printer"; 807bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola } 817bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 82a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printOperand(const MachineInstr *MI, int opNum, 83a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier = 0); 84a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printSOImmOperand(const MachineInstr *MI, int opNum); 85c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng void printSOImm2PartOperand(const MachineInstr *MI, int opNum); 86a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printSORegOperand(const MachineInstr *MI, int opNum); 87a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printAddrMode2Operand(const MachineInstr *MI, int OpNo); 88a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printAddrMode2OffsetOperand(const MachineInstr *MI, int OpNo); 89a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printAddrMode3Operand(const MachineInstr *MI, int OpNo); 90a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printAddrMode3OffsetOperand(const MachineInstr *MI, int OpNo); 91a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printAddrMode4Operand(const MachineInstr *MI, int OpNo, 92a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier = 0); 93a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printAddrMode5Operand(const MachineInstr *MI, int OpNo, 94a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier = 0); 95a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printAddrModePCOperand(const MachineInstr *MI, int OpNo, 96a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier = 0); 97a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printThumbAddrModeRROperand(const MachineInstr *MI, int OpNo); 98a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printThumbAddrModeRI5Operand(const MachineInstr *MI, int OpNo, 99a8e2989ece6dc46df59b0768184028257f913843Evan Cheng unsigned Scale); 100c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan Cheng void printThumbAddrModeS1Operand(const MachineInstr *MI, int OpNo); 101c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan Cheng void printThumbAddrModeS2Operand(const MachineInstr *MI, int OpNo); 102c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan Cheng void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNo); 103a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNo); 1047bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola void printCCOperand(const MachineInstr *MI, int opNum); 105a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printPCLabel(const MachineInstr *MI, int opNum); 106a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printRegisterList(const MachineInstr *MI, int opNum); 107a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printCPInstOperand(const MachineInstr *MI, int opNum, 108a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier); 109a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printJTBlockOperand(const MachineInstr *MI, int opNum); 110a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 111a8e2989ece6dc46df59b0768184028257f913843Evan Cheng virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 112a8e2989ece6dc46df59b0768184028257f913843Evan Cheng unsigned AsmVariant, const char *ExtraCode); 1137bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1147bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola bool printInstruction(const MachineInstr *MI); // autogenerated. 115a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void printMachineInstruction(const MachineInstr *MI); 1167bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola bool runOnMachineFunction(MachineFunction &F); 1177bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola bool doInitialization(Module &M); 1187bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola bool doFinalization(Module &M); 119a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 120a8e2989ece6dc46df59b0768184028257f913843Evan Cheng virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 121a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printDataDirective(MCPV->getType()); 122a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 123a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ARMConstantPoolValue *ACPV = (ARMConstantPoolValue*)MCPV; 1241a92d941b3541f0c361caad499d0eb37a8339453Lauro Ramos Venancio GlobalValue *GV = ACPV->getGV(); 125c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix(); 126c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng if (!GV) 127c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng Name += ACPV->getSymbol(); 128a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ACPV->isNonLazyPointer()) { 129a8e2989ece6dc46df59b0768184028257f913843Evan Cheng GVNonLazyPtrs.insert(Name); 130a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << TAI->getPrivateGlobalPrefix() << Name << "$non_lazy_ptr"; 131c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng } else if (ACPV->isStub()) { 132c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng FnStubs.insert(Name); 133c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng O << TAI->getPrivateGlobalPrefix() << Name << "$stub"; 134a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else 135a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << Name; 1360ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")"; 137a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ACPV->getPCAdjustment() != 0) 138a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "-(" << TAI->getPrivateGlobalPrefix() << "PC" 139a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << utostr(ACPV->getLabelId()) 140a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << "+" << (unsigned)ACPV->getPCAdjustment() << ")"; 141a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\n"; 1421a92d941b3541f0c361caad499d0eb37a8339453Lauro Ramos Venancio 1431a92d941b3541f0c361caad499d0eb37a8339453Lauro Ramos Venancio // If the constant pool value is a extern weak symbol, remember to emit 1441a92d941b3541f0c361caad499d0eb37a8339453Lauro Ramos Venancio // the weak reference. 145c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng if (GV && GV->hasExternalWeakLinkage()) 1461a92d941b3541f0c361caad499d0eb37a8339453Lauro Ramos Venancio ExtWeakSymbols.insert(GV); 147a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 148a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 149a8e2989ece6dc46df59b0768184028257f913843Evan Cheng void getAnalysisUsage(AnalysisUsage &AU) const { 150a8e2989ece6dc46df59b0768184028257f913843Evan Cheng AU.setPreservesAll(); 15144c3b9fdd416c79f4b67cde1aecfced5921efd81Jim Laskey AU.addRequired<MachineModuleInfo>(); 152a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 1537bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola }; 1547bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace 1557bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1567bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARMGenAsmWriter.inc" 1577bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1587bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// createARMCodePrinterPass - Returns a pass that prints the ARM 1597bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// assembly code for a MachineFunction to the given output stream, 1607bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// using the given target machine description. This should work 1617bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// regardless of whether the function is in SSA form. 1627bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// 1637bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaFunctionPass *llvm::createARMCodePrinterPass(std::ostream &o, 164a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ARMTargetMachine &tm) { 165a0f3d17daac73c9c71aad497b298cbe82848f726Jim Laskey return new ARMAsmPrinter(o, tm, tm.getTargetAsmInfo()); 1667bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 1677bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 168a8e2989ece6dc46df59b0768184028257f913843Evan Cheng/// runOnMachineFunction - This uses the printInstruction() 1697bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction. 1707bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// 1717bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 172a8e2989ece6dc46df59b0768184028257f913843Evan Cheng AFI = MF.getInfo<ARMFunctionInfo>(); 173a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 1745be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (Subtarget->isTargetDarwin()) { 17544c3b9fdd416c79f4b67cde1aecfced5921efd81Jim Laskey DW.SetModuleInfo(&getAnalysis<MachineModuleInfo>()); 1761a199de81322a844faee0ea242f68fe326bbd885Chris Lattner } 1771a199de81322a844faee0ea242f68fe326bbd885Chris Lattner 178a8e2989ece6dc46df59b0768184028257f913843Evan Cheng SetupMachineFunction(MF); 179a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\n"; 180a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 181a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // NOTE: we don't print out constant pools here, they are handled as 182a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // instructions. 1834b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola 184a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\n"; 1854b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola // Print out labels for the function. 1864b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola const Function *F = MF.getFunction(); 1874b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola switch (F->getLinkage()) { 1884b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola default: assert(0 && "Unknown linkage type!"); 1894b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola case Function::InternalLinkage: 190a8e2989ece6dc46df59b0768184028257f913843Evan Cheng SwitchToTextSection("\t.text", F); 1914b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola break; 1924b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola case Function::ExternalLinkage: 193a8e2989ece6dc46df59b0768184028257f913843Evan Cheng SwitchToTextSection("\t.text", F); 1944b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola O << "\t.globl\t" << CurrentFnName << "\n"; 1954b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola break; 1964b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola case Function::WeakLinkage: 1974b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola case Function::LinkOnceLinkage: 1985be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (Subtarget->isTargetDarwin()) { 199a8e2989ece6dc46df59b0768184028257f913843Evan Cheng SwitchToTextSection( 200a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F); 201a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.globl\t" << CurrentFnName << "\n"; 202a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.weak_definition\t" << CurrentFnName << "\n"; 203a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else { 204a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << TAI->getWeakRefDirective() << CurrentFnName << "\n"; 205a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 2064b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola break; 2074b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola } 208a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 209616cc663daf965695809213d8cf8e3686e5309c3Evan Cheng if (F->hasHiddenVisibility()) 210616cc663daf965695809213d8cf8e3686e5309c3Evan Cheng if (const char *Directive = TAI->getHiddenDirective()) 211616cc663daf965695809213d8cf8e3686e5309c3Evan Cheng O << Directive << CurrentFnName << "\n"; 212616cc663daf965695809213d8cf8e3686e5309c3Evan Cheng 213a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (AFI->isThumbFunction()) { 214a8e2989ece6dc46df59b0768184028257f913843Evan Cheng EmitAlignment(1, F); 215a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.code\t16\n"; 2166f46e59d2a0e66f3646db9677258876960477f87Lauro Ramos Venancio O << "\t.thumb_func"; 2176f46e59d2a0e66f3646db9677258876960477f87Lauro Ramos Venancio if (Subtarget->isTargetDarwin()) 2186f46e59d2a0e66f3646db9677258876960477f87Lauro Ramos Venancio O << "\t" << CurrentFnName; 2196f46e59d2a0e66f3646db9677258876960477f87Lauro Ramos Venancio O << "\n"; 220a8e2989ece6dc46df59b0768184028257f913843Evan Cheng InCPMode = false; 221a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else 222a8e2989ece6dc46df59b0768184028257f913843Evan Cheng EmitAlignment(2, F); 223a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 2244b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola O << CurrentFnName << ":\n"; 2255be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (Subtarget->isTargetDarwin()) { 226a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Emit pre-function debug information. 227a8e2989ece6dc46df59b0768184028257f913843Evan Cheng DW.BeginFunction(&MF); 228a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 2294b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola 2304b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola // Print out code for the function. 2314b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 2324b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola I != E; ++I) { 2334b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola // Print a label for the basic block. 2344b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola if (I != MF.begin()) { 2354b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola printBasicBlockLabel(I, true); 2364b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola O << '\n'; 2374b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola } 2384b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 2394b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola II != E; ++II) { 2404b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola // Print the assembly for the instruction. 241a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printMachineInstruction(II); 2423ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola } 2437cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola } 2447cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola 245a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (TAI->hasDotTypeDotSizeDirective()) 246a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n"; 2476e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola 2485be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (Subtarget->isTargetDarwin()) { 249a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Emit post-function debug information. 250a8e2989ece6dc46df59b0768184028257f913843Evan Cheng DW.EndFunction(); 2516e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola } 25232bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola 253a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return false; 25432bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola} 25532bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola 256a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum, 257a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier) { 258a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO = MI->getOperand(opNum); 2592f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola switch (MO.getType()) { 2602f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_Register: 2612f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola if (MRegisterInfo::isPhysicalRegister(MO.getReg())) 262a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << TM.getRegisterInfo()->get(MO.getReg()).Name; 2632f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola else 2642f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola assert(0 && "not implemented"); 2652f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 266a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_Immediate: { 267a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!Modifier || strcmp(Modifier, "no_hash") != 0) 268a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "#"; 269a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 270a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << (int)MO.getImmedValue(); 2712f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 272a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 2732f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_MachineBasicBlock: 274687bc49d1ada3fe0a2cd3fb5c044f12d267f259fRafael Espindola printBasicBlockLabel(MO.getMachineBasicBlock()); 2752f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola return; 27684b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola case MachineOperand::MO_GlobalAddress: { 277a8e2989ece6dc46df59b0768184028257f913843Evan Cheng bool isCallOp = Modifier && !strcmp(Modifier, "call"); 27884b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola GlobalValue *GV = MO.getGlobal(); 27984b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola std::string Name = Mang->getValueName(GV); 2805cbf985dcbc89fba3208e7baf8b6f488b06d3ec9Reid Spencer bool isExt = (GV->isDeclaration() || GV->hasWeakLinkage() || 281a8e2989ece6dc46df59b0768184028257f913843Evan Cheng GV->hasLinkOnceLinkage()); 2825be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (isExt && isCallOp && Subtarget->isTargetDarwin() && 283a8e2989ece6dc46df59b0768184028257f913843Evan Cheng TM.getRelocationModel() != Reloc::Static) { 284a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << TAI->getPrivateGlobalPrefix() << Name << "$stub"; 285a8e2989ece6dc46df59b0768184028257f913843Evan Cheng FnStubs.insert(Name); 286a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else 287a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << Name; 2880ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio if (isCallOp && Subtarget->isTargetELF() && 2890ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio TM.getRelocationModel() == Reloc::PIC_) 2900ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio O << "(PLT)"; 291a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (GV->hasExternalWeakLinkage()) 29215404d060ba8b604c03b9223a0f2e2abcd0fddedRafael Espindola ExtWeakSymbols.insert(GV); 2932f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 294a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 295a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_ExternalSymbol: { 296a8e2989ece6dc46df59b0768184028257f913843Evan Cheng bool isCallOp = Modifier && !strcmp(Modifier, "call"); 297a8e2989ece6dc46df59b0768184028257f913843Evan Cheng std::string Name(TAI->getGlobalPrefix()); 298a8e2989ece6dc46df59b0768184028257f913843Evan Cheng Name += MO.getSymbolName(); 2995be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (isCallOp && Subtarget->isTargetDarwin() && 300a8e2989ece6dc46df59b0768184028257f913843Evan Cheng TM.getRelocationModel() != Reloc::Static) { 301a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << TAI->getPrivateGlobalPrefix() << Name << "$stub"; 302a8e2989ece6dc46df59b0768184028257f913843Evan Cheng FnStubs.insert(Name); 303a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else 304a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << Name; 3050ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio if (isCallOp && Subtarget->isTargetELF() && 3060ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio TM.getRelocationModel() == Reloc::PIC_) 3070ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio O << "(PLT)"; 3082f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 309a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 3102f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_ConstantPoolIndex: 311563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() 31206c1e7eacb11edd1671eabfc11291b7716be2608Rafael Espindola << '_' << MO.getConstantPoolIndex(); 3132f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 314a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case MachineOperand::MO_JumpTableIndex: 315a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() 316a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << '_' << MO.getJumpTableIndex(); 317a8e2989ece6dc46df59b0768184028257f913843Evan Cheng break; 3182f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola default: 3192f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola O << "<unknown operand type>"; abort (); break; 3202f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola } 3217bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 3227bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 323c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Chengstatic void printSOImm(std::ostream &O, int64_t V, const TargetAsmInfo *TAI) { 324c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng assert(V < (1 << 12) && "Not a valid so_imm value!"); 325c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng unsigned Imm = ARM_AM::getSOImmValImm(V); 326c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng unsigned Rot = ARM_AM::getSOImmValRot(V); 327a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 328a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Print low-level immediate formation info, per 329a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // A5.1.3: "Data-processing operands - Immediate". 330a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (Rot) { 331a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "#" << Imm << ", " << Rot; 332a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Pretty printed version. 333a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ' ' << TAI->getCommentString() << ' ' << (int)ARM_AM::rotr32(Imm, Rot); 334a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else { 335a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "#" << Imm; 336a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 337a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 338a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 339c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit 340c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// immediate in bits 0-7. 341c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Chengvoid ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) { 342c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng const MachineOperand &MO = MI->getOperand(OpNum); 343c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng assert(MO.isImmediate() && "Not a valid so_imm value!"); 344c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng printSOImm(O, MO.getImmedValue(), TAI); 345c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng} 346c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng 347c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// printSOImm2PartOperand - SOImm is broken into two pieces using a mov 348c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// followed by a or to materialize. 349c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Chengvoid ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum) { 350c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng const MachineOperand &MO = MI->getOperand(OpNum); 351c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng assert(MO.isImmediate() && "Not a valid so_imm value!"); 352c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImmedValue()); 353c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImmedValue()); 354c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng printSOImm(O, ARM_AM::getSOImmVal(V1), TAI); 355c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng O << "\n\torr "; 356c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng printOperand(MI, 0); 357c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng O << ", "; 358c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng printOperand(MI, 0); 359c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng O << ", "; 360c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng printSOImm(O, ARM_AM::getSOImmVal(V2), TAI); 361c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng} 362c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng 363a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// so_reg is a 4-operand unit corresponding to register forms of the A5.1 364a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// "Addressing Mode 1 - Data-processing operands" forms. This includes: 365a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// REG 0 0 - e.g. R5 366a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// REG REG 0,SH_OPC - e.g. R5, ROR R3 367a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// REG 0 IMM,SH_OPC - e.g. R5, LSL #3 368a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op) { 369a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 370a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO2 = MI->getOperand(Op+1); 371a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO3 = MI->getOperand(Op+2); 372a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 373a8e2989ece6dc46df59b0768184028257f913843Evan Cheng assert(MRegisterInfo::isPhysicalRegister(MO1.getReg())); 374a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << TM.getRegisterInfo()->get(MO1.getReg()).Name; 375a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 376a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Print the shift opc. 377a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ", " 378a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImmedValue())) 379a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << " "; 380a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 381a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (MO2.getReg()) { 382a8e2989ece6dc46df59b0768184028257f913843Evan Cheng assert(MRegisterInfo::isPhysicalRegister(MO2.getReg())); 383a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << TM.getRegisterInfo()->get(MO2.getReg()).Name; 384a8e2989ece6dc46df59b0768184028257f913843Evan Cheng assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0); 385a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else { 386a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "#" << ARM_AM::getSORegOffset(MO3.getImm()); 387a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 388a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 389a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 390a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op) { 391a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 392a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO2 = MI->getOperand(Op+1); 393a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO3 = MI->getOperand(Op+2); 394a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 395a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!MO1.isRegister()) { // FIXME: This is for CP entries, but isn't right. 396a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printOperand(MI, Op); 397a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return; 398a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 399a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 400a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name; 401a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 402a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!MO2.getReg()) { 403a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0. 404a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ", #" 405a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << (char)ARM_AM::getAM2Op(MO3.getImm()) 406a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << ARM_AM::getAM2Offset(MO3.getImm()); 407a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "]"; 408a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return; 409a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 410a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 411a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ", " 412a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << (char)ARM_AM::getAM2Op(MO3.getImm()) 413a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << TM.getRegisterInfo()->get(MO2.getReg()).Name; 414a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 415a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) 416a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ", " 417a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImmedValue())) 418a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << " #" << ShImm; 419a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "]"; 420a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 421a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 422a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op){ 423a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 424a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO2 = MI->getOperand(Op+1); 425a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 426a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!MO1.getReg()) { 427a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ARM_AM::getAM2Offset(MO2.getImm())) // Don't print +0. 428a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "#" 429a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << (char)ARM_AM::getAM2Op(MO2.getImm()) 430a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << ARM_AM::getAM2Offset(MO2.getImm()); 431a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return; 432a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 433a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 434a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << (char)ARM_AM::getAM2Op(MO2.getImm()) 435a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << TM.getRegisterInfo()->get(MO1.getReg()).Name; 436a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 437a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm())) 438a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ", " 439a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImmedValue())) 440a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << " #" << ShImm; 441a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 442a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 443a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op) { 444a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 445a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO2 = MI->getOperand(Op+1); 446a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO3 = MI->getOperand(Op+2); 447a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 448a8e2989ece6dc46df59b0768184028257f913843Evan Cheng assert(MRegisterInfo::isPhysicalRegister(MO1.getReg())); 449a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name; 450a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 451a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (MO2.getReg()) { 452a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ", " 453a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << (char)ARM_AM::getAM3Op(MO3.getImm()) 454a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << TM.getRegisterInfo()->get(MO2.getReg()).Name 455a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << "]"; 456a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return; 457a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 458a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 459a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm())) 460a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ", #" 461a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << (char)ARM_AM::getAM3Op(MO3.getImm()) 462a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << ImmOffs; 463a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "]"; 464a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 465a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 466a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op){ 467a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 468a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO2 = MI->getOperand(Op+1); 469a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 470a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (MO1.getReg()) { 471a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << (char)ARM_AM::getAM3Op(MO2.getImm()) 472a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << TM.getRegisterInfo()->get(MO1.getReg()).Name; 473a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return; 474a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 475a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 476a8e2989ece6dc46df59b0768184028257f913843Evan Cheng unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm()); 477a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "#" 478a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << (char)ARM_AM::getAM3Op(MO2.getImm()) 479a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << ImmOffs; 480a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 481a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 482a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op, 483a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier) { 484a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 485a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO2 = MI->getOperand(Op+1); 486a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm()); 487a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (Modifier && strcmp(Modifier, "submode") == 0) { 488a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (MO1.getReg() == ARM::SP) { 489a8e2989ece6dc46df59b0768184028257f913843Evan Cheng bool isLDM = (MI->getOpcode() == ARM::LDM || 490a8e2989ece6dc46df59b0768184028257f913843Evan Cheng MI->getOpcode() == ARM::LDM_RET); 491a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ARM_AM::getAMSubModeAltStr(Mode, isLDM); 492a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else 493a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ARM_AM::getAMSubModeStr(Mode); 494a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else { 495a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printOperand(MI, Op); 496a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ARM_AM::getAM4WBFlag(MO2.getImm())) 497a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "!"; 498a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 499a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 500a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 501a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op, 502a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier) { 503a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 504a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO2 = MI->getOperand(Op+1); 505a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 506a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!MO1.isRegister()) { // FIXME: This is for CP entries, but isn't right. 507a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printOperand(MI, Op); 508a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return; 509a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 510a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 511a8e2989ece6dc46df59b0768184028257f913843Evan Cheng assert(MRegisterInfo::isPhysicalRegister(MO1.getReg())); 512a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 513a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (Modifier && strcmp(Modifier, "submode") == 0) { 514a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ARM_AM::AMSubMode Mode = ARM_AM::getAM5SubMode(MO2.getImm()); 515a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (MO1.getReg() == ARM::SP) { 516a8e2989ece6dc46df59b0768184028257f913843Evan Cheng bool isFLDM = (MI->getOpcode() == ARM::FLDMD || 517a8e2989ece6dc46df59b0768184028257f913843Evan Cheng MI->getOpcode() == ARM::FLDMS); 518a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ARM_AM::getAMSubModeAltStr(Mode, isFLDM); 519a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else 520a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ARM_AM::getAMSubModeStr(Mode); 521a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return; 522a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else if (Modifier && strcmp(Modifier, "base") == 0) { 523a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Used for FSTM{D|S} and LSTM{D|S} operations. 524a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << TM.getRegisterInfo()->get(MO1.getReg()).Name; 525a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ARM_AM::getAM5WBFlag(MO2.getImm())) 526a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "!"; 527a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return; 528a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 529a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 530a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name; 531a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 532a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) { 533a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ", #" 534a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << (char)ARM_AM::getAM5Op(MO2.getImm()) 535a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << ImmOffs*4; 536a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 537a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "]"; 538a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 539a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 540a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op, 541a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier) { 542a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (Modifier && strcmp(Modifier, "label") == 0) { 543a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printPCLabel(MI, Op+1); 544a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return; 545a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 546a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 547a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 548a8e2989ece6dc46df59b0768184028257f913843Evan Cheng assert(MRegisterInfo::isPhysicalRegister(MO1.getReg())); 549a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "[pc, +" << TM.getRegisterInfo()->get(MO1.getReg()).Name << "]"; 550a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 551a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 552a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid 553a8e2989ece6dc46df59b0768184028257f913843Evan ChengARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op) { 554a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 555a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO2 = MI->getOperand(Op+1); 556a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name; 557a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ", " << TM.getRegisterInfo()->get(MO2.getReg()).Name << "]"; 558a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 559a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 560a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid 561a8e2989ece6dc46df59b0768184028257f913843Evan ChengARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op, 562a8e2989ece6dc46df59b0768184028257f913843Evan Cheng unsigned Scale) { 563a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 564cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng const MachineOperand &MO2 = MI->getOperand(Op+1); 565cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng const MachineOperand &MO3 = MI->getOperand(Op+2); 566a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 567a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!MO1.isRegister()) { // FIXME: This is for CP entries, but isn't right. 568a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printOperand(MI, Op); 569a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return; 570a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 571a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 572a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name; 573cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng if (MO3.getReg()) 574cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng O << ", " << TM.getRegisterInfo()->get(MO3.getReg()).Name; 575cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng else if (unsigned ImmOffs = MO2.getImm()) { 576a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ", #" << ImmOffs; 577a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (Scale > 1) 578a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << " * " << Scale; 579a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 580a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "]"; 581a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 582a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 583a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid 584c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan ChengARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op) { 585cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng printThumbAddrModeRI5Operand(MI, Op, 1); 586a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 587a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid 588c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan ChengARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op) { 589cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng printThumbAddrModeRI5Operand(MI, Op, 2); 590a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 591a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid 592c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan ChengARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op) { 593cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng printThumbAddrModeRI5Operand(MI, Op, 4); 594a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 595a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 596a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op) { 597a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(Op); 598a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO2 = MI->getOperand(Op+1); 599a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name; 600a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (unsigned ImmOffs = MO2.getImm()) 601a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << ", #" << ImmOffs << " * 4"; 602a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "]"; 6037bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 6047bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 6057bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) { 6066f602de3b68cc63d12554ad6ae3c98a4c436c32dRafael Espindola int CC = (int)MI->getOperand(opNum).getImmedValue(); 6076f602de3b68cc63d12554ad6ae3c98a4c436c32dRafael Espindola O << ARMCondCodeToString((ARMCC::CondCodes)CC); 6087bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 6097bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 610a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int opNum) { 611a8e2989ece6dc46df59b0768184028257f913843Evan Cheng int Id = (int)MI->getOperand(opNum).getImmedValue(); 612a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << TAI->getPrivateGlobalPrefix() << "PC" << Id; 613a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 614a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 615a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int opNum) { 616a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "{"; 617a8e2989ece6dc46df59b0768184028257f913843Evan Cheng for (unsigned i = opNum, e = MI->getNumOperands(); i != e; ++i) { 618a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printOperand(MI, i); 619a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (i != e-1) O << ", "; 620a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 621a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "}"; 622a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 623a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 624a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNo, 625a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *Modifier) { 626a8e2989ece6dc46df59b0768184028257f913843Evan Cheng assert(Modifier && "This operand only works with a modifier!"); 627a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the 628a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // data itself. 629a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!strcmp(Modifier, "label")) { 630a8e2989ece6dc46df59b0768184028257f913843Evan Cheng unsigned ID = MI->getOperand(OpNo).getImm(); 631a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() 632a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << '_' << ID << ":\n"; 633a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else { 634a8e2989ece6dc46df59b0768184028257f913843Evan Cheng assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE"); 635a8e2989ece6dc46df59b0768184028257f913843Evan Cheng unsigned CPI = MI->getOperand(OpNo).getConstantPoolIndex(); 636a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 637a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineConstantPoolEntry &MCPE = // Chasing pointers is fun? 638a8e2989ece6dc46df59b0768184028257f913843Evan Cheng MI->getParent()->getParent()->getConstantPool()->getConstants()[CPI]; 639a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 640a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (MCPE.isMachineConstantPoolEntry()) 641a8e2989ece6dc46df59b0768184028257f913843Evan Cheng EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); 642a8e2989ece6dc46df59b0768184028257f913843Evan Cheng else 643a8e2989ece6dc46df59b0768184028257f913843Evan Cheng EmitGlobalConstant(MCPE.Val.ConstVal); 644a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 645a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 646a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 647a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNo) { 648a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO1 = MI->getOperand(OpNo); 649a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineOperand &MO2 = MI->getOperand(OpNo+1); // Unique Id 650a8e2989ece6dc46df59b0768184028257f913843Evan Cheng unsigned JTI = MO1.getJumpTableIndex(); 651a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() 652a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << '_' << JTI << '_' << MO2.getImmedValue() << ":\n"; 653a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 654a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const char *JTEntryDirective = TAI->getJumpTableDirective(); 655a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!JTEntryDirective) 656a8e2989ece6dc46df59b0768184028257f913843Evan Cheng JTEntryDirective = TAI->getData32bitsDirective(); 657a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 658a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const MachineFunction *MF = MI->getParent()->getParent(); 659a8e2989ece6dc46df59b0768184028257f913843Evan Cheng MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 660a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 661a8e2989ece6dc46df59b0768184028257f913843Evan Cheng const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 662a8e2989ece6dc46df59b0768184028257f913843Evan Cheng bool UseSet= TAI->getSetDirective() && TM.getRelocationModel() == Reloc::PIC_; 663a8e2989ece6dc46df59b0768184028257f913843Evan Cheng std::set<MachineBasicBlock*> JTSets; 664a8e2989ece6dc46df59b0768184028257f913843Evan Cheng for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 665a8e2989ece6dc46df59b0768184028257f913843Evan Cheng MachineBasicBlock *MBB = JTBBs[i]; 666a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (UseSet && JTSets.insert(MBB).second) 667a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printSetLabel(JTI, MO2.getImmedValue(), MBB); 668a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 669a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << JTEntryDirective << ' '; 670a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (UseSet) 671a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << TAI->getPrivateGlobalPrefix() << getFunctionNumber() 672a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << '_' << JTI << '_' << MO2.getImmedValue() 673a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << "_set_" << MBB->getNumber(); 674a8e2989ece6dc46df59b0768184028257f913843Evan Cheng else if (TM.getRelocationModel() == Reloc::PIC_) { 675a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printBasicBlockLabel(MBB, false, false); 676a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // If the arch uses custom Jump Table directives, don't calc relative to JT 677a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!TAI->getJumpTableDirective()) 678a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" 679a8e2989ece6dc46df59b0768184028257f913843Evan Cheng << getFunctionNumber() << '_' << JTI << '_' << MO2.getImmedValue(); 680a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else 681a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printBasicBlockLabel(MBB, false, false); 682d85ac4d07966a56b3101598f29393f4532acc50fEvan Cheng if (i != e-1) 683d85ac4d07966a56b3101598f29393f4532acc50fEvan Cheng O << '\n'; 684a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 685a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 686a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 687a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 688a8e2989ece6dc46df59b0768184028257f913843Evan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 689a8e2989ece6dc46df59b0768184028257f913843Evan Cheng unsigned AsmVariant, const char *ExtraCode){ 690a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Does this asm operand have a single letter operand modifier? 691a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ExtraCode && ExtraCode[0]) { 692a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (ExtraCode[1] != 0) return true; // Unknown modifier. 693a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 694a8e2989ece6dc46df59b0768184028257f913843Evan Cheng switch (ExtraCode[0]) { 695a8e2989ece6dc46df59b0768184028257f913843Evan Cheng default: return true; // Unknown modifier. 69623a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng case 'c': // Don't print "$" before a global var name or constant. 697e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng case 'P': // Print a VFP double precision register. 69823a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng printOperand(MI, OpNo); 69923a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng return false; 700a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case 'Q': 701a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (TM.getTargetData()->isLittleEndian()) 702a8e2989ece6dc46df59b0768184028257f913843Evan Cheng break; 703a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Fallthrough 704a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case 'R': 705a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (TM.getTargetData()->isBigEndian()) 706a8e2989ece6dc46df59b0768184028257f913843Evan Cheng break; 707a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Fallthrough 708a8e2989ece6dc46df59b0768184028257f913843Evan Cheng case 'H': // Write second word of DI / DF reference. 709a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Verify that this operand has two consecutive registers. 710a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!MI->getOperand(OpNo).isRegister() || 711a8e2989ece6dc46df59b0768184028257f913843Evan Cheng OpNo+1 == MI->getNumOperands() || 712a8e2989ece6dc46df59b0768184028257f913843Evan Cheng !MI->getOperand(OpNo+1).isRegister()) 713a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return true; 714a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ++OpNo; // Return the high-part. 715a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 716a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 717a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 718a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printOperand(MI, OpNo); 719a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return false; 720a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 721a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 722a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printMachineInstruction(const MachineInstr *MI) { 723a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ++EmittedInsts; 724a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 725c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng int Opc = MI->getOpcode(); 726c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng switch (Opc) { 727c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng case ARM::CONSTPOOL_ENTRY: 728a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (!InCPMode && AFI->isThumbFunction()) { 729a8e2989ece6dc46df59b0768184028257f913843Evan Cheng EmitAlignment(2); 730a8e2989ece6dc46df59b0768184028257f913843Evan Cheng InCPMode = true; 731a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 732c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng break; 733c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng default: { 7343bf12d0460cc6dcd5ad9375be9a2b05535b002a6Evan Cheng if (InCPMode && AFI->isThumbFunction()) 735a8e2989ece6dc46df59b0768184028257f913843Evan Cheng InCPMode = false; 736c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng switch (Opc) { 737c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng case ARM::PICADD: 738c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng case ARM::PICLD: 739c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng case ARM::tPICADD: 740c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng break; 741c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng default: 742c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng O << "\t"; 743c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng break; 744c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng } 745c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng }} 746a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 747a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Call the autogenerated instruction printer routines. 748a8e2989ece6dc46df59b0768184028257f913843Evan Cheng printInstruction(MI); 749a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 750a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 7517bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::doInitialization(Module &M) { 7525be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (Subtarget->isTargetDarwin()) { 753a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Emit initial debug information. 754a8e2989ece6dc46df59b0768184028257f913843Evan Cheng DW.BeginModule(&M); 755a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 756a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 757a8e2989ece6dc46df59b0768184028257f913843Evan Cheng return AsmPrinter::doInitialization(M); 7587bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 7597bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 7607bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::doFinalization(Module &M) { 761b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola const TargetData *TD = TM.getTargetData(); 762b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola 763b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 764b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola I != E; ++I) { 765b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola if (!I->hasInitializer()) // External global require no code 766b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola continue; 767b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola 768b267ca17d1351b28d597e7807b5ed398e92d65e4Evan Cheng if (EmitSpecialLLVMGlobal(I)) { 769b267ca17d1351b28d597e7807b5ed398e92d65e4Evan Cheng if (Subtarget->isTargetDarwin() && 770b267ca17d1351b28d597e7807b5ed398e92d65e4Evan Cheng TM.getRelocationModel() == Reloc::Static) { 771b267ca17d1351b28d597e7807b5ed398e92d65e4Evan Cheng if (I->getName() == "llvm.global_ctors") 772b267ca17d1351b28d597e7807b5ed398e92d65e4Evan Cheng O << ".reference .constructors_used\n"; 773b267ca17d1351b28d597e7807b5ed398e92d65e4Evan Cheng else if (I->getName() == "llvm.global_dtors") 774b267ca17d1351b28d597e7807b5ed398e92d65e4Evan Cheng O << ".reference .destructors_used\n"; 775b267ca17d1351b28d597e7807b5ed398e92d65e4Evan Cheng } 776b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola continue; 777b267ca17d1351b28d597e7807b5ed398e92d65e4Evan Cheng } 778b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola 779b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola std::string name = Mang->getValueName(I); 780b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola Constant *C = I->getInitializer(); 78198ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng const Type *Type = C->getType(); 78298ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng unsigned Size = TD->getTypeSize(Type); 783a8e2989ece6dc46df59b0768184028257f913843Evan Cheng unsigned Align = TD->getPreferredAlignmentLog(I); 784b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola 7855be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (I->hasHiddenVisibility()) 7865be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (const char *Directive = TAI->getHiddenDirective()) 7875be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng O << Directive << name << "\n"; 7885be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (Subtarget->isTargetELF()) 789b1cc0528232a732b337a4ba2eb0ba64d7538f1efLauro Ramos Venancio O << "\t.type " << name << ",%object\n"; 7905be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng 7915be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (C->isNullValue()) { 792a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (I->hasExternalLinkage()) { 7935be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (const char *Directive = TAI->getZeroFillDirective()) { 794a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.globl\t" << name << "\n"; 7955be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng O << Directive << "__DATA__, __common, " << name << ", " 7965be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng << Size << ", " << Align << "\n"; 7975be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng continue; 7985be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng } 7995be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng } 8005be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng 8015be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (!I->hasSection() && 8025be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng (I->hasInternalLinkage() || I->hasWeakLinkage() || 8035be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng I->hasLinkOnceLinkage())) { 8045be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. 8055be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (!NoZerosInBSS && TAI->getBSSSection()) 8065be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng SwitchToDataSection(TAI->getBSSSection(), I); 8075be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng else 8085be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng SwitchToDataSection(TAI->getDataSection(), I); 809a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (TAI->getLCOMMDirective() != NULL) { 810a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (I->hasInternalLinkage()) { 811a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << TAI->getLCOMMDirective() << name << "," << Size; 8125be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (Subtarget->isTargetDarwin()) 813a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "," << Align; 814a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else 815a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << TAI->getCOMMDirective() << name << "," << Size; 816a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } else { 817a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (I->hasInternalLinkage()) 818a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.local\t" << name << "\n"; 819a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << TAI->getCOMMDirective() << name << "," << Size; 820a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (TAI->getCOMMDirectiveTakesAlignment()) 821a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align); 822a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 8235be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng O << "\t\t" << TAI->getCommentString() << " " << I->getName() << "\n"; 8245be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng continue; 825a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 8265be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng } 8271366626e08322aaecd60704d02a5d881b0826725Rafael Espindola 8285be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng switch (I->getLinkage()) { 8295be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng case GlobalValue::LinkOnceLinkage: 8305be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng case GlobalValue::WeakLinkage: 8315be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (Subtarget->isTargetDarwin()) { 8325be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng O << "\t.globl " << name << "\n" 8335be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng << "\t.weak_definition " << name << "\n"; 8345be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng SwitchToDataSection("\t.section __DATA,__const_coal,coalesced", I); 8355be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng } else { 8365be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng std::string SectionName("\t.section\t.llvm.linkonce.d." + 8375be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng name + 8385be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng ",\"aw\",%progbits"); 8395be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng SwitchToDataSection(SectionName.c_str(), I); 8405be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng O << "\t.weak " << name << "\n"; 8415be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng } 8425be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng break; 8435be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng case GlobalValue::AppendingLinkage: 8445be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng // FIXME: appending linkage variables should go into a section of 8455be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng // their name or something. For now, just emit them as external. 8465be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng case GlobalValue::ExternalLinkage: 8475be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng O << "\t.globl " << name << "\n"; 8485be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng // FALL THROUGH 8495be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng case GlobalValue::InternalLinkage: { 8505be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (I->isConstant()) { 8515be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng const ConstantArray *CVA = dyn_cast<ConstantArray>(C); 8525be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (TAI->getCStringSection() && CVA && CVA->isCString()) { 8535be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng SwitchToDataSection(TAI->getCStringSection(), I); 8545be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng break; 855a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 8561366626e08322aaecd60704d02a5d881b0826725Rafael Espindola } 8575be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng // FIXME: special handling for ".ctors" & ".dtors" sections 8585be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (I->hasSection() && 8595be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng (I->getSection() == ".ctors" || 8605be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng I->getSection() == ".dtors")) { 8615be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng assert(!Subtarget->isTargetDarwin()); 8625be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng std::string SectionName = ".section " + I->getSection(); 8635be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng SectionName += ",\"aw\",%progbits"; 8645be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng SwitchToDataSection(SectionName.c_str()); 8655be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng } else { 8665be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (C->isNullValue() && !NoZerosInBSS && TAI->getBSSSection()) 8675be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng SwitchToDataSection(TAI->getBSSSection(), I); 86898ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng else if (!I->isConstant()) 8695be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng SwitchToDataSection(TAI->getDataSection(), I); 87098ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng else { 87198ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng // Read-only data. 872032953d74746fa89b62e49b63a38ba6d8827b81aEvan Cheng bool HasReloc = C->ContainsRelocations(); 873032953d74746fa89b62e49b63a38ba6d8827b81aEvan Cheng if (HasReloc && 874032953d74746fa89b62e49b63a38ba6d8827b81aEvan Cheng Subtarget->isTargetDarwin() && 87598ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng TM.getRelocationModel() != Reloc::Static) 87698ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng SwitchToDataSection("\t.const_data\n"); 877032953d74746fa89b62e49b63a38ba6d8827b81aEvan Cheng else if (!HasReloc && Size == 4 && 87898ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng TAI->getFourByteConstantSection()) 87998ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng SwitchToDataSection(TAI->getFourByteConstantSection(), I); 880032953d74746fa89b62e49b63a38ba6d8827b81aEvan Cheng else if (!HasReloc && Size == 8 && 88198ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng TAI->getEightByteConstantSection()) 88298ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng SwitchToDataSection(TAI->getEightByteConstantSection(), I); 883032953d74746fa89b62e49b63a38ba6d8827b81aEvan Cheng else if (!HasReloc && Size == 16 && 88498ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng TAI->getSixteenByteConstantSection()) 88598ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng SwitchToDataSection(TAI->getSixteenByteConstantSection(), I); 88698ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng else if (TAI->getReadOnlySection()) 88798ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng SwitchToDataSection(TAI->getReadOnlySection(), I); 88898ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng else 88998ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng SwitchToDataSection(TAI->getDataSection(), I); 89098ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng } 8915be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng } 8925be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng 8935be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng break; 8945be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng } 8955be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng default: 8965be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng assert(0 && "Unknown linkage type!"); 8975be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng break; 898a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 899b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola 900a8e2989ece6dc46df59b0768184028257f913843Evan Cheng EmitAlignment(Align, I); 9015be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng O << name << ":\t\t\t\t" << TAI->getCommentString() << " " << I->getName() 9025be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng << "\n"; 9035be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (TAI->hasDotTypeDotSizeDirective()) 904b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola O << "\t.size " << name << ", " << Size << "\n"; 905a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // If the initializer is a extern weak symbol, remember to emit the weak 906a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // reference! 907a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (const GlobalValue *GV = dyn_cast<GlobalValue>(C)) 908a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (GV->hasExternalWeakLinkage()) 909a8e2989ece6dc46df59b0768184028257f913843Evan Cheng ExtWeakSymbols.insert(GV); 910a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 911a8e2989ece6dc46df59b0768184028257f913843Evan Cheng EmitGlobalConstant(C); 912a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << '\n'; 913a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 914a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 9155be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng if (Subtarget->isTargetDarwin()) { 9165be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng SwitchToDataSection(""); 9175be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng 918a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Output stubs for dynamically-linked functions 919a8e2989ece6dc46df59b0768184028257f913843Evan Cheng unsigned j = 1; 920a8e2989ece6dc46df59b0768184028257f913843Evan Cheng for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end(); 921a8e2989ece6dc46df59b0768184028257f913843Evan Cheng i != e; ++i, ++j) { 922a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (TM.getRelocationModel() == Reloc::PIC_) 923a8e2989ece6dc46df59b0768184028257f913843Evan Cheng SwitchToTextSection(".section __TEXT,__picsymbolstub4,symbol_stubs," 924a8e2989ece6dc46df59b0768184028257f913843Evan Cheng "none,16", 0); 925a8e2989ece6dc46df59b0768184028257f913843Evan Cheng else 926a8e2989ece6dc46df59b0768184028257f913843Evan Cheng SwitchToTextSection(".section __TEXT,__symbol_stub4,symbol_stubs," 927a8e2989ece6dc46df59b0768184028257f913843Evan Cheng "none,12", 0); 928a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 929a8e2989ece6dc46df59b0768184028257f913843Evan Cheng EmitAlignment(2); 930a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.code\t32\n"; 931a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 932a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "L" << *i << "$stub:\n"; 933a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.indirect_symbol " << *i << "\n"; 934a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\tldr ip, L" << *i << "$slp\n"; 935a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (TM.getRelocationModel() == Reloc::PIC_) { 936a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "L" << *i << "$scv:\n"; 937a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\tadd ip, pc, ip\n"; 938a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 939a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\tldr pc, [ip, #0]\n"; 940a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "L" << *i << "$slp:\n"; 941a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (TM.getRelocationModel() == Reloc::PIC_) 942a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.long\tL" << *i << "$lazy_ptr-(L" << *i << "$scv+8)\n"; 943a8e2989ece6dc46df59b0768184028257f913843Evan Cheng else 944a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.long\tL" << *i << "$lazy_ptr\n"; 945a8e2989ece6dc46df59b0768184028257f913843Evan Cheng SwitchToDataSection(".lazy_symbol_pointer", 0); 946a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "L" << *i << "$lazy_ptr:\n"; 947a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.indirect_symbol " << *i << "\n"; 948a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.long\tdyld_stub_binding_helper\n"; 949a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 950a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\n"; 951a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 952a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Output non-lazy-pointers for external and common global variables. 953a8e2989ece6dc46df59b0768184028257f913843Evan Cheng if (GVNonLazyPtrs.begin() != GVNonLazyPtrs.end()) 954a8e2989ece6dc46df59b0768184028257f913843Evan Cheng SwitchToDataSection(".non_lazy_symbol_pointer", 0); 955a8e2989ece6dc46df59b0768184028257f913843Evan Cheng for (std::set<std::string>::iterator i = GVNonLazyPtrs.begin(), 956a8e2989ece6dc46df59b0768184028257f913843Evan Cheng e = GVNonLazyPtrs.end(); i != e; ++i) { 957a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "L" << *i << "$non_lazy_ptr:\n"; 958a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.indirect_symbol " << *i << "\n"; 959a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.long\t0\n"; 960a8e2989ece6dc46df59b0768184028257f913843Evan Cheng } 961a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 962a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Emit initial debug information. 963a8e2989ece6dc46df59b0768184028257f913843Evan Cheng DW.EndModule(); 964a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 965a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Funny Darwin hack: This flag tells the linker that no global symbols 966a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // contain code that falls through to other global symbols (e.g. the obvious 967a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // implementation of multiple entry points). If this doesn't occur, the 968a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // linker can safely perform dead code stripping. Since LLVM never 969a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // generates code that does this, it is always safe to set. 970a8e2989ece6dc46df59b0768184028257f913843Evan Cheng O << "\t.subsections_via_symbols\n"; 971b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola } 972b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola 9737bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola AsmPrinter::doFinalization(M); 9747bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola return false; // success 9757bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 976