ARMAsmPrinter.cpp revision 1366626e08322aaecd60704d02a5d881b0826725
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 167bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARM.h" 177bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARMInstrInfo.h" 187bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Constants.h" 197bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/DerivedTypes.h" 207bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Module.h" 217bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/AsmPrinter.h" 227bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFunctionPass.h" 237bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineConstantPool.h" 247bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineInstr.h" 25563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey#include "llvm/Target/TargetAsmInfo.h" 26b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola#include "llvm/Target/TargetData.h" 277bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Target/TargetMachine.h" 287bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Support/Mangler.h" 297bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/ADT/Statistic.h" 307bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/ADT/StringExtras.h" 317bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Support/CommandLine.h" 327bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Support/MathExtras.h" 337bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <cctype> 347bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm; 357bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 367bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolanamespace { 37ac0b6ae358944ae8b2b5a11dc08f52c3ed89f2daChris Lattner Statistic EmittedInsts("asm-printer", "Number of machine instrs printed"); 387bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 39e931a37a4eb3e46d73ab0379dd84173dca1214f2Rafael Espindola static const char *ARMCondCodeToString(ARMCC::CondCodes CC) { 40e931a37a4eb3e46d73ab0379dd84173dca1214f2Rafael Espindola switch (CC) { 41e931a37a4eb3e46d73ab0379dd84173dca1214f2Rafael Espindola default: assert(0 && "Unknown condition code"); 42e931a37a4eb3e46d73ab0379dd84173dca1214f2Rafael Espindola case ARMCC::EQ: return "eq"; 43e931a37a4eb3e46d73ab0379dd84173dca1214f2Rafael Espindola case ARMCC::NE: return "ne"; 44e931a37a4eb3e46d73ab0379dd84173dca1214f2Rafael Espindola case ARMCC::CS: return "cs"; 45e931a37a4eb3e46d73ab0379dd84173dca1214f2Rafael Espindola case ARMCC::CC: return "cc"; 46e931a37a4eb3e46d73ab0379dd84173dca1214f2Rafael Espindola case ARMCC::MI: return "mi"; 47e931a37a4eb3e46d73ab0379dd84173dca1214f2Rafael Espindola case ARMCC::PL: return "pl"; 48e931a37a4eb3e46d73ab0379dd84173dca1214f2Rafael Espindola case ARMCC::VS: return "vs"; 49e931a37a4eb3e46d73ab0379dd84173dca1214f2Rafael Espindola case ARMCC::VC: return "vc"; 50e931a37a4eb3e46d73ab0379dd84173dca1214f2Rafael Espindola case ARMCC::HI: return "hi"; 51e931a37a4eb3e46d73ab0379dd84173dca1214f2Rafael Espindola case ARMCC::LS: return "ls"; 52e931a37a4eb3e46d73ab0379dd84173dca1214f2Rafael Espindola case ARMCC::GE: return "ge"; 53e931a37a4eb3e46d73ab0379dd84173dca1214f2Rafael Espindola case ARMCC::LT: return "lt"; 54e931a37a4eb3e46d73ab0379dd84173dca1214f2Rafael Espindola case ARMCC::GT: return "gt"; 55e931a37a4eb3e46d73ab0379dd84173dca1214f2Rafael Espindola case ARMCC::LE: return "le"; 56e931a37a4eb3e46d73ab0379dd84173dca1214f2Rafael Espindola case ARMCC::AL: return "al"; 57e931a37a4eb3e46d73ab0379dd84173dca1214f2Rafael Espindola } 58e931a37a4eb3e46d73ab0379dd84173dca1214f2Rafael Espindola } 59e931a37a4eb3e46d73ab0379dd84173dca1214f2Rafael Espindola 60563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey struct VISIBILITY_HIDDEN ARMAsmPrinter : public AsmPrinter { 61a0f3d17daac73c9c71aad497b298cbe82848f726Jim Laskey ARMAsmPrinter(std::ostream &O, TargetMachine &TM, const TargetAsmInfo *T) 62563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey : AsmPrinter(O, TM, T) { 63563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey } 647bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 65392b1b2ef3ace82b5104ba4c9280fc7957c669d4Rafael Espindola std::set<std::string> ExtWeakSymbols; 66392b1b2ef3ace82b5104ba4c9280fc7957c669d4Rafael Espindola 677bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola /// We name each basic block in a Function with a unique number, so 687bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola /// that we can consistently refer to them later. This is cleared 697bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola /// at the beginning of each call to runOnMachineFunction(). 707bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola /// 717bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola typedef std::map<const Value *, unsigned> ValueMapTy; 727bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola ValueMapTy NumberForBB; 737bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 747bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola virtual const char *getPassName() const { 757bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola return "ARM Assembly Printer"; 767bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola } 777bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 787cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola void printAddrMode1(const MachineInstr *MI, int opNum); 796e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola void printAddrMode2(const MachineInstr *MI, int opNum); 8032bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola void printAddrMode5(const MachineInstr *MI, int opNum); 817bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola void printOperand(const MachineInstr *MI, int opNum); 827bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola void printMemOperand(const MachineInstr *MI, int opNum, 837bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola const char *Modifier = 0); 847bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola void printCCOperand(const MachineInstr *MI, int opNum); 857bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 867bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola bool printInstruction(const MachineInstr *MI); // autogenerated. 877bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola bool runOnMachineFunction(MachineFunction &F); 887bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola bool doInitialization(Module &M); 897bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola bool doFinalization(Module &M); 907bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola }; 917bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace 927bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 937bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARMGenAsmWriter.inc" 947bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 957bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// createARMCodePrinterPass - Returns a pass that prints the ARM 967bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// assembly code for a MachineFunction to the given output stream, 977bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// using the given target machine description. This should work 987bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// regardless of whether the function is in SSA form. 997bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// 1007bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaFunctionPass *llvm::createARMCodePrinterPass(std::ostream &o, 1017bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola TargetMachine &tm) { 102a0f3d17daac73c9c71aad497b298cbe82848f726Jim Laskey return new ARMAsmPrinter(o, tm, tm.getTargetAsmInfo()); 1037bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 1047bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1057bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// runOnMachineFunction - This uses the printMachineInstruction() 1067bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction. 1077bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// 1087bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 1094b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola SetupMachineFunction(MF); 1104b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola O << "\n\n"; 1114b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola 1124b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola // Print out constants referenced by the function 1134b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola EmitConstantPool(MF.getConstantPool()); 1144b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola 1154b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola // Print out jump tables referenced by the function 1161da31ee472b9615d7329c656e2cc17c419ed7c95Chris Lattner EmitJumpTableInfo(MF.getJumpTableInfo(), MF); 1174b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola 1184b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola // Print out labels for the function. 1194b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola const Function *F = MF.getFunction(); 1206f6f69950f5a36d3ae7e4d1d5b96fda204beb79aChris Lattner SwitchToTextSection(getSectionForFunction(*F).c_str(), F); 1216f6f69950f5a36d3ae7e4d1d5b96fda204beb79aChris Lattner 1224b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola switch (F->getLinkage()) { 1234b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola default: assert(0 && "Unknown linkage type!"); 1244b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola case Function::InternalLinkage: 1254b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola break; 1264b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola case Function::ExternalLinkage: 1274b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola O << "\t.globl\t" << CurrentFnName << "\n"; 1284b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola break; 1294b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola case Function::WeakLinkage: 1304b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola case Function::LinkOnceLinkage: 131392b1b2ef3ace82b5104ba4c9280fc7957c669d4Rafael Espindola O << TAI->getWeakRefDirective() << CurrentFnName << "\n"; 1324b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola break; 1334b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola } 134a1334cdfb2afb44a1f2b952391e1b2fecb1d4bd8Rafael Espindola EmitAlignment(2, F); 1354b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola O << CurrentFnName << ":\n"; 1364b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola 1374b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola // Print out code for the function. 1384b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 1394b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola I != E; ++I) { 1404b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola // Print a label for the basic block. 1414b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola if (I != MF.begin()) { 1424b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola printBasicBlockLabel(I, true); 1434b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola O << '\n'; 1444b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola } 1454b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 1464b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola II != E; ++II) { 1474b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola // Print the assembly for the instruction. 1484b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola O << "\t"; 1494b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola printInstruction(II); 1504b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola } 1514b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola } 1524b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola 1537bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola return false; 1547bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 1557bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1567cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindolavoid ARMAsmPrinter::printAddrMode1(const MachineInstr *MI, int opNum) { 1573ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola const MachineOperand &Arg = MI->getOperand(opNum); 1583ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola const MachineOperand &Shift = MI->getOperand(opNum + 1); 1593ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola const MachineOperand &ShiftType = MI->getOperand(opNum + 2); 1607cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola 1613ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola if(Arg.isImmediate()) { 1623ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola assert(Shift.getImmedValue() == 0); 1637cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola printOperand(MI, opNum); 1647cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola } else { 1653ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola assert(Arg.isRegister()); 1667cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola printOperand(MI, opNum); 1673ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola if(Shift.isRegister() || Shift.getImmedValue() != 0) { 1683ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola const char *s = NULL; 1693ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola switch(ShiftType.getImmedValue()) { 1703ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola case ARMShift::LSL: 1713ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola s = ", lsl "; 1723ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola break; 1733ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola case ARMShift::LSR: 1743ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola s = ", lsr "; 1753ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola break; 1763ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola case ARMShift::ASR: 1773ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola s = ", asr "; 1783ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola break; 1793ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola case ARMShift::ROR: 1803ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola s = ", ror "; 1813ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola break; 1823ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola case ARMShift::RRX: 1833ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola s = ", rrx "; 1843ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola break; 1853ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola } 1863ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola O << s; 1873ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola printOperand(MI, opNum + 1); 1883ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola } 1897cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola } 1907cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola} 1917cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola 1926e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindolavoid ARMAsmPrinter::printAddrMode2(const MachineInstr *MI, int opNum) { 1936e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola const MachineOperand &Arg = MI->getOperand(opNum); 1946e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola const MachineOperand &Offset = MI->getOperand(opNum + 1); 1956e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola assert(Offset.isImmediate()); 1966e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola 1976e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola if (Arg.isConstantPoolIndex()) { 1986e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola assert(Offset.getImmedValue() == 0); 1996e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola printOperand(MI, opNum); 2006e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola } else { 2016e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola assert(Arg.isRegister()); 2026e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola O << '['; 2036e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola printOperand(MI, opNum); 2046e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola O << ", "; 2056e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola printOperand(MI, opNum + 1); 2066e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola O << ']'; 2076e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola } 2086e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola} 2096e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola 21032bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindolavoid ARMAsmPrinter::printAddrMode5(const MachineInstr *MI, int opNum) { 21132bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola const MachineOperand &Arg = MI->getOperand(opNum); 21232bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola const MachineOperand &Offset = MI->getOperand(opNum + 1); 21332bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola assert(Offset.isImmediate()); 21432bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola 21532bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola if (Arg.isConstantPoolIndex()) { 21632bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola assert(Offset.getImmedValue() == 0); 21732bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola printOperand(MI, opNum); 21832bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola } else { 21932bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola assert(Arg.isRegister()); 22032bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola O << '['; 22132bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola printOperand(MI, opNum); 22232bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola O << ", "; 22332bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola printOperand(MI, opNum + 1); 22432bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola O << ']'; 22532bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola } 22632bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola} 22732bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola 2287bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum) { 2292f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola const MachineOperand &MO = MI->getOperand (opNum); 2302f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola const MRegisterInfo &RI = *TM.getRegisterInfo(); 2312f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola switch (MO.getType()) { 2322f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_Register: 2332f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola if (MRegisterInfo::isPhysicalRegister(MO.getReg())) 2342f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola O << LowercaseString (RI.get(MO.getReg()).Name); 2352f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola else 2362f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola assert(0 && "not implemented"); 2372f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 2382f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_Immediate: 2392f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola O << "#" << (int)MO.getImmedValue(); 2402f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 2412f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_MachineBasicBlock: 242687bc49d1ada3fe0a2cd3fb5c044f12d267f259fRafael Espindola printBasicBlockLabel(MO.getMachineBasicBlock()); 2432f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola return; 24484b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola case MachineOperand::MO_GlobalAddress: { 24584b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola GlobalValue *GV = MO.getGlobal(); 24684b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola std::string Name = Mang->getValueName(GV); 24784b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola O << Name; 248392b1b2ef3ace82b5104ba4c9280fc7957c669d4Rafael Espindola if (GV->hasExternalWeakLinkage()) { 249392b1b2ef3ace82b5104ba4c9280fc7957c669d4Rafael Espindola ExtWeakSymbols.insert(Name); 250392b1b2ef3ace82b5104ba4c9280fc7957c669d4Rafael Espindola } 25184b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola } 2522f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 2532f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_ExternalSymbol: 2540505be03adf561afbd8307516125da10dba8f0c4Rafael Espindola O << TAI->getGlobalPrefix() << MO.getSymbolName(); 2552f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 2562f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_ConstantPoolIndex: 257563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() 25806c1e7eacb11edd1671eabfc11291b7716be2608Rafael Espindola << '_' << MO.getConstantPoolIndex(); 2592f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 2602f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola default: 2612f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola O << "<unknown operand type>"; abort (); break; 2622f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola } 2637bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 2647bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 2657bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum, 2667bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola const char *Modifier) { 2677bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola assert(0 && "not implemented"); 2687bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 2697bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 2707bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) { 2716f602de3b68cc63d12554ad6ae3c98a4c436c32dRafael Espindola int CC = (int)MI->getOperand(opNum).getImmedValue(); 2726f602de3b68cc63d12554ad6ae3c98a4c436c32dRafael Espindola O << ARMCondCodeToString((ARMCC::CondCodes)CC); 2737bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 2747bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 2757bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::doInitialization(Module &M) { 276ff59d22232f47f138ed3d753975153befd1aa0c0Rafael Espindola AsmPrinter::doInitialization(M); 2777bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola return false; // success 2787bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 2797bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 2807bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::doFinalization(Module &M) { 281b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola const TargetData *TD = TM.getTargetData(); 282b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola 283b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 284b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola I != E; ++I) { 285b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola if (!I->hasInitializer()) // External global require no code 286b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola continue; 287b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola 288b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola if (EmitSpecialLLVMGlobal(I)) 289b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola continue; 290b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola 291b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola O << "\n\n"; 292b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola std::string name = Mang->getValueName(I); 293b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola Constant *C = I->getInitializer(); 294b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola unsigned Size = TD->getTypeSize(C->getType()); 2951c411dee4f406e33d70666898f62ab9ba23bb73dRafael Espindola unsigned Align = Log2_32(TD->getTypeAlignment(C->getType())); 296b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola 297b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola if (C->isNullValue() && 2987367d05cb713d11f8ac1e0815ac6b2eb6b17088cRafael Espindola !I->hasSection() && 299b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || 300b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola I->hasWeakLinkage())) { 301b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola SwitchToDataSection(".data", I); 302b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola if (I->hasInternalLinkage()) 303b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola O << "\t.local " << name << "\n"; 304b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola 3051c411dee4f406e33d70666898f62ab9ba23bb73dRafael Espindola O << "\t.comm " << name << "," << Size 3061c411dee4f406e33d70666898f62ab9ba23bb73dRafael Espindola << "," << (unsigned)Align; 307b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola O << "\n"; 308b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola } else { 309b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola switch (I->getLinkage()) { 310b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola default: 311b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola assert(0 && "Unknown linkage type!"); 312b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola break; 313b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola case GlobalValue::ExternalLinkage: 314b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola O << "\t.globl " << name << "\n"; 315b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola break; 316b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola case GlobalValue::InternalLinkage: 317b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola break; 318b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola } 319b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola 3201366626e08322aaecd60704d02a5d881b0826725Rafael Espindola if (I->hasSection() && 3211366626e08322aaecd60704d02a5d881b0826725Rafael Espindola (I->getSection() == ".ctors" || 3221366626e08322aaecd60704d02a5d881b0826725Rafael Espindola I->getSection() == ".dtors")) { 3231366626e08322aaecd60704d02a5d881b0826725Rafael Espindola std::string SectionName = ".section " + I->getSection(); 3241366626e08322aaecd60704d02a5d881b0826725Rafael Espindola 3251366626e08322aaecd60704d02a5d881b0826725Rafael Espindola SectionName += ",\"aw\",@progbits"; 3261366626e08322aaecd60704d02a5d881b0826725Rafael Espindola 3271366626e08322aaecd60704d02a5d881b0826725Rafael Espindola SwitchToDataSection(SectionName.c_str()); 3281366626e08322aaecd60704d02a5d881b0826725Rafael Espindola } else { 3291366626e08322aaecd60704d02a5d881b0826725Rafael Espindola SwitchToDataSection(TAI->getDataSection(), I); 3301366626e08322aaecd60704d02a5d881b0826725Rafael Espindola } 331b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola 332b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola EmitAlignment(Align, I); 333b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola O << "\t.type " << name << ", %object\n"; 334b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola O << "\t.size " << name << ", " << Size << "\n"; 335b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola O << name << ":\n"; 336b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola EmitGlobalConstant(C); 337b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola } 338b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola } 339b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola 340392b1b2ef3ace82b5104ba4c9280fc7957c669d4Rafael Espindola if (ExtWeakSymbols.begin() != ExtWeakSymbols.end()) 341392b1b2ef3ace82b5104ba4c9280fc7957c669d4Rafael Espindola SwitchToDataSection(""); 342392b1b2ef3ace82b5104ba4c9280fc7957c669d4Rafael Espindola for (std::set<std::string>::iterator i = ExtWeakSymbols.begin(), 343392b1b2ef3ace82b5104ba4c9280fc7957c669d4Rafael Espindola e = ExtWeakSymbols.end(); i != e; ++i) { 344392b1b2ef3ace82b5104ba4c9280fc7957c669d4Rafael Espindola O << TAI->getWeakRefDirective() << *i << "\n"; 345392b1b2ef3ace82b5104ba4c9280fc7957c669d4Rafael Espindola } 346392b1b2ef3ace82b5104ba4c9280fc7957c669d4Rafael Espindola 3477bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola AsmPrinter::doFinalization(M); 3487bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola return false; // success 3497bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 350