summaryrefslogtreecommitdiffstats
path: root/lib/Target/X86/X86CodeEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/X86/X86CodeEmitter.cpp')
-rw-r--r--lib/Target/X86/X86CodeEmitter.cpp526
1 files changed, 147 insertions, 379 deletions
diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp
index 828e872..8deadf6 100644
--- a/lib/Target/X86/X86CodeEmitter.cpp
+++ b/lib/Target/X86/X86CodeEmitter.cpp
@@ -21,9 +21,7 @@
#include "X86.h"
#include "llvm/LLVMContext.h"
#include "llvm/PassManager.h"
-#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/CodeGen/JITCodeEmitter.h"
-#include "llvm/CodeGen/ObjectCodeEmitter.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
@@ -110,19 +108,10 @@ template<class CodeEmitter>
/// createX86CodeEmitterPass - Return a pass that emits the collected X86 code
/// to the specified templated MachineCodeEmitter object.
-
-FunctionPass *llvm::createX86CodeEmitterPass(X86TargetMachine &TM,
- MachineCodeEmitter &MCE) {
- return new Emitter<MachineCodeEmitter>(TM, MCE);
-}
FunctionPass *llvm::createX86JITCodeEmitterPass(X86TargetMachine &TM,
JITCodeEmitter &JCE) {
return new Emitter<JITCodeEmitter>(TM, JCE);
}
-FunctionPass *llvm::createX86ObjectCodeEmitterPass(X86TargetMachine &TM,
- ObjectCodeEmitter &OCE) {
- return new Emitter<ObjectCodeEmitter>(TM, OCE);
-}
template<class CodeEmitter>
bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) {
@@ -202,8 +191,15 @@ template<class CodeEmitter>
void Emitter<CodeEmitter>::emitExternalSymbolAddress(const char *ES,
unsigned Reloc) {
intptr_t RelocCST = (Reloc == X86::reloc_picrel_word) ? PICBaseOffset : 0;
+
+ // X86 never needs stubs because instruction selection will always pick
+ // an instruction sequence that is large enough to hold any address
+ // to a symbol.
+ // (see X86ISelLowering.cpp, near 2039: X86TargetLowering::LowerCall)
+ bool NeedStub = false;
MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
- Reloc, ES, RelocCST));
+ Reloc, ES, RelocCST,
+ 0, NeedStub));
if (Reloc == X86::reloc_absolute_dword)
MCE.emitDWordLE(0);
else
@@ -253,7 +249,7 @@ void Emitter<CodeEmitter>::emitJumpTableAddress(unsigned JTI, unsigned Reloc,
template<class CodeEmitter>
unsigned Emitter<CodeEmitter>::getX86RegNum(unsigned RegNo) const {
- return II->getRegisterInfo().getX86RegNum(RegNo);
+ return X86RegisterInfo::getX86RegNum(RegNo);
}
inline static unsigned char ModRMByte(unsigned Mod, unsigned RegOpcode,
@@ -391,86 +387,103 @@ void Emitter<CodeEmitter>::emitMemModRMByte(const MachineInstr &MI,
// If no BaseReg, issue a RIP relative instruction only if the MCE can
// resolve addresses on-the-fly, otherwise use SIB (Intel Manual 2A, table
// 2-7) and absolute references.
- if ((!Is64BitMode || DispForReloc || BaseReg != 0) &&
+ unsigned BaseRegNo = -1U;
+ if (BaseReg != 0 && BaseReg != X86::RIP)
+ BaseRegNo = getX86RegNum(BaseReg);
+
+ if (// The SIB byte must be used if there is an index register.
IndexReg.getReg() == 0 &&
- ((BaseReg == 0 && MCE.earlyResolveAddresses()) || BaseReg == X86::RIP ||
- (BaseReg != 0 && getX86RegNum(BaseReg) != N86::ESP))) {
- if (BaseReg == 0 || BaseReg == X86::RIP) { // Just a displacement?
- // Emit special case [disp32] encoding
+ // The SIB byte must be used if the base is ESP/RSP/R12, all of which
+ // encode to an R/M value of 4, which indicates that a SIB byte is
+ // present.
+ BaseRegNo != N86::ESP &&
+ // If there is no base register and we're in 64-bit mode, we need a SIB
+ // byte to emit an addr that is just 'disp32' (the non-RIP relative form).
+ (!Is64BitMode || BaseReg != 0)) {
+ if (BaseReg == 0 || // [disp32] in X86-32 mode
+ BaseReg == X86::RIP) { // [disp32+RIP] in X86-64 mode
MCE.emitByte(ModRMByte(0, RegOpcodeField, 5));
emitDisplacementField(DispForReloc, DispVal, PCAdj, true);
- } else {
- unsigned BaseRegNo = getX86RegNum(BaseReg);
- if (!DispForReloc && DispVal == 0 && BaseRegNo != N86::EBP) {
- // Emit simple indirect register encoding... [EAX] f.e.
- MCE.emitByte(ModRMByte(0, RegOpcodeField, BaseRegNo));
- } else if (!DispForReloc && isDisp8(DispVal)) {
- // Emit the disp8 encoding... [REG+disp8]
- MCE.emitByte(ModRMByte(1, RegOpcodeField, BaseRegNo));
- emitConstant(DispVal, 1);
- } else {
- // Emit the most general non-SIB encoding: [REG+disp32]
- MCE.emitByte(ModRMByte(2, RegOpcodeField, BaseRegNo));
- emitDisplacementField(DispForReloc, DispVal, PCAdj, IsPCRel);
- }
+ return;
}
-
- } else { // We need a SIB byte, so start by outputting the ModR/M byte first
- assert(IndexReg.getReg() != X86::ESP &&
- IndexReg.getReg() != X86::RSP && "Cannot use ESP as index reg!");
-
- bool ForceDisp32 = false;
- bool ForceDisp8 = false;
- if (BaseReg == 0) {
- // If there is no base register, we emit the special case SIB byte with
- // MOD=0, BASE=5, to JUST get the index, scale, and displacement.
- MCE.emitByte(ModRMByte(0, RegOpcodeField, 4));
- ForceDisp32 = true;
- } else if (DispForReloc) {
- // Emit the normal disp32 encoding.
- MCE.emitByte(ModRMByte(2, RegOpcodeField, 4));
- ForceDisp32 = true;
- } else if (DispVal == 0 && getX86RegNum(BaseReg) != N86::EBP) {
- // Emit no displacement ModR/M byte
- MCE.emitByte(ModRMByte(0, RegOpcodeField, 4));
- } else if (isDisp8(DispVal)) {
- // Emit the disp8 encoding...
- MCE.emitByte(ModRMByte(1, RegOpcodeField, 4));
- ForceDisp8 = true; // Make sure to force 8 bit disp if Base=EBP
- } else {
- // Emit the normal disp32 encoding...
- MCE.emitByte(ModRMByte(2, RegOpcodeField, 4));
- }
-
- // Calculate what the SS field value should be...
- static const unsigned SSTable[] = { ~0, 0, 1, ~0, 2, ~0, ~0, ~0, 3 };
- unsigned SS = SSTable[Scale.getImm()];
-
- if (BaseReg == 0) {
- // Handle the SIB byte for the case where there is no base, see Intel
- // Manual 2A, table 2-7. The displacement has already been output.
- unsigned IndexRegNo;
- if (IndexReg.getReg())
- IndexRegNo = getX86RegNum(IndexReg.getReg());
- else // Examples: [ESP+1*<noreg>+4] or [scaled idx]+disp32 (MOD=0,BASE=5)
- IndexRegNo = 4;
- emitSIBByte(SS, IndexRegNo, 5);
- } else {
- unsigned BaseRegNo = getX86RegNum(BaseReg);
- unsigned IndexRegNo;
- if (IndexReg.getReg())
- IndexRegNo = getX86RegNum(IndexReg.getReg());
- else
- IndexRegNo = 4; // For example [ESP+1*<noreg>+4]
- emitSIBByte(SS, IndexRegNo, BaseRegNo);
+
+ // If the base is not EBP/ESP and there is no displacement, use simple
+ // indirect register encoding, this handles addresses like [EAX]. The
+ // encoding for [EBP] with no displacement means [disp32] so we handle it
+ // by emitting a displacement of 0 below.
+ if (!DispForReloc && DispVal == 0 && BaseRegNo != N86::EBP) {
+ MCE.emitByte(ModRMByte(0, RegOpcodeField, BaseRegNo));
+ return;
}
-
- // Do we need to output a displacement?
- if (ForceDisp8) {
+
+ // Otherwise, if the displacement fits in a byte, encode as [REG+disp8].
+ if (!DispForReloc && isDisp8(DispVal)) {
+ MCE.emitByte(ModRMByte(1, RegOpcodeField, BaseRegNo));
emitConstant(DispVal, 1);
- } else if (DispVal != 0 || ForceDisp32) {
- emitDisplacementField(DispForReloc, DispVal, PCAdj, IsPCRel);
+ return;
}
+
+ // Otherwise, emit the most general non-SIB encoding: [REG+disp32]
+ MCE.emitByte(ModRMByte(2, RegOpcodeField, BaseRegNo));
+ emitDisplacementField(DispForReloc, DispVal, PCAdj, IsPCRel);
+ return;
+ }
+
+ // Otherwise we need a SIB byte, so start by outputting the ModR/M byte first.
+ assert(IndexReg.getReg() != X86::ESP &&
+ IndexReg.getReg() != X86::RSP && "Cannot use ESP as index reg!");
+
+ bool ForceDisp32 = false;
+ bool ForceDisp8 = false;
+ if (BaseReg == 0) {
+ // If there is no base register, we emit the special case SIB byte with
+ // MOD=0, BASE=4, to JUST get the index, scale, and displacement.
+ MCE.emitByte(ModRMByte(0, RegOpcodeField, 4));
+ ForceDisp32 = true;
+ } else if (DispForReloc) {
+ // Emit the normal disp32 encoding.
+ MCE.emitByte(ModRMByte(2, RegOpcodeField, 4));
+ ForceDisp32 = true;
+ } else if (DispVal == 0 && getX86RegNum(BaseReg) != N86::EBP) {
+ // Emit no displacement ModR/M byte
+ MCE.emitByte(ModRMByte(0, RegOpcodeField, 4));
+ } else if (isDisp8(DispVal)) {
+ // Emit the disp8 encoding...
+ MCE.emitByte(ModRMByte(1, RegOpcodeField, 4));
+ ForceDisp8 = true; // Make sure to force 8 bit disp if Base=EBP
+ } else {
+ // Emit the normal disp32 encoding...
+ MCE.emitByte(ModRMByte(2, RegOpcodeField, 4));
+ }
+
+ // Calculate what the SS field value should be...
+ static const unsigned SSTable[] = { ~0, 0, 1, ~0, 2, ~0, ~0, ~0, 3 };
+ unsigned SS = SSTable[Scale.getImm()];
+
+ if (BaseReg == 0) {
+ // Handle the SIB byte for the case where there is no base, see Intel
+ // Manual 2A, table 2-7. The displacement has already been output.
+ unsigned IndexRegNo;
+ if (IndexReg.getReg())
+ IndexRegNo = getX86RegNum(IndexReg.getReg());
+ else // Examples: [ESP+1*<noreg>+4] or [scaled idx]+disp32 (MOD=0,BASE=5)
+ IndexRegNo = 4;
+ emitSIBByte(SS, IndexRegNo, 5);
+ } else {
+ unsigned BaseRegNo = getX86RegNum(BaseReg);
+ unsigned IndexRegNo;
+ if (IndexReg.getReg())
+ IndexRegNo = getX86RegNum(IndexReg.getReg());
+ else
+ IndexRegNo = 4; // For example [ESP+1*<noreg>+4]
+ emitSIBByte(SS, IndexRegNo, BaseRegNo);
+ }
+
+ // Do we need to output a displacement?
+ if (ForceDisp8) {
+ emitConstant(DispVal, 1);
+ } else if (DispVal != 0 || ForceDisp32) {
+ emitDisplacementField(DispForReloc, DispVal, PCAdj, IsPCRel);
}
}
@@ -570,7 +583,7 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
// Skip the last source operand that is tied_to the dest reg. e.g. LXADD32
--NumOps;
- unsigned char BaseOpcode = II->getBaseOpcodeFor(Desc);
+ unsigned char BaseOpcode = X86II::getBaseOpcodeFor(Desc->TSFlags);
switch (Desc->TSFlags & X86II::FormMask) {
default:
llvm_unreachable("Unknown FormMask value in X86 MachineCodeEmitter!");
@@ -582,25 +595,25 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
llvm_unreachable("psuedo instructions should be removed before code"
" emission");
break;
- case TargetInstrInfo::INLINEASM:
+ 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])
llvm_report_error("JIT does not support inline asm!");
break;
- case TargetInstrInfo::DBG_LABEL:
- case TargetInstrInfo::EH_LABEL:
- case TargetInstrInfo::GC_LABEL:
+ case TargetOpcode::DBG_LABEL:
+ case TargetOpcode::EH_LABEL:
+ case TargetOpcode::GC_LABEL:
MCE.emitLabel(MI.getOperand(0).getImm());
break;
- case TargetInstrInfo::IMPLICIT_DEF:
- case TargetInstrInfo::KILL:
+ case TargetOpcode::IMPLICIT_DEF:
+ case TargetOpcode::KILL:
case X86::FP_REG_KILL:
break;
case X86::MOVPC32r: {
// This emits the "call" portion of this pseudo instruction.
MCE.emitByte(BaseOpcode);
- emitConstant(0, X86InstrInfo::sizeOfImm(Desc));
+ emitConstant(0, X86II::getSizeOfImm(Desc->TSFlags));
// Remember PIC base.
PICBaseOffset = (intptr_t) MCE.getCurrentPCOffset();
X86JITInfo *JTI = TM.getJITInfo();
@@ -639,15 +652,21 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
emitExternalSymbolAddress(MO.getSymbolName(), X86::reloc_pcrel_word);
break;
}
+
+ // FIXME: Only used by hackish MCCodeEmitter, remove when dead.
+ if (MO.isJTI()) {
+ emitJumpTableAddress(MO.getIndex(), X86::reloc_pcrel_word);
+ break;
+ }
assert(MO.isImm() && "Unknown RawFrm operand!");
if (Opcode == X86::CALLpcrel32 || Opcode == X86::CALL64pcrel32) {
// Fix up immediate operand for pc relative calls.
intptr_t Imm = (intptr_t)MO.getImm();
Imm = Imm - MCE.getCurrentPCValue() - 4;
- emitConstant(Imm, X86InstrInfo::sizeOfImm(Desc));
+ emitConstant(Imm, X86II::getSizeOfImm(Desc->TSFlags));
} else
- emitConstant(MO.getImm(), X86InstrInfo::sizeOfImm(Desc));
+ emitConstant(MO.getImm(), X86II::getSizeOfImm(Desc->TSFlags));
break;
}
@@ -658,7 +677,7 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
break;
const MachineOperand &MO1 = MI.getOperand(CurOp++);
- unsigned Size = X86InstrInfo::sizeOfImm(Desc);
+ unsigned Size = X86II::getSizeOfImm(Desc->TSFlags);
if (MO1.isImm()) {
emitConstant(MO1.getImm(), Size);
break;
@@ -691,7 +710,7 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
CurOp += 2;
if (CurOp != NumOps)
emitConstant(MI.getOperand(CurOp++).getImm(),
- X86InstrInfo::sizeOfImm(Desc));
+ X86II::getSizeOfImm(Desc->TSFlags));
break;
}
case X86II::MRMDestMem: {
@@ -702,7 +721,7 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
CurOp += X86AddrNumOperands + 1;
if (CurOp != NumOps)
emitConstant(MI.getOperand(CurOp++).getImm(),
- X86InstrInfo::sizeOfImm(Desc));
+ X86II::getSizeOfImm(Desc->TSFlags));
break;
}
@@ -713,7 +732,7 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
CurOp += 2;
if (CurOp != NumOps)
emitConstant(MI.getOperand(CurOp++).getImm(),
- X86InstrInfo::sizeOfImm(Desc));
+ X86II::getSizeOfImm(Desc->TSFlags));
break;
case X86II::MRMSrcMem: {
@@ -726,7 +745,7 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
AddrOperands = X86AddrNumOperands;
intptr_t PCAdj = (CurOp + AddrOperands + 1 != NumOps) ?
- X86InstrInfo::sizeOfImm(Desc) : 0;
+ X86II::getSizeOfImm(Desc->TSFlags) : 0;
MCE.emitByte(BaseOpcode);
emitMemModRMByte(MI, CurOp+1, getX86RegNum(MI.getOperand(CurOp).getReg()),
@@ -734,7 +753,7 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
CurOp += AddrOperands + 1;
if (CurOp != NumOps)
emitConstant(MI.getOperand(CurOp++).getImm(),
- X86InstrInfo::sizeOfImm(Desc));
+ X86II::getSizeOfImm(Desc->TSFlags));
break;
}
@@ -743,33 +762,14 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
case X86II::MRM4r: case X86II::MRM5r:
case X86II::MRM6r: case X86II::MRM7r: {
MCE.emitByte(BaseOpcode);
-
- // Special handling of lfence, mfence, monitor, and mwait.
- if (Desc->getOpcode() == X86::LFENCE ||
- Desc->getOpcode() == X86::MFENCE ||
- Desc->getOpcode() == X86::MONITOR ||
- Desc->getOpcode() == X86::MWAIT) {
- emitRegModRMByte((Desc->TSFlags & X86II::FormMask)-X86II::MRM0r);
-
- switch (Desc->getOpcode()) {
- default: break;
- case X86::MONITOR:
- MCE.emitByte(0xC8);
- break;
- case X86::MWAIT:
- MCE.emitByte(0xC9);
- break;
- }
- } else {
- emitRegModRMByte(MI.getOperand(CurOp++).getReg(),
- (Desc->TSFlags & X86II::FormMask)-X86II::MRM0r);
- }
+ emitRegModRMByte(MI.getOperand(CurOp++).getReg(),
+ (Desc->TSFlags & X86II::FormMask)-X86II::MRM0r);
if (CurOp == NumOps)
break;
const MachineOperand &MO1 = MI.getOperand(CurOp++);
- unsigned Size = X86InstrInfo::sizeOfImm(Desc);
+ unsigned Size = X86II::getSizeOfImm(Desc->TSFlags);
if (MO1.isImm()) {
emitConstant(MO1.getImm(), Size);
break;
@@ -798,7 +798,7 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
case X86II::MRM6m: case X86II::MRM7m: {
intptr_t PCAdj = (CurOp + X86AddrNumOperands != NumOps) ?
(MI.getOperand(CurOp+X86AddrNumOperands).isImm() ?
- X86InstrInfo::sizeOfImm(Desc) : 4) : 0;
+ X86II::getSizeOfImm(Desc->TSFlags) : 4) : 0;
MCE.emitByte(BaseOpcode);
emitMemModRMByte(MI, CurOp, (Desc->TSFlags & X86II::FormMask)-X86II::MRM0m,
@@ -809,7 +809,7 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
break;
const MachineOperand &MO = MI.getOperand(CurOp++);
- unsigned Size = X86InstrInfo::sizeOfImm(Desc);
+ unsigned Size = X86II::getSizeOfImm(Desc->TSFlags);
if (MO.isImm()) {
emitConstant(MO.getImm(), Size);
break;
@@ -839,6 +839,27 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
getX86RegNum(MI.getOperand(CurOp).getReg()));
++CurOp;
break;
+
+ case X86II::MRM_C1:
+ MCE.emitByte(BaseOpcode);
+ MCE.emitByte(0xC1);
+ break;
+ case X86II::MRM_C8:
+ MCE.emitByte(BaseOpcode);
+ MCE.emitByte(0xC8);
+ break;
+ case X86II::MRM_C9:
+ MCE.emitByte(BaseOpcode);
+ MCE.emitByte(0xC9);
+ break;
+ case X86II::MRM_E8:
+ MCE.emitByte(BaseOpcode);
+ MCE.emitByte(0xE8);
+ break;
+ case X86II::MRM_F0:
+ MCE.emitByte(BaseOpcode);
+ MCE.emitByte(0xF0);
+ break;
}
if (!Desc->isVariadic() && CurOp != NumOps) {
@@ -850,256 +871,3 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
MCE.processDebugLoc(MI.getDebugLoc(), false);
}
-
-// Adapt the Emitter / CodeEmitter interfaces to MCCodeEmitter.
-//
-// FIXME: This is a total hack designed to allow work on llvm-mc to proceed
-// without being blocked on various cleanups needed to support a clean interface
-// to instruction encoding.
-//
-// Look away!
-
-#include "llvm/DerivedTypes.h"
-
-namespace {
-class MCSingleInstructionCodeEmitter : public MachineCodeEmitter {
- uint8_t Data[256];
-
-public:
- MCSingleInstructionCodeEmitter() { reset(); }
-
- void reset() {
- BufferBegin = Data;
- BufferEnd = array_endof(Data);
- CurBufferPtr = Data;
- }
-
- StringRef str() {
- return StringRef(reinterpret_cast<char*>(BufferBegin),
- CurBufferPtr - BufferBegin);
- }
-
- virtual void startFunction(MachineFunction &F) {}
- virtual bool finishFunction(MachineFunction &F) { return false; }
- virtual void emitLabel(uint64_t LabelID) {}
- virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {}
- virtual bool earlyResolveAddresses() const { return false; }
- virtual void addRelocation(const MachineRelocation &MR) { }
- virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
- return 0;
- }
- virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const {
- return 0;
- }
- virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
- return 0;
- }
- virtual uintptr_t getLabelAddress(uint64_t LabelID) const {
- return 0;
- }
- virtual void setModuleInfo(MachineModuleInfo* Info) {}
-};
-
-class X86MCCodeEmitter : public MCCodeEmitter {
- X86MCCodeEmitter(const X86MCCodeEmitter &); // DO NOT IMPLEMENT
- void operator=(const X86MCCodeEmitter &); // DO NOT IMPLEMENT
-
-private:
- X86TargetMachine &TM;
- llvm::Function *DummyF;
- TargetData *DummyTD;
- mutable llvm::MachineFunction *DummyMF;
- llvm::MachineBasicBlock *DummyMBB;
-
- MCSingleInstructionCodeEmitter *InstrEmitter;
- Emitter<MachineCodeEmitter> *Emit;
-
-public:
- X86MCCodeEmitter(X86TargetMachine &_TM) : TM(_TM) {
- // Verily, thou shouldst avert thine eyes.
- const llvm::FunctionType *FTy =
- FunctionType::get(llvm::Type::getVoidTy(getGlobalContext()), false);
- DummyF = Function::Create(FTy, GlobalValue::InternalLinkage);
- DummyTD = new TargetData("");
- DummyMF = new MachineFunction(DummyF, TM);
- DummyMBB = DummyMF->CreateMachineBasicBlock();
-
- InstrEmitter = new MCSingleInstructionCodeEmitter();
- Emit = new Emitter<MachineCodeEmitter>(TM, *InstrEmitter,
- *TM.getInstrInfo(),
- *DummyTD, false);
- }
- ~X86MCCodeEmitter() {
- delete Emit;
- delete InstrEmitter;
- delete DummyMF;
- delete DummyF;
- }
-
- bool AddRegToInstr(const MCInst &MI, MachineInstr *Instr,
- unsigned Start) const {
- if (Start + 1 > MI.getNumOperands())
- return false;
-
- const MCOperand &Op = MI.getOperand(Start);
- if (!Op.isReg()) return false;
-
- Instr->addOperand(MachineOperand::CreateReg(Op.getReg(), false));
- return true;
- }
-
- bool AddImmToInstr(const MCInst &MI, MachineInstr *Instr,
- unsigned Start) const {
- if (Start + 1 > MI.getNumOperands())
- return false;
-
- const MCOperand &Op = MI.getOperand(Start);
- if (Op.isImm()) {
- Instr->addOperand(MachineOperand::CreateImm(Op.getImm()));
- return true;
- }
- if (!Op.isExpr())
- return false;
-
- const MCExpr *Expr = Op.getExpr();
- if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) {
- Instr->addOperand(MachineOperand::CreateImm(CE->getValue()));
- return true;
- }
-
- // FIXME: Relocation / fixup.
- Instr->addOperand(MachineOperand::CreateImm(0));
- return true;
- }
-
- bool AddLMemToInstr(const MCInst &MI, MachineInstr *Instr,
- unsigned Start) const {
- return (AddRegToInstr(MI, Instr, Start + 0) &&
- AddImmToInstr(MI, Instr, Start + 1) &&
- AddRegToInstr(MI, Instr, Start + 2) &&
- AddImmToInstr(MI, Instr, Start + 3));
- }
-
- bool AddMemToInstr(const MCInst &MI, MachineInstr *Instr,
- unsigned Start) const {
- return (AddRegToInstr(MI, Instr, Start + 0) &&
- AddImmToInstr(MI, Instr, Start + 1) &&
- AddRegToInstr(MI, Instr, Start + 2) &&
- AddImmToInstr(MI, Instr, Start + 3) &&
- AddRegToInstr(MI, Instr, Start + 4));
- }
-
- void EncodeInstruction(const MCInst &MI, raw_ostream &OS) const {
- // Don't look yet!
-
- // Convert the MCInst to a MachineInstr so we can (ab)use the regular
- // emitter.
- const X86InstrInfo &II = *TM.getInstrInfo();
- const TargetInstrDesc &Desc = II.get(MI.getOpcode());
- MachineInstr *Instr = DummyMF->CreateMachineInstr(Desc, DebugLoc());
- DummyMBB->push_back(Instr);
-
- unsigned Opcode = MI.getOpcode();
- unsigned NumOps = MI.getNumOperands();
- unsigned CurOp = 0;
- if (NumOps > 1 && Desc.getOperandConstraint(1, TOI::TIED_TO) != -1) {
- Instr->addOperand(MachineOperand::CreateReg(0, false));
- ++CurOp;
- } else if (NumOps > 2 &&
- Desc.getOperandConstraint(NumOps-1, TOI::TIED_TO)== 0)
- // Skip the last source operand that is tied_to the dest reg. e.g. LXADD32
- --NumOps;
-
- bool OK = true;
- switch (Desc.TSFlags & X86II::FormMask) {
- case X86II::MRMDestReg:
- case X86II::MRMSrcReg:
- // Matching doesn't fill this in completely, we have to choose operand 0
- // for a tied register.
- OK &= AddRegToInstr(MI, Instr, 0); CurOp++;
- OK &= AddRegToInstr(MI, Instr, CurOp++);
- if (CurOp < NumOps)
- OK &= AddImmToInstr(MI, Instr, CurOp);
- break;
-
- case X86II::RawFrm:
- if (CurOp < NumOps) {
- // Hack to make branches work.
- if (!(Desc.TSFlags & X86II::ImmMask) &&
- MI.getOperand(0).isExpr() &&
- isa<MCSymbolRefExpr>(MI.getOperand(0).getExpr()))
- Instr->addOperand(MachineOperand::CreateMBB(DummyMBB));
- else
- OK &= AddImmToInstr(MI, Instr, CurOp);
- }
- break;
-
- case X86II::AddRegFrm:
- OK &= AddRegToInstr(MI, Instr, CurOp++);
- if (CurOp < NumOps)
- OK &= AddImmToInstr(MI, Instr, CurOp);
- break;
-
- case X86II::MRM0r: case X86II::MRM1r:
- case X86II::MRM2r: case X86II::MRM3r:
- case X86II::MRM4r: case X86II::MRM5r:
- case X86II::MRM6r: case X86II::MRM7r:
- // Matching doesn't fill this in completely, we have to choose operand 0
- // for a tied register.
- OK &= AddRegToInstr(MI, Instr, 0); CurOp++;
- if (CurOp < NumOps)
- OK &= AddImmToInstr(MI, Instr, CurOp);
- break;
-
- case X86II::MRM0m: case X86II::MRM1m:
- case X86II::MRM2m: case X86II::MRM3m:
- case X86II::MRM4m: case X86II::MRM5m:
- case X86II::MRM6m: case X86II::MRM7m:
- OK &= AddMemToInstr(MI, Instr, CurOp); CurOp += 5;
- if (CurOp < NumOps)
- OK &= AddImmToInstr(MI, Instr, CurOp);
- break;
-
- case X86II::MRMSrcMem:
- OK &= AddRegToInstr(MI, Instr, CurOp++);
- if (Opcode == X86::LEA64r || Opcode == X86::LEA64_32r ||
- Opcode == X86::LEA16r || Opcode == X86::LEA32r)
- OK &= AddLMemToInstr(MI, Instr, CurOp);
- else
- OK &= AddMemToInstr(MI, Instr, CurOp);
- break;
-
- case X86II::MRMDestMem:
- OK &= AddMemToInstr(MI, Instr, CurOp); CurOp += 5;
- OK &= AddRegToInstr(MI, Instr, CurOp);
- break;
-
- default:
- case X86II::MRMInitReg:
- case X86II::Pseudo:
- OK = false;
- break;
- }
-
- if (!OK) {
- dbgs() << "couldn't convert inst '";
- MI.dump();
- dbgs() << "' to machine instr:\n";
- Instr->dump();
- }
-
- InstrEmitter->reset();
- if (OK)
- Emit->emitInstruction(*Instr, &Desc);
- OS << InstrEmitter->str();
-
- Instr->eraseFromParent();
- }
-};
-}
-
-// Ok, now you can look.
-MCCodeEmitter *llvm::createX86MCCodeEmitter(const Target &,
- TargetMachine &TM) {
- return new X86MCCodeEmitter(static_cast<X86TargetMachine&>(TM));
-}
OpenPOWER on IntegriCloud