#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/PassManager.h"
-#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/CodeGen/JITCodeEmitter.h"
-#include "llvm/CodeGen/ObjectCodeEmitter.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
namespace {
- class ARMCodeEmitter {
- public:
- /// getBinaryCodeForInstr - This function, generated by the
- /// CodeEmitterGenerator using TableGen, produces the binary encoding for
- /// machine instructions.
- unsigned getBinaryCodeForInstr(const MachineInstr &MI);
- };
-
- template<class CodeEmitter>
- class VISIBILITY_HIDDEN Emitter : public MachineFunctionPass,
- public ARMCodeEmitter {
+ class ARMCodeEmitter : public MachineFunctionPass {
ARMJITInfo *JTI;
const ARMInstrInfo *II;
const TargetData *TD;
+ const ARMSubtarget *Subtarget;
TargetMachine &TM;
- CodeEmitter &MCE;
+ JITCodeEmitter &MCE;
const std::vector<MachineConstantPoolEntry> *MCPEs;
const std::vector<MachineJumpTableEntry> *MJTEs;
bool IsPIC;
-
- public:
+
+ void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<MachineModuleInfo>();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
static char ID;
- explicit Emitter(TargetMachine &tm, CodeEmitter &mce)
- : MachineFunctionPass(&ID), JTI(0), II(0), TD(0), TM(tm),
- MCE(mce), MCPEs(0), MJTEs(0),
- IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
- Emitter(TargetMachine &tm, CodeEmitter &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_) {}
+ public:
+ ARMCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce)
+ : MachineFunctionPass(&ID), JTI(0), II((ARMInstrInfo*)tm.getInstrInfo()),
+ TD(tm.getTargetData()), TM(tm),
+ MCE(mce), MCPEs(0), MJTEs(0),
+ IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
+
+ /// getBinaryCodeForInstr - This function, generated by the
+ /// CodeEmitterGenerator using TableGen, produces the binary encoding for
+ /// machine instructions.
+ unsigned getBinaryCodeForInstr(const MachineInstr &MI);
bool runOnMachineFunction(MachineFunction &MF);
private:
void emitWordLE(unsigned Binary);
-
void emitDWordLE(uint64_t Binary);
-
void emitConstPoolInstruction(const MachineInstr &MI);
-
void emitMOVi2piecesInstruction(const MachineInstr &MI);
-
void emitLEApcrelJTInstruction(const MachineInstr &MI);
-
void emitPseudoMoveInstruction(const MachineInstr &MI);
-
void addPCLabel(unsigned LabelID);
-
void emitPseudoInstruction(const MachineInstr &MI);
-
unsigned getMachineSoRegOpValue(const MachineInstr &MI,
const TargetInstrDesc &TID,
const MachineOperand &MO,
/// Routines that handle operands which add machine relocations which are
/// fixed up by the relocation stage.
void emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
- bool NeedStub, intptr_t ACPV = 0);
+ bool MayNeedFarStub, bool Indirect,
+ intptr_t ACPV = 0);
void emitExternalSymbolAddress(const char *ES, unsigned Reloc);
void emitConstPoolAddress(unsigned CPI, unsigned Reloc);
void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc);
void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc,
intptr_t JTBase = 0);
};
- template <class CodeEmitter>
- char Emitter<CodeEmitter>::ID = 0;
}
-/// createARMCodeEmitterPass - Return a pass that emits the collected ARM code
-/// to the specified MCE object.
+char ARMCodeEmitter::ID = 0;
-FunctionPass *llvm::createARMCodeEmitterPass(ARMBaseTargetMachine &TM,
- MachineCodeEmitter &MCE) {
- return new Emitter<MachineCodeEmitter>(TM, MCE);
-}
+/// createARMJITCodeEmitterPass - Return a pass that emits the collected ARM
+/// code to the specified MCE object.
FunctionPass *llvm::createARMJITCodeEmitterPass(ARMBaseTargetMachine &TM,
JITCodeEmitter &JCE) {
- return new Emitter<JITCodeEmitter>(TM, JCE);
-}
-FunctionPass *llvm::createARMObjectCodeEmitterPass(ARMBaseTargetMachine &TM,
- ObjectCodeEmitter &OCE) {
- return new Emitter<ObjectCodeEmitter>(TM, OCE);
+ return new ARMCodeEmitter(TM, JCE);
}
-template<class CodeEmitter>
-bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) {
+bool ARMCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
assert((MF.getTarget().getRelocationModel() != Reloc::Default ||
MF.getTarget().getRelocationModel() != Reloc::Static) &&
"JIT relocation model must be set to static or default!");
+ JTI = ((ARMTargetMachine&)MF.getTarget()).getJITInfo();
II = ((ARMTargetMachine&)MF.getTarget()).getInstrInfo();
TD = ((ARMTargetMachine&)MF.getTarget()).getTargetData();
- JTI = ((ARMTargetMachine&)MF.getTarget()).getJITInfo();
+ Subtarget = &TM.getSubtarget<ARMSubtarget>();
MCPEs = &MF.getConstantPool()->getConstants();
- MJTEs = &MF.getJumpTableInfo()->getJumpTables();
+ MJTEs = 0;
+ if (MF.getJumpTableInfo()) MJTEs = &MF.getJumpTableInfo()->getJumpTables();
IsPIC = TM.getRelocationModel() == Reloc::PIC_;
JTI->Initialize(MF, IsPIC);
+ MCE.setModuleInfo(&getAnalysis<MachineModuleInfo>());
do {
- DOUT << "JITTing function '" << MF.getFunction()->getName() << "'\n";
+ DEBUG(errs() << "JITTing function '"
+ << MF.getFunction()->getName() << "'\n");
MCE.startFunction(MF);
- for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
+ for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
MBB != E; ++MBB) {
MCE.StartMachineBasicBlock(MBB);
for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end();
/// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
///
-template<class CodeEmitter>
-unsigned Emitter<CodeEmitter>::getShiftOp(unsigned Imm) const {
+unsigned ARMCodeEmitter::getShiftOp(unsigned Imm) const {
switch (ARM_AM::getAM2ShiftOpc(Imm)) {
default: llvm_unreachable("Unknown shift opc!");
case ARM_AM::asr: return 2;
/// getMachineOpValue - Return binary encoding of operand. If the machine
/// operand requires relocation, record the relocation and return zero.
-template<class CodeEmitter>
-unsigned Emitter<CodeEmitter>::getMachineOpValue(const MachineInstr &MI,
- const MachineOperand &MO) {
+unsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI,
+ const MachineOperand &MO) {
if (MO.isReg())
return ARMRegisterInfo::getRegisterNumbering(MO.getReg());
else if (MO.isImm())
return static_cast<unsigned>(MO.getImm());
else if (MO.isGlobal())
- emitGlobalAddress(MO.getGlobal(), ARM::reloc_arm_branch, true);
+ emitGlobalAddress(MO.getGlobal(), ARM::reloc_arm_branch, true, false);
else if (MO.isSymbol())
emitExternalSymbolAddress(MO.getSymbolName(), ARM::reloc_arm_branch);
else if (MO.isCPI()) {
emitMachineBasicBlock(MO.getMBB(), ARM::reloc_arm_branch);
else {
#ifndef NDEBUG
- cerr << MO;
+ errs() << MO;
#endif
llvm_unreachable(0);
}
/// emitGlobalAddress - Emit the specified address to the code stream.
///
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
- bool NeedStub, intptr_t ACPV) {
- MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
- GV, ACPV, NeedStub));
+void ARMCodeEmitter::emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
+ bool MayNeedFarStub, bool Indirect,
+ intptr_t ACPV) {
+ MachineRelocation MR = Indirect
+ ? MachineRelocation::getIndirectSymbol(MCE.getCurrentPCOffset(), Reloc,
+ GV, ACPV, MayNeedFarStub)
+ : MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
+ GV, ACPV, MayNeedFarStub);
+ MCE.addRelocation(MR);
}
/// emitExternalSymbolAddress - Arrange for the address of an external symbol to
/// be emitted to the current location in the function, and allow it to be PC
/// relative.
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitExternalSymbolAddress(const char *ES,
- unsigned Reloc) {
+void ARMCodeEmitter::emitExternalSymbolAddress(const char *ES, unsigned Reloc) {
MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
Reloc, ES));
}
/// emitConstPoolAddress - Arrange for the address of an constant pool
/// to be emitted to the current location in the function, and allow it to be PC
/// relative.
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitConstPoolAddress(unsigned CPI,
- unsigned Reloc) {
+void ARMCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) {
// Tell JIT emitter we'll resolve the address.
MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
Reloc, CPI, 0, true));
/// emitJumpTableAddress - Arrange for the address of a jump table to
/// be emitted to the current location in the function, and allow it to be PC
/// relative.
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitJumpTableAddress(unsigned JTIndex,
- unsigned Reloc) {
+void ARMCodeEmitter::emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) {
MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
Reloc, JTIndex, 0, true));
}
/// emitMachineBasicBlock - Emit the specified address basic block.
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitMachineBasicBlock(MachineBasicBlock *BB,
- unsigned Reloc, intptr_t JTBase) {
+void ARMCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
+ unsigned Reloc, intptr_t JTBase) {
MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
Reloc, BB, JTBase));
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitWordLE(unsigned Binary) {
-#ifndef NDEBUG
- DOUT << " 0x" << std::hex << std::setw(8) << std::setfill('0')
- << Binary << std::dec << "\n";
-#endif
+void ARMCodeEmitter::emitWordLE(unsigned Binary) {
+ DEBUG(errs() << " 0x";
+ errs().write_hex(Binary) << "\n");
MCE.emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitDWordLE(uint64_t Binary) {
-#ifndef NDEBUG
- DOUT << " 0x" << std::hex << std::setw(8) << std::setfill('0')
- << (unsigned)Binary << std::dec << "\n";
- DOUT << " 0x" << std::hex << std::setw(8) << std::setfill('0')
- << (unsigned)(Binary >> 32) << std::dec << "\n";
-#endif
+void ARMCodeEmitter::emitDWordLE(uint64_t Binary) {
+ DEBUG(errs() << " 0x";
+ errs().write_hex(Binary) << "\n");
MCE.emitDWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI) {
- DOUT << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << MI;
+void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
+ DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << MI);
- MCE.processDebugLoc(MI.getDebugLoc());
+ MCE.processDebugLoc(MI.getDebugLoc(), true);
NumEmitted++; // Keep track of the # of mi's emitted
switch (MI.getDesc().TSFlags & ARMII::FormMask) {
emitMiscInstruction(MI);
break;
}
+ MCE.processDebugLoc(MI.getDebugLoc(), false);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitConstPoolInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
unsigned CPI = MI.getOperand(0).getImm(); // CP instruction index.
unsigned CPIndex = MI.getOperand(1).getIndex(); // Actual cp entry index.
const MachineConstantPoolEntry &MCPE = (*MCPEs)[CPIndex];
-
+
// Remember the CONSTPOOL_ENTRY address for later relocation.
JTI->addConstantPoolEntryAddr(CPI, MCE.getCurrentPCValue());
ARMConstantPoolValue *ACPV =
static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);
- DOUT << " ** ARM constant pool #" << CPI << " @ "
- << (void*)MCE.getCurrentPCValue() << " " << *ACPV << '\n';
+ DEBUG(errs() << " ** ARM constant pool #" << CPI << " @ "
+ << (void*)MCE.getCurrentPCValue() << " " << *ACPV << '\n');
+ assert(ACPV->isGlobalValue() && "unsupported constant pool value");
GlobalValue *GV = ACPV->getGV();
if (GV) {
- assert(!ACPV->isStub() && "Don't know how to deal this yet!");
- if (ACPV->isNonLazyPointer())
- MCE.addRelocation(MachineRelocation::getIndirectSymbol(
- MCE.getCurrentPCOffset(), ARM::reloc_arm_machine_cp_entry, GV,
- (intptr_t)ACPV, false));
- else
- emitGlobalAddress(GV, ARM::reloc_arm_machine_cp_entry,
- ACPV->isStub() || isa<Function>(GV), (intptr_t)ACPV);
+ Reloc::Model RelocM = TM.getRelocationModel();
+ emitGlobalAddress(GV, ARM::reloc_arm_machine_cp_entry,
+ isa<Function>(GV),
+ Subtarget->GVIsIndirectSymbol(GV, RelocM),
+ (intptr_t)ACPV);
} else {
- assert(!ACPV->isNonLazyPointer() && "Don't know how to deal this yet!");
emitExternalSymbolAddress(ACPV->getSymbol(), ARM::reloc_arm_absolute);
}
emitWordLE(0);
} else {
Constant *CV = MCPE.Val.ConstVal;
-#ifndef NDEBUG
- DOUT << " ** Constant pool #" << CPI << " @ "
- << (void*)MCE.getCurrentPCValue() << " ";
- if (const Function *F = dyn_cast<Function>(CV))
- DOUT << F->getName();
- else
- DOUT << *CV;
- DOUT << '\n';
-#endif
+ DEBUG({
+ errs() << " ** Constant pool #" << CPI << " @ "
+ << (void*)MCE.getCurrentPCValue() << " ";
+ if (const Function *F = dyn_cast<Function>(CV))
+ errs() << F->getName();
+ else
+ errs() << *CV;
+ errs() << '\n';
+ });
if (GlobalValue *GV = dyn_cast<GlobalValue>(CV)) {
- emitGlobalAddress(GV, ARM::reloc_arm_absolute, isa<Function>(GV));
+ emitGlobalAddress(GV, ARM::reloc_arm_absolute, isa<Function>(GV), false);
emitWordLE(0);
} else if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
uint32_t Val = *(uint32_t*)CI->getValue().getRawData();
emitWordLE(Val);
} else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
- if (CFP->getType() == Type::FloatTy)
+ if (CFP->getType()->isFloatTy())
emitWordLE(CFP->getValueAPF().bitcastToAPInt().getZExtValue());
- else if (CFP->getType() == Type::DoubleTy)
+ else if (CFP->getType()->isDoubleTy())
emitDWordLE(CFP->getValueAPF().bitcastToAPInt().getZExtValue());
else {
llvm_unreachable("Unable to handle this constantpool entry!");
}
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitMOVi2piecesInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitMOVi2piecesInstruction(const MachineInstr &MI) {
const MachineOperand &MO0 = MI.getOperand(0);
const MachineOperand &MO1 = MI.getOperand(1);
assert(MO1.isImm() && ARM_AM::getSOImmVal(MO1.isImm()) != -1 &&
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitLEApcrelJTInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitLEApcrelJTInstruction(const MachineInstr &MI) {
// It's basically add r, pc, (LJTI - $+8)
-
+
const TargetInstrDesc &TID = MI.getDesc();
// Emit the 'add' instruction.
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitPseudoMoveInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitPseudoMoveInstruction(const MachineInstr &MI) {
unsigned Opcode = MI.getDesc().Opcode;
// Part of binary is determined by TableGn.
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::addPCLabel(unsigned LabelID) {
- DOUT << " ** LPC" << LabelID << " @ "
- << (void*)MCE.getCurrentPCValue() << '\n';
+void ARMCodeEmitter::addPCLabel(unsigned LabelID) {
+ DEBUG(errs() << " ** LPC" << LabelID << " @ "
+ << (void*)MCE.getCurrentPCValue() << '\n');
JTI->addPCLabelAddr(LabelID, MCE.getCurrentPCValue());
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitPseudoInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
unsigned Opcode = MI.getDesc().Opcode;
switch (Opcode) {
default:
- llvm_unreachable("ARMCodeEmitter::emitPseudoInstruction");//FIXME:
- case TargetInstrInfo::INLINEASM: {
+ llvm_unreachable("ARMCodeEmitter::emitPseudoInstruction");
+ // FIXME: Add support for MOVimm32.
+ case TargetOpcode::INLINEASM: {
// We allow inline assembler nodes with empty bodies - they can
// implicitly define registers, which is ok for JIT.
if (MI.getOperand(0).getSymbolName()[0]) {
}
break;
}
- case TargetInstrInfo::DBG_LABEL:
- case TargetInstrInfo::EH_LABEL:
+ case TargetOpcode::DBG_LABEL:
+ case TargetOpcode::EH_LABEL:
MCE.emitLabel(MI.getOperand(0).getImm());
break;
- case TargetInstrInfo::IMPLICIT_DEF:
- case TargetInstrInfo::DECLARE:
- case ARM::DWARF_LOC:
+ case TargetOpcode::IMPLICIT_DEF:
+ case TargetOpcode::KILL:
// Do nothing.
break;
case ARM::CONSTPOOL_ENTRY:
}
}
-template<class CodeEmitter>
-unsigned Emitter<CodeEmitter>::getMachineSoRegOpValue(
+unsigned ARMCodeEmitter::getMachineSoRegOpValue(
const MachineInstr &MI,
const TargetInstrDesc &TID,
const MachineOperand &MO,
return Binary | ARM_AM::getSORegOffset(MO2.getImm()) << 7;
}
-template<class CodeEmitter>
-unsigned Emitter<CodeEmitter>::getMachineSoImmOpValue(unsigned SoImm) {
+unsigned ARMCodeEmitter::getMachineSoImmOpValue(unsigned SoImm) {
int SoImmVal = ARM_AM::getSOImmVal(SoImm);
assert(SoImmVal != -1 && "Not a valid so_imm value!");
return Binary;
}
-template<class CodeEmitter>
-unsigned Emitter<CodeEmitter>::getAddrModeSBit(const MachineInstr &MI,
+unsigned ARMCodeEmitter::getAddrModeSBit(const MachineInstr &MI,
const TargetInstrDesc &TID) const {
for (unsigned i = MI.getNumOperands(), e = TID.getNumOperands(); i != e; --i){
const MachineOperand &MO = MI.getOperand(i-1);
return 0;
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitDataProcessingInstruction(
+void ARMCodeEmitter::emitDataProcessingInstruction(
const MachineInstr &MI,
unsigned ImplicitRd,
unsigned ImplicitRn) {
const TargetInstrDesc &TID = MI.getDesc();
if (TID.Opcode == ARM::BFC) {
- llvm_report_error("ERROR: ARMv6t2 JIT is not yet supported.");
+ llvm_report_error("ARMv6t2 JIT is not yet supported.");
}
// Part of binary is determined by TableGn.
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitLoadStoreInstruction(
+void ARMCodeEmitter::emitLoadStoreInstruction(
const MachineInstr &MI,
unsigned ImplicitRd,
unsigned ImplicitRn) {
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitMiscLoadStoreInstruction(const MachineInstr &MI,
+void ARMCodeEmitter::emitMiscLoadStoreInstruction(const MachineInstr &MI,
unsigned ImplicitRn) {
const TargetInstrDesc &TID = MI.getDesc();
unsigned Form = TID.TSFlags & ARMII::FormMask;
// DB - Decrement before - bit U = 0 and bit P = 1
switch (Mode) {
default: llvm_unreachable("Unknown addressing sub-mode!");
- case ARM_AM::da: break;
+ case ARM_AM::da: break;
case ARM_AM::db: Binary |= 0x1 << ARMII::P_BitShift; break;
case ARM_AM::ia: Binary |= 0x1 << ARMII::U_BitShift; break;
case ARM_AM::ib: Binary |= 0x3 << ARMII::U_BitShift; break;
return Binary;
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitLoadStoreMultipleInstruction(
+void ARMCodeEmitter::emitLoadStoreMultipleInstruction(
const MachineInstr &MI) {
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);
Binary |= 0x1 << ARMII::W_BitShift;
// Set registers
- for (unsigned i = 4, e = MI.getNumOperands(); i != e; ++i) {
+ for (unsigned i = 5, e = MI.getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg() || MO.isImplicit())
break;
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitMulFrmInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitMulFrmInstruction(const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
// Part of binary is determined by TableGn.
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitExtendInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitExtendInstruction(const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
// Part of binary is determined by TableGn.
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitMiscArithInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitMiscArithInstruction(const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
// Part of binary is determined by TableGn.
unsigned ShiftAmt = MI.getOperand(OpIdx).getImm();
assert(ShiftAmt < 32 && "shift_imm range is 0 to 31!");
Binary |= ShiftAmt << ARMII::ShiftShift;
-
+
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitBranchInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitBranchInstruction(const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
if (TID.Opcode == ARM::TPsoft) {
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitInlineJumpTable(unsigned JTIndex) {
+void ARMCodeEmitter::emitInlineJumpTable(unsigned JTIndex) {
// Remember the base address of the inline jump table.
uintptr_t JTBase = MCE.getCurrentPCValue();
JTI->addJumpTableBaseAddr(JTIndex, JTBase);
- DOUT << " ** Jump Table #" << JTIndex << " @ " << (void*)JTBase << '\n';
+ DEBUG(errs() << " ** Jump Table #" << JTIndex << " @ " << (void*)JTBase
+ << '\n');
// Now emit the jump table entries.
const std::vector<MachineBasicBlock*> &MBBs = (*MJTEs)[JTIndex].MBBs;
}
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitMiscBranchInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitMiscBranchInstruction(const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
// Handle jump tables.
- if (TID.Opcode == ARM::BR_JTr || TID.Opcode == ARM::BR_JTadd ||
- TID.Opcode == ARM::t2BR_JTr || TID.Opcode == ARM::t2BR_JTadd) {
+ if (TID.Opcode == ARM::BR_JTr || TID.Opcode == ARM::BR_JTadd) {
// First emit a ldr pc, [] instruction.
emitDataProcessingInstruction(MI, ARM::PC);
// Then emit the inline jump table.
unsigned JTIndex =
- (TID.Opcode == ARM::BR_JTr || TID.Opcode == ARM::t2BR_JTr)
+ (TID.Opcode == ARM::BR_JTr)
? MI.getOperand(1).getIndex() : MI.getOperand(2).getIndex();
emitInlineJumpTable(JTIndex);
return;
- } else if (TID.Opcode == ARM::BR_JTm || TID.Opcode == ARM::t2BR_JTm) {
+ } else if (TID.Opcode == ARM::BR_JTm) {
// First emit a ldr pc, [] instruction.
emitLoadStoreInstruction(MI, ARM::PC);
if (TID.Opcode == ARM::BX_RET)
// The return register is LR.
Binary |= ARMRegisterInfo::getRegisterNumbering(ARM::LR);
- else
+ else
// otherwise, set the return register
Binary |= getMachineOpValue(MI, 0);
return Binary;
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitVFPArithInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitVFPArithInstruction(const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
// Part of binary is determined by TableGn.
// Encode Dm / Sm.
Binary |= encodeVFPRm(MI, OpIdx);
-
+
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitVFPConversionInstruction(
+void ARMCodeEmitter::emitVFPConversionInstruction(
const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
unsigned Form = TID.TSFlags & ARMII::FormMask;
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitVFPLoadStoreInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitVFPLoadStoreInstruction(const MachineInstr &MI) {
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitVFPLoadStoreMultipleInstruction(
+void ARMCodeEmitter::emitVFPLoadStoreMultipleInstruction(
const MachineInstr &MI) {
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);
Binary |= 0x1 << ARMII::W_BitShift;
// First register is encoded in Dd.
- Binary |= encodeVFPRd(MI, 4);
+ Binary |= encodeVFPRd(MI, 5);
// Number of registers are encoded in offset field.
unsigned NumRegs = 1;
- for (unsigned i = 5, e = MI.getNumOperands(); i != e; ++i) {
+ for (unsigned i = 6, e = MI.getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg() || MO.isImplicit())
break;
emitWordLE(Binary);
}
-template<class CodeEmitter>
-void Emitter<CodeEmitter>::emitMiscInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitMiscInstruction(const MachineInstr &MI) {
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);