//
//===----------------------------------------------------------------------===//
+#define DEBUG_TYPE "x86-emitter"
#include "X86InstrInfo.h"
#include "X86Subtarget.h"
#include "X86TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
using namespace llvm;
-namespace {
- Statistic<>
- NumEmitted("x86-emitter", "Number of machine instructions emitted");
-}
+STATISTIC(NumEmitted, "Number of machine instructions emitted");
namespace {
class VISIBILITY_HIDDEN Emitter : public MachineFunctionPass {
MachineCodeEmitter &MCE;
bool Is64BitMode;
public:
+ static char ID;
explicit Emitter(TargetMachine &tm, MachineCodeEmitter &mce)
- : II(0), TD(0), TM(tm), MCE(mce), Is64BitMode(false) {}
+ : MachineFunctionPass((intptr_t)&ID), II(0), TD(0), TM(tm),
+ MCE(mce), Is64BitMode(false) {}
Emitter(TargetMachine &tm, MachineCodeEmitter &mce,
const X86InstrInfo &ii, const TargetData &td, bool is64)
- : II(&ii), TD(&td), TM(tm), MCE(mce), Is64BitMode(is64) {}
+ : MachineFunctionPass((intptr_t)&ID), II(&ii), TD(&td), TM(tm),
+ MCE(mce), Is64BitMode(is64) {}
bool runOnMachineFunction(MachineFunction &MF);
bool isX86_64ExtendedReg(const MachineOperand &MO);
unsigned determineREX(const MachineInstr &MI);
};
+ char Emitter::ID = 0;
}
/// createX86CodeEmitterPass - Return a pass that emits the collected X86 code
unsigned PCAdj /* = 0 */) {
MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
Reloc, CPI, PCAdj));
+ if (Reloc == X86::reloc_absolute_dword)
+ MCE.emitWordLE(0);
MCE.emitWordLE(Disp); // The relocated value will be added to the displacement
}
unsigned PCAdj /* = 0 */) {
MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
Reloc, JTI, PCAdj));
+ if (Reloc == X86::reloc_absolute_dword)
+ MCE.emitWordLE(0);
MCE.emitWordLE(0); // The relocated value will be added to the displacement
}
for (unsigned e = NumOps; i != e; ++i) {
const MachineOperand& MO = MI.getOperand(i);
if (MO.isRegister()) {
- unsigned Reg = MO.getReg();
- // Trunc to byte are actually movb. The real source operand is the low
- // byte of the register.
- if (isTrunc8 && i == 1)
- Reg = getX86SubSuperRegister(Reg, MVT::i8);
- if (isX86_64NonExtLowByteReg(Reg))
- REX |= 0x40;
+ unsigned Reg = MO.getReg();
+ // Trunc to byte are actually movb. The real source operand is the low
+ // byte of the register.
+ if (isTrunc8 && i == 1)
+ Reg = getX86SubSuperRegister(Reg, MVT::i8);
+ if (isX86_64NonExtLowByteReg(Reg))
+ REX |= 0x40;
}
}
case X86II::TB:
Need0FPrefix = true; // Two-byte opcode prefix
break;
+ case X86II::T8:
+ MCE.emitByte(0x0F);
+ MCE.emitByte(0x38);
+ break;
+ case X86II::TA:
+ MCE.emitByte(0x0F);
+ MCE.emitByte(0x3A);
+ break;
case X86II::REP: break; // already handled.
case X86II::XS: // F3 0F
MCE.emitByte(0xF3);
unsigned CurOp = 0;
if (NumOps > 1 && Desc->getOperandConstraint(1, TOI::TIED_TO) != -1)
CurOp++;
-
+
unsigned char BaseOpcode = II->getBaseOpcodeFor(Desc);
switch (Desc->TSFlags & X86II::FormMask) {
default: assert(0 && "Unknown FormMask value in X86 MachineCodeEmitter!");
assert(0 && "psuedo instructions should be removed before code emission");
case TargetInstrInfo::INLINEASM:
assert(0 && "JIT does not support inline asm!\n");
+ case TargetInstrInfo::LABEL:
+ assert(0 && "JIT does not support meta labels!\n");
case X86::IMPLICIT_USE:
case X86::IMPLICIT_DEF:
case X86::IMPLICIT_DEF_GR8:
if (MO.isMachineBasicBlock()) {
emitPCRelativeBlockAddress(MO.getMachineBasicBlock());
} else if (MO.isGlobalAddress()) {
- bool isTailCall = Opcode == X86::TAILJMPd ||
- Opcode == X86::TAILJMPr || Opcode == X86::TAILJMPm;
- emitGlobalAddressForCall(MO.getGlobal(), !isTailCall);
+ bool NeedStub = Is64BitMode ||
+ Opcode == X86::TAILJMPd ||
+ Opcode == X86::TAILJMPr || Opcode == X86::TAILJMPm;
+ emitGlobalAddressForCall(MO.getGlobal(), !NeedStub);
} else if (MO.isExternalSymbol()) {
emitExternalSymbolAddress(MO.getSymbolName(), X86::reloc_pcrel_word);
} else if (MO.isImmediate()) {
emitConstant(MO1.getImm(), Size);
else {
unsigned rt = Is64BitMode ? X86::reloc_pcrel_word : X86::reloc_absolute_word;
- // FIXME
if (Opcode == X86::MOV64ri)
- rt = X86::reloc_absolute_dword;
+ rt = X86::reloc_absolute_dword; // FIXME: add X86II flag?
if (MO1.isGlobalAddress())
emitGlobalAddressForPtr(MO1.getGlobal(), rt, MO1.getOffset());
else if (MO1.isExternalSymbol())
if (MO1.isImmediate())
emitConstant(MO1.getImm(), Size);
else {
- unsigned rt = Is64BitMode ? X86::reloc_pcrel_word : X86::reloc_absolute_word;
- // FIXME
+ unsigned rt = Is64BitMode ? X86::reloc_pcrel_word
+ : X86::reloc_absolute_word;
if (Opcode == X86::MOV64ri32)
- rt = X86::reloc_absolute_word;
+ rt = X86::reloc_absolute_word; // FIXME: add X86II flag?
if (MO1.isGlobalAddress())
emitGlobalAddressForPtr(MO1.getGlobal(), rt, MO1.getOffset());
else if (MO1.isExternalSymbol())
if (MO.isImmediate())
emitConstant(MO.getImm(), Size);
else {
- unsigned rt = Is64BitMode ? X86::reloc_pcrel_word : X86::reloc_absolute_word;
+ unsigned rt = Is64BitMode ? X86::reloc_pcrel_word
+ : X86::reloc_absolute_word;
+ if (Opcode == X86::MOV64mi32)
+ rt = X86::reloc_absolute_word; // FIXME: add X86II flag?
if (MO.isGlobalAddress())
emitGlobalAddressForPtr(MO.getGlobal(), rt, MO.getOffset());
else if (MO.isExternalSymbol())