ARMAsmPrinter.cpp revision 32bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56
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/Assembly/Writer.h" 227bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/AsmPrinter.h" 237bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFunctionPass.h" 247bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineConstantPool.h" 257bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineInstr.h" 26563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey#include "llvm/Target/TargetAsmInfo.h" 27b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola#include "llvm/Target/TargetData.h" 287bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Target/TargetMachine.h" 297bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Support/Mangler.h" 307bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/ADT/Statistic.h" 317bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/ADT/StringExtras.h" 327bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Support/CommandLine.h" 337bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Support/MathExtras.h" 347bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <cctype> 357bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <iostream> 367bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm; 377bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 387bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolanamespace { 397bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); 407bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 41563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey struct VISIBILITY_HIDDEN ARMAsmPrinter : public AsmPrinter { 42a0f3d17daac73c9c71aad497b298cbe82848f726Jim Laskey ARMAsmPrinter(std::ostream &O, TargetMachine &TM, const TargetAsmInfo *T) 43563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey : AsmPrinter(O, TM, T) { 44563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey } 457bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 467bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola /// We name each basic block in a Function with a unique number, so 477bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola /// that we can consistently refer to them later. This is cleared 487bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola /// at the beginning of each call to runOnMachineFunction(). 497bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola /// 507bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola typedef std::map<const Value *, unsigned> ValueMapTy; 517bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola ValueMapTy NumberForBB; 527bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 537bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola virtual const char *getPassName() const { 547bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola return "ARM Assembly Printer"; 557bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola } 567bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 577cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola void printAddrMode1(const MachineInstr *MI, int opNum); 5832bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola void printAddrMode5(const MachineInstr *MI, int opNum); 597cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola 60f3a335cedff423438789c593d58be068b124dc1eRafael Espindola void printMemRegImm(const MachineInstr *MI, int opNum, 61f3a335cedff423438789c593d58be068b124dc1eRafael Espindola const char *Modifier = NULL) { 62f3a335cedff423438789c593d58be068b124dc1eRafael Espindola const MachineOperand &MO1 = MI->getOperand(opNum); 63f3a335cedff423438789c593d58be068b124dc1eRafael Espindola const MachineOperand &MO2 = MI->getOperand(opNum + 1); 641ed3af11b55becb26a3485494409084a668a9232Rafael Espindola assert(MO1.isImmediate()); 65f3a335cedff423438789c593d58be068b124dc1eRafael Espindola bool arith = false; 66f3a335cedff423438789c593d58be068b124dc1eRafael Espindola if (Modifier != NULL) { 67f3a335cedff423438789c593d58be068b124dc1eRafael Espindola assert(strcmp(Modifier, "arith") == 0); 68f3a335cedff423438789c593d58be068b124dc1eRafael Espindola arith = true; 69f3a335cedff423438789c593d58be068b124dc1eRafael Espindola } 701ed3af11b55becb26a3485494409084a668a9232Rafael Espindola 711ed3af11b55becb26a3485494409084a668a9232Rafael Espindola if (MO2.isConstantPoolIndex()) { 72f3a335cedff423438789c593d58be068b124dc1eRafael Espindola printOperand(MI, opNum + 1); 731ed3af11b55becb26a3485494409084a668a9232Rafael Espindola } else if (MO2.isRegister()) { 74f3a335cedff423438789c593d58be068b124dc1eRafael Espindola if(!arith) 75f3a335cedff423438789c593d58be068b124dc1eRafael Espindola O << '['; 76f3a335cedff423438789c593d58be068b124dc1eRafael Espindola printOperand(MI, opNum + 1); 771ed3af11b55becb26a3485494409084a668a9232Rafael Espindola O << ", "; 78f3a335cedff423438789c593d58be068b124dc1eRafael Espindola printOperand(MI, opNum); 79f3a335cedff423438789c593d58be068b124dc1eRafael Espindola if(!arith) 80f3a335cedff423438789c593d58be068b124dc1eRafael Espindola O << ']'; 811ed3af11b55becb26a3485494409084a668a9232Rafael Espindola } else { 821ed3af11b55becb26a3485494409084a668a9232Rafael Espindola assert(0 && "Invalid Operand Type"); 831ed3af11b55becb26a3485494409084a668a9232Rafael Espindola } 84a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola } 85a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola 867bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola void printOperand(const MachineInstr *MI, int opNum); 877bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola void printMemOperand(const MachineInstr *MI, int opNum, 887bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola const char *Modifier = 0); 897bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola void printCCOperand(const MachineInstr *MI, int opNum); 907bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 917bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola bool printInstruction(const MachineInstr *MI); // autogenerated. 927bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola bool runOnMachineFunction(MachineFunction &F); 937bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola bool doInitialization(Module &M); 947bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola bool doFinalization(Module &M); 957bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola }; 967bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace 977bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 987bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARMGenAsmWriter.inc" 997bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1007bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// createARMCodePrinterPass - Returns a pass that prints the ARM 1017bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// assembly code for a MachineFunction to the given output stream, 1027bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// using the given target machine description. This should work 1037bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// regardless of whether the function is in SSA form. 1047bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// 1057bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaFunctionPass *llvm::createARMCodePrinterPass(std::ostream &o, 1067bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola TargetMachine &tm) { 107a0f3d17daac73c9c71aad497b298cbe82848f726Jim Laskey return new ARMAsmPrinter(o, tm, tm.getTargetAsmInfo()); 1087bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 1097bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// runOnMachineFunction - This uses the printMachineInstruction() 1117bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction. 1127bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// 1137bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 1144b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola SetupMachineFunction(MF); 1154b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola O << "\n\n"; 1164b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola 1174b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola // Print out constants referenced by the function 1184b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola EmitConstantPool(MF.getConstantPool()); 1194b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola 1204b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola // Print out jump tables referenced by the function 1211da31ee472b9615d7329c656e2cc17c419ed7c95Chris Lattner EmitJumpTableInfo(MF.getJumpTableInfo(), MF); 1224b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola 1234b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola // Print out labels for the function. 1244b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola const Function *F = MF.getFunction(); 1256f6f69950f5a36d3ae7e4d1d5b96fda204beb79aChris Lattner SwitchToTextSection(getSectionForFunction(*F).c_str(), F); 1266f6f69950f5a36d3ae7e4d1d5b96fda204beb79aChris Lattner 1274b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola switch (F->getLinkage()) { 1284b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola default: assert(0 && "Unknown linkage type!"); 1294b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola case Function::InternalLinkage: 1304b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola break; 1314b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola case Function::ExternalLinkage: 1324b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola O << "\t.globl\t" << CurrentFnName << "\n"; 1334b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola break; 1344b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola case Function::WeakLinkage: 1354b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola case Function::LinkOnceLinkage: 1364b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola assert(0 && "Not implemented"); 1374b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola break; 1384b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola } 139a1334cdfb2afb44a1f2b952391e1b2fecb1d4bd8Rafael Espindola EmitAlignment(2, F); 1404b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola O << CurrentFnName << ":\n"; 1414b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola 1424b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola // Print out code for the function. 1434b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 1444b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola I != E; ++I) { 1454b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola // Print a label for the basic block. 1464b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola if (I != MF.begin()) { 1474b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola printBasicBlockLabel(I, true); 1484b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola O << '\n'; 1494b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola } 1504b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 1514b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola II != E; ++II) { 1524b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola // Print the assembly for the instruction. 1534b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola O << "\t"; 1544b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola printInstruction(II); 1554b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola } 1564b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola } 1574b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola 1587bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola return false; 1597bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 1607bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 1617cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindolavoid ARMAsmPrinter::printAddrMode1(const MachineInstr *MI, int opNum) { 1623ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola const MachineOperand &Arg = MI->getOperand(opNum); 1633ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola const MachineOperand &Shift = MI->getOperand(opNum + 1); 1643ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola const MachineOperand &ShiftType = MI->getOperand(opNum + 2); 1657cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola 1663ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola if(Arg.isImmediate()) { 1673ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola assert(Shift.getImmedValue() == 0); 1687cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola printOperand(MI, opNum); 1697cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola } else { 1703ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola assert(Arg.isRegister()); 1717cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola printOperand(MI, opNum); 1723ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola if(Shift.isRegister() || Shift.getImmedValue() != 0) { 1733ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola const char *s = NULL; 1743ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola switch(ShiftType.getImmedValue()) { 1753ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola case ARMShift::LSL: 1763ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola s = ", lsl "; 1773ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola break; 1783ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola case ARMShift::LSR: 1793ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola s = ", lsr "; 1803ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola break; 1813ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola case ARMShift::ASR: 1823ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola s = ", asr "; 1833ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola break; 1843ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola case ARMShift::ROR: 1853ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola s = ", ror "; 1863ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola break; 1873ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola case ARMShift::RRX: 1883ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola s = ", rrx "; 1893ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola break; 1903ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola } 1913ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola O << s; 1923ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola printOperand(MI, opNum + 1); 1933ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola } 1947cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola } 1957cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola} 1967cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola 19732bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindolavoid ARMAsmPrinter::printAddrMode5(const MachineInstr *MI, int opNum) { 19832bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola const MachineOperand &Arg = MI->getOperand(opNum); 19932bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola const MachineOperand &Offset = MI->getOperand(opNum + 1); 20032bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola assert(Offset.isImmediate()); 20132bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola 20232bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola if (Arg.isConstantPoolIndex()) { 20332bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola assert(Offset.getImmedValue() == 0); 20432bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola printOperand(MI, opNum); 20532bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola } else { 20632bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola assert(Arg.isRegister()); 20732bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola O << '['; 20832bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola printOperand(MI, opNum); 20932bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola O << ", "; 21032bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola printOperand(MI, opNum + 1); 21132bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola O << ']'; 21232bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola } 21332bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola} 21432bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola 2157bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum) { 2162f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola const MachineOperand &MO = MI->getOperand (opNum); 2172f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola const MRegisterInfo &RI = *TM.getRegisterInfo(); 2182f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola switch (MO.getType()) { 2192f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_Register: 2202f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola if (MRegisterInfo::isPhysicalRegister(MO.getReg())) 2212f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola O << LowercaseString (RI.get(MO.getReg()).Name); 2222f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola else 2232f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola assert(0 && "not implemented"); 2242f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 2252f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_Immediate: 2262f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola O << "#" << (int)MO.getImmedValue(); 2272f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 2282f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_MachineBasicBlock: 229687bc49d1ada3fe0a2cd3fb5c044f12d267f259fRafael Espindola printBasicBlockLabel(MO.getMachineBasicBlock()); 2302f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola return; 23184b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola case MachineOperand::MO_GlobalAddress: { 23284b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola GlobalValue *GV = MO.getGlobal(); 23384b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola std::string Name = Mang->getValueName(GV); 23484b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola O << Name; 23584b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola } 2362f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 2372f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_ExternalSymbol: 2380505be03adf561afbd8307516125da10dba8f0c4Rafael Espindola O << TAI->getGlobalPrefix() << MO.getSymbolName(); 2392f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 2402f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola case MachineOperand::MO_ConstantPoolIndex: 241563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() 24206c1e7eacb11edd1671eabfc11291b7716be2608Rafael Espindola << '_' << MO.getConstantPoolIndex(); 2432f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola break; 2442f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola default: 2452f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola O << "<unknown operand type>"; abort (); break; 2462f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola } 2477bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 2487bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 2497bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum, 2507bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola const char *Modifier) { 2517bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola assert(0 && "not implemented"); 2527bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 2537bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 2547bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) { 2556f602de3b68cc63d12554ad6ae3c98a4c436c32dRafael Espindola int CC = (int)MI->getOperand(opNum).getImmedValue(); 2566f602de3b68cc63d12554ad6ae3c98a4c436c32dRafael Espindola O << ARMCondCodeToString((ARMCC::CondCodes)CC); 2577bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 2587bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 2597bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::doInitialization(Module &M) { 260ff59d22232f47f138ed3d753975153befd1aa0c0Rafael Espindola AsmPrinter::doInitialization(M); 2617bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola return false; // success 2627bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 2637bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola 2647bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::doFinalization(Module &M) { 265b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola const TargetData *TD = TM.getTargetData(); 266b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola 267b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 268b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola I != E; ++I) { 269b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola if (!I->hasInitializer()) // External global require no code 270b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola continue; 271b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola 272b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola if (EmitSpecialLLVMGlobal(I)) 273b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola continue; 274b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola 275b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola O << "\n\n"; 276b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola std::string name = Mang->getValueName(I); 277b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola Constant *C = I->getInitializer(); 278b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola unsigned Size = TD->getTypeSize(C->getType()); 279b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola unsigned Align = TD->getTypeAlignment(C->getType()); 280b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola 2816d581e8d1567e4e445e2cc88c790c79eb75c226aRafael Espindola switch (I->getLinkage()) { 2826d581e8d1567e4e445e2cc88c790c79eb75c226aRafael Espindola default: 2836d581e8d1567e4e445e2cc88c790c79eb75c226aRafael Espindola assert(0 && "Unknown linkage type!"); 2846d581e8d1567e4e445e2cc88c790c79eb75c226aRafael Espindola break; 2856d581e8d1567e4e445e2cc88c790c79eb75c226aRafael Espindola case GlobalValue::ExternalLinkage: 2866d581e8d1567e4e445e2cc88c790c79eb75c226aRafael Espindola O << "\t.globl " << name << "\n"; 2876d581e8d1567e4e445e2cc88c790c79eb75c226aRafael Espindola break; 2886d581e8d1567e4e445e2cc88c790c79eb75c226aRafael Espindola case GlobalValue::InternalLinkage: 2896d581e8d1567e4e445e2cc88c790c79eb75c226aRafael Espindola break; 2906d581e8d1567e4e445e2cc88c790c79eb75c226aRafael Espindola } 291b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola 292b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola assert (!C->isNullValue()); 293b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola SwitchToDataSection(".data", I); 294b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola 295b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola EmitAlignment(Align, I); 296b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola O << "\t.type " << name << ", %object\n"; 297b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola O << "\t.size " << name << ", " << Size << "\n"; 298b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola O << name << ":\n"; 299b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola EmitGlobalConstant(C); 300b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola } 3017bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola AsmPrinter::doFinalization(M); 3027bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola return false; // success 3037bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} 304