//===-- ARMAsmPrinter.cpp - ARM LLVM assembly writer ----------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains a printer that converts from our internal representation
// of machine-dependent LLVM code to GAS-format ARM assembly language.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "asm-printer"
#include "ARM.h"
#include "ARMTargetMachine.h"
#include "ARMAddressingModes.h"
#include "ARMConstantPoolValue.h"
#include "ARMMachineFunctionInfo.h"
#include "llvm/Constants.h"
#include "llvm/Module.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <cctype>
using namespace llvm;
STATISTIC(EmittedInsts, "Number of machine instrs printed");
namespace {
class VISIBILITY_HIDDEN ARMAsmPrinter : public AsmPrinter {
DwarfWriter *DW;
MachineModuleInfo *MMI;
/// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
/// make the right decision when printing asm code for different targets.
const ARMSubtarget *Subtarget;
/// AFI - Keep a pointer to ARMFunctionInfo for the current
/// MachineFunction.
ARMFunctionInfo *AFI;
/// MCP - Keep a pointer to constantpool entries of the current
/// MachineFunction.
const MachineConstantPool *MCP;
/// We name each basic block in a Function with a unique number, so
/// that we can consistently refer to them later. This is cleared
/// at the beginning of each call to runOnMachineFunction().
///
typedef std::map<const Value *, unsigned> ValueMapTy;
ValueMapTy NumberForBB;
/// GVNonLazyPtrs - Keeps the set of GlobalValues that require
/// non-lazy-pointers for indirect access.
StringSet<> GVNonLazyPtrs;
/// HiddenGVNonLazyPtrs - Keeps the set of GlobalValues with hidden
/// visibility that require non-lazy-pointers for indirect access.
StringSet<> HiddenGVNonLazyPtrs;
/// FnStubs - Keeps the set of external function GlobalAddresses that the
/// asm printer should generate stubs for.
StringSet<> FnStubs;
/// True if asm printer is printing a series of CONSTPOOL_ENTRY.
bool InCPMode;
public:
ARMAsmPrinter(raw_ostream &O, TargetMachine &TM,
const TargetAsmInfo *T, bool F)
: AsmPrinter(O, TM, T, F), DW(0), MMI(NULL), AFI(NULL), MCP(NULL),
InCPMode(false) {
Subtarget = &TM.getSubtarget<ARMSubtarget>();
}
virtual const char *getPassName() const {
return "ARM Assembly Printer";
}
void printOperand(const MachineInstr *MI, int opNum,
const char *Modifier = 0);
void printSOImmOperand(const MachineInstr *MI, int opNum);
void printSOImm2PartOperand(const MachineInstr *MI, int opNum);
void printSORegOperand(const MachineInstr *MI, int opNum);
void printAddrMode2Operand(const MachineInstr *MI, int OpNo);
void printAddrMode2OffsetOperand(const MachineInstr *MI, int OpNo);
void printAddrMode3Operand(const MachineInstr *MI, int OpNo);
void printAddrMode3OffsetOperand(const MachineInstr *MI, int OpNo);
void printAddrMode4Operand(const MachineInstr *MI, int OpNo,
const char *Modifier = 0);
void printAddrMode5Operand(const MachineInstr *MI, int OpNo,
const char *Modifier = 0);
void printAddrModePCOperand(const MachineInstr *MI, int OpNo,
const char *Modifier = 0);
void printThumbAddrModeRROperand(const MachineInstr *MI, int OpNo);
void printThumbAddrModeRI5Operand(const MachineInstr *MI, int OpNo,
unsigned Scale);
void printThumbAddrModeS1Operand(const MachineInstr *MI, int OpNo);
void printThumbAddrModeS2Operand(const MachineInstr *MI, int OpNo);
void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNo);
void