ARMAsmPrinter.cpp revision 7cca7c531773f763c1bddc3fefecc99ba56ed10a
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);
587cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola
59f3a335cedff423438789c593d58be068b124dc1eRafael Espindola    void printMemRegImm(const MachineInstr *MI, int opNum,
60f3a335cedff423438789c593d58be068b124dc1eRafael Espindola			const char *Modifier = NULL) {
61f3a335cedff423438789c593d58be068b124dc1eRafael Espindola      const MachineOperand &MO1 = MI->getOperand(opNum);
62f3a335cedff423438789c593d58be068b124dc1eRafael Espindola      const MachineOperand &MO2 = MI->getOperand(opNum + 1);
631ed3af11b55becb26a3485494409084a668a9232Rafael Espindola      assert(MO1.isImmediate());
64f3a335cedff423438789c593d58be068b124dc1eRafael Espindola      bool arith = false;
65f3a335cedff423438789c593d58be068b124dc1eRafael Espindola      if (Modifier != NULL) {
66f3a335cedff423438789c593d58be068b124dc1eRafael Espindola	assert(strcmp(Modifier, "arith") == 0);
67f3a335cedff423438789c593d58be068b124dc1eRafael Espindola	arith = true;
68f3a335cedff423438789c593d58be068b124dc1eRafael Espindola      }
691ed3af11b55becb26a3485494409084a668a9232Rafael Espindola
701ed3af11b55becb26a3485494409084a668a9232Rafael Espindola      if (MO2.isConstantPoolIndex()) {
71f3a335cedff423438789c593d58be068b124dc1eRafael Espindola	printOperand(MI, opNum + 1);
721ed3af11b55becb26a3485494409084a668a9232Rafael Espindola      } else if (MO2.isRegister()) {
73f3a335cedff423438789c593d58be068b124dc1eRafael Espindola	if(!arith)
74f3a335cedff423438789c593d58be068b124dc1eRafael Espindola	  O << '[';
75f3a335cedff423438789c593d58be068b124dc1eRafael Espindola	printOperand(MI, opNum + 1);
761ed3af11b55becb26a3485494409084a668a9232Rafael Espindola	O << ", ";
77f3a335cedff423438789c593d58be068b124dc1eRafael Espindola	printOperand(MI, opNum);
78f3a335cedff423438789c593d58be068b124dc1eRafael Espindola	if(!arith)
79f3a335cedff423438789c593d58be068b124dc1eRafael Espindola	  O << ']';
801ed3af11b55becb26a3485494409084a668a9232Rafael Espindola      } else {
811ed3af11b55becb26a3485494409084a668a9232Rafael Espindola	assert(0 && "Invalid Operand Type");
821ed3af11b55becb26a3485494409084a668a9232Rafael Espindola      }
83a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola    }
84a4e64359aafaf23e440e9dc171859daef1995f1bRafael Espindola
857bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    void printOperand(const MachineInstr *MI, int opNum);
867bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    void printMemOperand(const MachineInstr *MI, int opNum,
877bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                         const char *Modifier = 0);
887bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    void printCCOperand(const MachineInstr *MI, int opNum);
897bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
907bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    bool printInstruction(const MachineInstr *MI);  // autogenerated.
917bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    bool runOnMachineFunction(MachineFunction &F);
927bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    bool doInitialization(Module &M);
937bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    bool doFinalization(Module &M);
947bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  };
957bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace
967bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
977bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARMGenAsmWriter.inc"
987bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
997bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// createARMCodePrinterPass - Returns a pass that prints the ARM
1007bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// assembly code for a MachineFunction to the given output stream,
1017bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// using the given target machine description.  This should work
1027bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// regardless of whether the function is in SSA form.
1037bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola///
1047bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaFunctionPass *llvm::createARMCodePrinterPass(std::ostream &o,
1057bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                               TargetMachine &tm) {
106a0f3d17daac73c9c71aad497b298cbe82848f726Jim Laskey  return new ARMAsmPrinter(o, tm, tm.getTargetAsmInfo());
1077bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1087bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1097bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// runOnMachineFunction - This uses the printMachineInstruction()
1107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction.
1117bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola///
1127bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
1134b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  SetupMachineFunction(MF);
1144b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  O << "\n\n";
1154b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola
1164b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  // Print out constants referenced by the function
1174b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  EmitConstantPool(MF.getConstantPool());
1184b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola
1194b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  // Print out jump tables referenced by the function
1204b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  EmitJumpTableInfo(MF.getJumpTableInfo());
1214b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola
1224b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  // Print out labels for the function.
1234b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  const Function *F = MF.getFunction();
1244b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  switch (F->getLinkage()) {
1254b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  default: assert(0 && "Unknown linkage type!");
1264b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  case Function::InternalLinkage:
1274b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    SwitchToTextSection("\t.text", F);
1284b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    break;
1294b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  case Function::ExternalLinkage:
1304b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    SwitchToTextSection("\t.text", F);
1314b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    O << "\t.globl\t" << CurrentFnName << "\n";
1324b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    break;
1334b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  case Function::WeakLinkage:
1344b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  case Function::LinkOnceLinkage:
1354b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    assert(0 && "Not implemented");
1364b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    break;
1374b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  }
138a1334cdfb2afb44a1f2b952391e1b2fecb1d4bd8Rafael Espindola  EmitAlignment(2, F);
1394b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  O << CurrentFnName << ":\n";
1404b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola
1414b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  // Print out code for the function.
1424b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
1434b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola       I != E; ++I) {
1444b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    // Print a label for the basic block.
1454b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    if (I != MF.begin()) {
1464b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola      printBasicBlockLabel(I, true);
1474b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola      O << '\n';
1484b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    }
1494b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
1504b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola         II != E; ++II) {
1514b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola      // Print the assembly for the instruction.
1524b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola      O << "\t";
1534b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola      printInstruction(II);
1544b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    }
1554b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  }
1564b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola
1577bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  return false;
1587bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1597bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1607cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindolavoid ARMAsmPrinter::printAddrMode1(const MachineInstr *MI, int opNum) {
1617cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola  const MachineOperand &MO1 = MI->getOperand(opNum);
1627cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola
1637cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola  if(MO1.isImmediate()) {
1647cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola    printOperand(MI, opNum);
1657cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola  } else {
1667cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola    assert(MO1.isRegister());
1677cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola    printOperand(MI, opNum);
1687cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola  }
1697cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola}
1707cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola
1717bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
1722f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  const MachineOperand &MO = MI->getOperand (opNum);
1732f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  const MRegisterInfo &RI = *TM.getRegisterInfo();
1742f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  switch (MO.getType()) {
1752f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_Register:
1762f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    if (MRegisterInfo::isPhysicalRegister(MO.getReg()))
1772f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola      O << LowercaseString (RI.get(MO.getReg()).Name);
1782f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    else
1792f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola      assert(0 && "not implemented");
1802f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
1812f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_Immediate:
1822f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    O << "#" << (int)MO.getImmedValue();
1832f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
1842f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_MachineBasicBlock:
185687bc49d1ada3fe0a2cd3fb5c044f12d267f259fRafael Espindola    printBasicBlockLabel(MO.getMachineBasicBlock());
1862f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    return;
18784b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola  case MachineOperand::MO_GlobalAddress: {
18884b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola    GlobalValue *GV = MO.getGlobal();
18984b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola    std::string Name = Mang->getValueName(GV);
19084b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola    O << Name;
19184b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola  }
1922f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
1932f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_ExternalSymbol:
1942f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    assert(0 && "not implemented");
1952f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    abort();
1962f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
1972f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_ConstantPoolIndex:
198563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey    O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
19906c1e7eacb11edd1671eabfc11291b7716be2608Rafael Espindola      << '_' << MO.getConstantPoolIndex();
2002f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
2012f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  default:
2022f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    O << "<unknown operand type>"; abort (); break;
2032f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  }
2047bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
2057bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
2067bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum,
2077bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola                                      const char *Modifier) {
2087bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  assert(0 && "not implemented");
2097bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
2107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
2117bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
2126f602de3b68cc63d12554ad6ae3c98a4c436c32dRafael Espindola  int CC = (int)MI->getOperand(opNum).getImmedValue();
2136f602de3b68cc63d12554ad6ae3c98a4c436c32dRafael Espindola  O << ARMCondCodeToString((ARMCC::CondCodes)CC);
2147bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
2157bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
2167bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::doInitialization(Module &M) {
217ff59d22232f47f138ed3d753975153befd1aa0c0Rafael Espindola  AsmPrinter::doInitialization(M);
2187bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  return false; // success
2197bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
2207bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
2217bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::doFinalization(Module &M) {
222b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola  const TargetData *TD = TM.getTargetData();
223b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola
224b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola  for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
225b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola       I != E; ++I) {
226b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola    if (!I->hasInitializer())   // External global require no code
227b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola      continue;
228b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola
229b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola    if (EmitSpecialLLVMGlobal(I))
230b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola      continue;
231b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola
232b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola    O << "\n\n";
233b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola    std::string name = Mang->getValueName(I);
234b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola    Constant *C = I->getInitializer();
235b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola    unsigned Size = TD->getTypeSize(C->getType());
236b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola    unsigned Align = TD->getTypeAlignment(C->getType());
237b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola
2386d581e8d1567e4e445e2cc88c790c79eb75c226aRafael Espindola    switch (I->getLinkage()) {
2396d581e8d1567e4e445e2cc88c790c79eb75c226aRafael Espindola    default:
2406d581e8d1567e4e445e2cc88c790c79eb75c226aRafael Espindola      assert(0 && "Unknown linkage type!");
2416d581e8d1567e4e445e2cc88c790c79eb75c226aRafael Espindola      break;
2426d581e8d1567e4e445e2cc88c790c79eb75c226aRafael Espindola    case GlobalValue::ExternalLinkage:
2436d581e8d1567e4e445e2cc88c790c79eb75c226aRafael Espindola      O << "\t.globl " << name << "\n";
2446d581e8d1567e4e445e2cc88c790c79eb75c226aRafael Espindola      break;
2456d581e8d1567e4e445e2cc88c790c79eb75c226aRafael Espindola    case GlobalValue::InternalLinkage:
2466d581e8d1567e4e445e2cc88c790c79eb75c226aRafael Espindola      break;
2476d581e8d1567e4e445e2cc88c790c79eb75c226aRafael Espindola    }
248b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola
249b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola    assert (!C->isNullValue());
250b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola    SwitchToDataSection(".data", I);
251b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola
252b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola    EmitAlignment(Align, I);
253b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola    O << "\t.type " << name << ", %object\n";
254b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola    O << "\t.size " << name << ", " << Size << "\n";
255b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola    O << name << ":\n";
256b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola    EmitGlobalConstant(C);
257b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola  }
2587bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  AsmPrinter::doFinalization(M);
2597bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  return false; // success
2607bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
261