//===-- ARMAsmPrinter.cpp - ARM LLVM assembly writer ----------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the "Instituto Nokia de Tecnologia" and
// 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/Support/Compiler.h"
#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
#include <cctype>
using namespace llvm;
STATISTIC(EmittedInsts, "Number of machine instrs printed");
namespace {
struct VISIBILITY_HIDDEN ARMAsmPrinter : public AsmPrinter {
ARMAsmPrinter(std::ostream &O, TargetMachine &TM, const TargetAsmInfo *T)
: AsmPrinter(O, TM, T), DW(O, this, T), AFI(NULL), InCPMode(false) {
Subtarget = &TM.getSubtarget<ARMSubtarget>();
}
DwarfWriter DW;
/// 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;
/// 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;
/// Keeps the set of GlobalValues that require non-lazy-pointers for
/// indirect access.
std::set<std::string> GVNonLazyPtrs;
/// Keeps the set of external function GlobalAddresses that the asm
/// printer should generate stubs for.
std::set<std::string> FnStubs;
/// True if asm printer is printing a series of CONSTPOOL_ENTRY.
bool InCPMode;
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 printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNo);
void printCCOperand(const MachineInstr *MI, int opNum);
void printPCLabel(const MachineInstr *MI, int opNum);
void printRegisterList(const MachineInstr *MI, int opNum);
void printCPInstOperand(const MachineInstr *MI, int opNum,
const char *Modifier);
void printJTBlockOperand(const MachineInstr *MI, int opNum);
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode);
bool printInstruction(const MachineInstr *MI); // autogenerated.
void printMachineInstruction(const MachineInstr *MI);
bool