//===-- ARM/ARMCodeEmitter.cpp - Convert ARM code to machine code ---------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the pass that transforms the ARM machine instructions into
// relocatable machine code.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "jit"
#include "ARM.h"
#include "ARMAddressingModes.h"
#include "ARMConstantPoolValue.h"
#include "ARMInstrInfo.h"
#include "ARMRelocations.h"
#include "ARMSubtarget.h"
#include "ARMTargetMachine.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/PassManager.h"
#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#ifndef NDEBUG
#include <iomanip>
#endif
using namespace llvm;
STATISTIC(NumEmitted, "Number of machine instructions emitted");
namespace {
class VISIBILITY_HIDDEN ARMCodeEmitter : public MachineFunctionPass {
ARMJITInfo *JTI;
const ARMInstrInfo *II;
const TargetData *TD;
TargetMachine &TM;
MachineCodeEmitter &MCE;
const std::vector<MachineConstantPoolEntry> *MCPEs;
const std::vector<MachineJumpTableEntry> *MJTEs;
bool IsPIC;
public:
static char ID;
explicit ARMCodeEmitter(TargetMachine &tm, MachineCodeEmitter &mce)
: MachineFunctionPass(&ID), JTI(0), II(0), TD(0), TM(tm),
MCE(mce), MCPEs(0), MJTEs(0),
IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
ARMCodeEmitter(TargetMachine &tm, MachineCodeEmitter &mce,
const ARMInstrInfo &ii, const TargetData &td)
: MachineFunctionPass(&ID), JTI(0), II(&ii), TD(&td), TM(tm),
MCE(mce), MCPEs(0), MJTEs(0),
IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
bool runOnMachineFunction(MachineFunction &MF);
virtual const char *getPassName() const {
return "ARM Machine Code Emitter";
}
void emitInstruction(const MachineInstr &MI);
private:
void emitWordLE(unsigned Binary);
void emitConstPoolInstruction(const MachineInstr &MI);
void emitMOVi2piecesInstruction(const MachineInstr &MI);
void emitLEApcrelJTInstruction(const MachineInstr &MI);
void addPCLabel(unsigned LabelID);
void emitPseudoInstruction(const MachineInstr &MI);
unsigned getMachineSoRegOpValue(const MachineInstr &MI,
const TargetInstrDesc &TID,
const MachineOperand &MO,
unsigned OpIdx);
unsigned getMachineSoImmOpValue(unsigned SoImm);
unsigned getAddrModeSBit(const MachineInstr &MI,
const TargetInstrDesc &TID) const;
void emitDataProcessingInstruction(const MachineInstr &MI,
unsigned ImplicitRd = 0,
unsigned ImplicitRn = 0);
void emitLoadStoreInstruction(const MachineInstr &MI,
unsigned ImplicitRd = 0,
unsigned ImplicitRn = 0);
void emitMiscLoadStoreInstruction(const MachineInstr &MI,
unsigned ImplicitRn = 0);
void emitLoadStoreMultipleInstruction(const MachineInstr &MI);
void emitMulFrmInstruction(const MachineInstr &MI);
void emitExtendInstruction(const MachineInstr &MI);
void emitMiscArithInstruction(const MachineInstr &MI);
void emitBranchInstruction(const MachineInstr &MI);
void emitInlineJumpTable(unsigned JTIndex);
void emitMiscBranchInstruction(const MachineInstr &MI);
/// getBinaryCodeForInstr - This function, generated by the
/// CodeEmitterGenerator using TableGen, produces the binary encoding for
/// machine instructions.
///
unsigned getBinaryCodeForInstr(const MachineInstr &MI);
/// getMachineOpValue - Return binary encoding of operand. If the machine
/// operand requires relocation, record the relocation and return zero.
unsigned getMachineOpValue(const MachineInstr &MI,const MachineOperand &MO);
unsigned getMachineOpValue(const MachineInstr &MI, unsigned