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