X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FTarget%2FX86%2FMCTargetDesc%2FX86MCCodeEmitter.cpp;h=52d6d14a8f81b1a1e18e459d6cde79c4e3ca4c74;hb=93f81d9b33bf5f01c113b1558962a5112b987092;hp=ac72fce032fd67386af41b20f945bbd316fc5e13;hpb=db9fa461d7d9643a1b25f13df73638be9c36cafb;p=oota-llvm.git diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index ac72fce032f..52d6d14a8f8 100644 --- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -32,39 +32,35 @@ class X86MCCodeEmitter : public MCCodeEmitter { X86MCCodeEmitter(const X86MCCodeEmitter &) LLVM_DELETED_FUNCTION; void operator=(const X86MCCodeEmitter &) LLVM_DELETED_FUNCTION; const MCInstrInfo &MCII; - const MCSubtargetInfo &STI; MCContext &Ctx; public: - X86MCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti, - MCContext &ctx) - : MCII(mcii), STI(sti), Ctx(ctx) { + X86MCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx) + : MCII(mcii), Ctx(ctx) { } ~X86MCCodeEmitter() {} - bool is64BitMode() const { - // FIXME: Can tablegen auto-generate this? + bool is64BitMode(const MCSubtargetInfo &STI) const { return (STI.getFeatureBits() & X86::Mode64Bit) != 0; } - bool is32BitMode() const { - // FIXME: Can tablegen auto-generate this? + bool is32BitMode(const MCSubtargetInfo &STI) const { return (STI.getFeatureBits() & X86::Mode32Bit) != 0; } - bool is16BitMode() const { - // FIXME: Can tablegen auto-generate this? + bool is16BitMode(const MCSubtargetInfo &STI) const { return (STI.getFeatureBits() & X86::Mode16Bit) != 0; } /// Is16BitMemOperand - Return true if the specified instruction has /// a 16-bit memory operand. Op specifies the operand # of the memoperand. - bool Is16BitMemOperand(const MCInst &MI, unsigned Op) const { + bool Is16BitMemOperand(const MCInst &MI, unsigned Op, + const MCSubtargetInfo &STI) const { const MCOperand &BaseReg = MI.getOperand(Op+X86::AddrBaseReg); const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg); const MCOperand &Disp = MI.getOperand(Op+X86::AddrDisp); - if (is16BitMode() && BaseReg.getReg() == 0 && + if (is16BitMode(STI) && BaseReg.getReg() == 0 && Disp.isImm() && Disp.getImm() < 0x10000) return true; if ((BaseReg.getReg() != 0 && @@ -149,10 +145,12 @@ public: void EmitMemModRMByte(const MCInst &MI, unsigned Op, unsigned RegOpcodeField, uint64_t TSFlags, unsigned &CurByte, raw_ostream &OS, - SmallVectorImpl &Fixups) const; + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; void EncodeInstruction(const MCInst &MI, raw_ostream &OS, - SmallVectorImpl &Fixups) const; + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; void EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand, const MCInst &MI, const MCInstrDesc &Desc, @@ -163,6 +161,7 @@ public: void EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand, const MCInst &MI, const MCInstrDesc &Desc, + const MCSubtargetInfo &STI, raw_ostream &OS) const; }; @@ -173,7 +172,7 @@ MCCodeEmitter *llvm::createX86MCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, const MCSubtargetInfo &STI, MCContext &Ctx) { - return new X86MCCodeEmitter(MCII, STI, Ctx); + return new X86MCCodeEmitter(MCII, Ctx); } /// isDisp8 - Return true if this signed displacement fits in a 8-bit @@ -234,6 +233,12 @@ static MCFixupKind getImmFixupKind(uint64_t TSFlags) { unsigned Size = X86II::getSizeOfImm(TSFlags); bool isPCRel = X86II::isImmPCRel(TSFlags); + if (X86II::isImmSigned(TSFlags)) { + switch (Size) { + default: llvm_unreachable("Unsupported signed fixup size!"); + case 4: return MCFixupKind(X86::reloc_signed_4byte); + } + } return MCFixup::getKindForSize(Size, isPCRel); } @@ -374,7 +379,8 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, unsigned RegOpcodeField, uint64_t TSFlags, unsigned &CurByte, raw_ostream &OS, - SmallVectorImpl &Fixups) const{ + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const{ const MCOperand &Disp = MI.getOperand(Op+X86::AddrDisp); const MCOperand &Base = MI.getOperand(Op+X86::AddrBaseReg); const MCOperand &Scale = MI.getOperand(Op+X86::AddrScaleAmt); @@ -384,7 +390,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, // Handle %rip relative addressing. if (BaseReg == X86::RIP) { // [disp32+RIP] in X86-64 mode - assert(is64BitMode() && "Rip-relative addressing requires 64-bit mode"); + assert(is64BitMode(STI) && "Rip-relative addressing requires 64-bit mode"); assert(IndexReg.getReg() == 0 && "Invalid rip-relative address"); EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS); @@ -412,7 +418,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, // 16-bit addressing forms of the ModR/M byte have a different encoding for // the R/M field and are far more limited in which registers can be used. - if (Is16BitMemOperand(MI, Op)) { + if (Is16BitMemOperand(MI, Op, STI)) { if (BaseReg) { // For 32-bit addressing, the row and column values in Table 2-2 are // basically the same. It's AX/CX/DX/BX/SP/BP/SI/DI in that order, with @@ -483,7 +489,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, 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)) { + (!is64BitMode(STI) || BaseReg != 0)) { if (BaseReg == 0) { // [disp32] in X86-32 mode EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS); @@ -1143,6 +1149,7 @@ void X86MCCodeEmitter::EmitSegmentOverridePrefix(unsigned &CurByte, void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand, const MCInst &MI, const MCInstrDesc &Desc, + const MCSubtargetInfo &STI, raw_ostream &OS) const { // Emit the lock opcode prefix as needed. @@ -1161,8 +1168,8 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, bool need_address_override; // The AdSize prefix is only for 32-bit and 64-bit modes. Hm, perhaps we // should introduce an AdSize16 bit instead of having seven special cases? - if ((!is16BitMode() && TSFlags & X86II::AdSize) || - (is16BitMode() && (MI.getOpcode() == X86::JECXZ_32 || + if ((!is16BitMode(STI) && TSFlags & X86II::AdSize) || + (is16BitMode(STI) && (MI.getOpcode() == X86::JECXZ_32 || MI.getOpcode() == X86::MOV8o8a || MI.getOpcode() == X86::MOV16o16a || MI.getOpcode() == X86::MOV32o32a || @@ -1172,23 +1179,23 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, need_address_override = true; } else if (MemOperand == -1) { need_address_override = false; - } else if (is64BitMode()) { - assert(!Is16BitMemOperand(MI, MemOperand)); + } else if (is64BitMode(STI)) { + assert(!Is16BitMemOperand(MI, MemOperand, STI)); need_address_override = Is32BitMemOperand(MI, MemOperand); - } else if (is32BitMode()) { + } else if (is32BitMode(STI)) { assert(!Is64BitMemOperand(MI, MemOperand)); - need_address_override = Is16BitMemOperand(MI, MemOperand); + need_address_override = Is16BitMemOperand(MI, MemOperand, STI); } else { - assert(is16BitMode()); + assert(is16BitMode(STI)); assert(!Is64BitMemOperand(MI, MemOperand)); - need_address_override = !Is16BitMemOperand(MI, MemOperand); + need_address_override = !Is16BitMemOperand(MI, MemOperand, STI); } if (need_address_override) EmitByte(0x67, CurByte, OS); // Emit the operand size opcode prefix as needed. - if (TSFlags & (is16BitMode() ? X86II::OpSize16 : X86II::OpSize)) + if (TSFlags & (is16BitMode(STI) ? X86II::OpSize16 : X86II::OpSize)) EmitByte(0x66, CurByte, OS); bool Need0FPrefix = false; @@ -1235,7 +1242,7 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, // Handle REX prefix. // FIXME: Can this come before F2 etc to simplify emission? - if (is64BitMode()) { + if (is64BitMode(STI)) { if (unsigned REX = DetermineREXPrefix(MI, TSFlags, Desc)) EmitByte(0x40 | REX, CurByte, OS); } @@ -1268,7 +1275,8 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, void X86MCCodeEmitter:: EncodeInstruction(const MCInst &MI, raw_ostream &OS, - SmallVectorImpl &Fixups) const { + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { unsigned Opcode = MI.getOpcode(); const MCInstrDesc &Desc = MCII.get(Opcode); uint64_t TSFlags = Desc.TSFlags; @@ -1302,7 +1310,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, if (MemoryOperand != -1) MemoryOperand += CurOp; if (!HasVEXPrefix) - EmitOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, OS); + EmitOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, STI, OS); else EmitVEXOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, OS); @@ -1317,19 +1325,46 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, llvm_unreachable("Unknown FormMask value in X86MCCodeEmitter!"); case X86II::Pseudo: llvm_unreachable("Pseudo instruction shouldn't be emitted"); + case X86II::RawFrmDstSrc: { + unsigned siReg = MI.getOperand(1).getReg(); + assert(((siReg == X86::SI && MI.getOperand(0).getReg() == X86::DI) || + (siReg == X86::ESI && MI.getOperand(0).getReg() == X86::EDI) || + (siReg == X86::RSI && MI.getOperand(0).getReg() == X86::RDI)) && + "SI and DI register sizes do not match"); + // Emit segment override opcode prefix as needed (not for %ds). + if (MI.getOperand(2).getReg() != X86::DS) + EmitSegmentOverridePrefix(CurByte, 2, MI, OS); + // Emit OpSize prefix as needed. + if ((!is32BitMode(STI) && siReg == X86::ESI) || + (is32BitMode(STI) && siReg == X86::SI)) + EmitByte(0x67, CurByte, OS); + CurOp += 3; // Consume operands. + EmitByte(BaseOpcode, CurByte, OS); + break; + } case X86II::RawFrmSrc: { unsigned siReg = MI.getOperand(0).getReg(); // Emit segment override opcode prefix as needed (not for %ds). if (MI.getOperand(1).getReg() != X86::DS) EmitSegmentOverridePrefix(CurByte, 1, MI, OS); // Emit OpSize prefix as needed. - if ((!is32BitMode() && siReg == X86::ESI) || - (is32BitMode() && siReg == X86::SI)) + if ((!is32BitMode(STI) && siReg == X86::ESI) || + (is32BitMode(STI) && siReg == X86::SI)) EmitByte(0x67, CurByte, OS); CurOp += 2; // Consume operands. EmitByte(BaseOpcode, CurByte, OS); break; } + case X86II::RawFrmDst: { + unsigned siReg = MI.getOperand(0).getReg(); + // Emit OpSize prefix as needed. + if ((!is32BitMode(STI) && siReg == X86::EDI) || + (is32BitMode(STI) && siReg == X86::DI)) + EmitByte(0x67, CurByte, OS); + ++CurOp; // Consume operand. + EmitByte(BaseOpcode, CurByte, OS); + break; + } case X86II::RawFrm: EmitByte(BaseOpcode, CurByte, OS); break; @@ -1390,7 +1425,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, EmitMemModRMByte(MI, CurOp, GetX86RegNum(MI.getOperand(SrcRegNum)), - TSFlags, CurByte, OS, Fixups); + TSFlags, CurByte, OS, Fixups, STI); CurOp = SrcRegNum + 1; break; @@ -1438,7 +1473,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, EmitByte(BaseOpcode, CurByte, OS); EmitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)), - TSFlags, CurByte, OS, Fixups); + TSFlags, CurByte, OS, Fixups, STI); CurOp += AddrOperands + 1; if (HasVEX_4VOp3) ++CurOp; @@ -1464,7 +1499,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, ++CurOp; EmitByte(BaseOpcode, CurByte, OS); EmitMemModRMByte(MI, CurOp, (TSFlags & X86II::FormMask)-X86II::MRM0m, - TSFlags, CurByte, OS, Fixups); + TSFlags, CurByte, OS, Fixups, STI); CurOp += X86::AddrNumOperands; break; case X86II::MRM_C1: case X86II::MRM_C2: case X86II::MRM_C3: @@ -1537,17 +1572,8 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, EmitImmediate(MCOperand::CreateImm(RegNum), MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups); } else { - unsigned FixupKind; - // FIXME: Is there a better way to know that we need a signed relocation? - if (MI.getOpcode() == X86::ADD64ri32 || - MI.getOpcode() == X86::MOV64ri32 || - MI.getOpcode() == X86::MOV64mi32 || - MI.getOpcode() == X86::PUSH64i32) - FixupKind = X86::reloc_signed_4byte; - else - FixupKind = getImmFixupKind(TSFlags); EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), - X86II::getSizeOfImm(TSFlags), MCFixupKind(FixupKind), + X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), CurByte, OS, Fixups); } }