diff --git a/lib/Target/X86/X86MCCodeEmitter.cpp b/lib/Target/X86/X86MCCodeEmitter.cpp index 0578c6d8c88..d5613b2dda9 100644 --- a/lib/Target/X86/X86MCCodeEmitter.cpp +++ b/lib/Target/X86/X86MCCodeEmitter.cpp @@ -13,23 +13,31 @@ #define DEBUG_TYPE "x86-emitter" #include "X86.h" -#include "X86TargetMachine.h" +#include "X86InstrInfo.h" #include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCInst.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; namespace { class X86MCCodeEmitter : public MCCodeEmitter { X86MCCodeEmitter(const X86MCCodeEmitter &); // DO NOT IMPLEMENT void operator=(const X86MCCodeEmitter &); // DO NOT IMPLEMENT - X86TargetMachine &TM; + const TargetMachine &TM; + const TargetInstrInfo &TII; public: - X86MCCodeEmitter(X86TargetMachine &tm) : TM(tm) { + X86MCCodeEmitter(TargetMachine &tm) + : TM(tm), TII(*TM.getInstrInfo()) { } ~X86MCCodeEmitter() {} - void EncodeInstruction(const MCInst &MI, raw_ostream &OS) const { + void EmitByte(unsigned char C, raw_ostream &OS) const { + OS << (char)C; } + + void EncodeInstruction(const MCInst &MI, raw_ostream &OS) const; + }; } // end anonymous namespace @@ -37,5 +45,31 @@ public: MCCodeEmitter *llvm::createX86MCCodeEmitter(const Target &, TargetMachine &TM) { - return new X86MCCodeEmitter(static_cast(TM)); + return new X86MCCodeEmitter(TM); +} + + + +void X86MCCodeEmitter:: +EncodeInstruction(const MCInst &MI, raw_ostream &OS) const { + unsigned Opcode = MI.getOpcode(); + const TargetInstrDesc &Desc = TII.get(Opcode); + + // Emit the lock opcode prefix as needed. + if (Desc.TSFlags & X86II::LOCK) + EmitByte(0xF0, OS); + + // Emit segment override opcode prefix as needed. + switch (Desc.TSFlags & X86II::SegOvrMask) { + default: assert(0 && "Invalid segment!"); + case 0: break; // No segment override! + case X86II::FS: + EmitByte(0x64, OS); + break; + case X86II::GS: + EmitByte(0x65, OS); + break; + } + + }