diff --git a/llvm/include/llvm/MC/MCCodeEmitter.h b/llvm/include/llvm/MC/MCCodeEmitter.h --- a/llvm/include/llvm/MC/MCCodeEmitter.h +++ b/llvm/include/llvm/MC/MCCodeEmitter.h @@ -37,11 +37,11 @@ /// Lifetime management virtual void reset() {} - /// Emit the prefixes of given instruction on the output stream. + /// Append the prefixes of given instruction to the code buffer. /// /// \param Inst a single low-level machine instruction. - /// \param OS output stream. - virtual void emitPrefix(const MCInst &Inst, raw_ostream &OS, + /// \param CB code buffer + virtual void emitPrefix(const MCInst &Inst, SmallVectorImpl &CB, const MCSubtargetInfo &STI) const {} /// EncodeInstruction - Encode the given \p Inst to bytes and append to \p CB. virtual void encodeInstruction(const MCInst &Inst, SmallVectorImpl &CB, diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp --- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -796,8 +796,7 @@ const unsigned MaxPossiblePad = std::min(15 - OldSize, RemainingSize); const unsigned RemainingPrefixSize = [&]() -> unsigned { SmallString<15> Code; - raw_svector_ostream VecOS(Code); - Emitter.emitPrefix(RF.getInst(), VecOS, STI); + Emitter.emitPrefix(RF.getInst(), Code, STI); assert(Code.size() < 15 && "The number of prefixes must be less than 15."); // TODO: It turns out we need a decent amount of plumbing for the target diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -26,7 +26,6 @@ #include "llvm/MC/MCSymbol.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" #include #include #include @@ -39,7 +38,7 @@ enum PrefixKind { None, REX, XOP, VEX2, VEX3, EVEX }; -static void emitByte(uint8_t C, raw_ostream &OS) { OS << static_cast(C); } +static void emitByte(uint8_t C, SmallVectorImpl &CB) { CB.push_back(C); } class X86OpcodePrefixHelper { // REX (1 byte) @@ -207,7 +206,7 @@ return Kind; } - void emit(raw_ostream &OS) const { + void emit(SmallVectorImpl &CB) const { uint8_t FirstPayload = ((~R) & 0x1) << 7 | ((~X) & 0x1) << 6 | ((~B) & 0x1) << 5; uint8_t LastPayload = ((~VEX_4V) & 0xf) << 3 | VEX_L << 2 | VEX_PP; @@ -215,26 +214,26 @@ case None: return; case REX: - emitByte(0x40 | W << 3 | R << 2 | X << 1 | B, OS); + emitByte(0x40 | W << 3 | R << 2 | X << 1 | B, CB); return; case VEX2: - emitByte(0xC5, OS); - emitByte(((~R) & 1) << 7 | LastPayload, OS); + emitByte(0xC5, CB); + emitByte(((~R) & 1) << 7 | LastPayload, CB); return; case VEX3: case XOP: - emitByte(Kind == VEX3 ? 0xC4 : 0x8F, OS); - emitByte(FirstPayload | VEX_5M, OS); - emitByte(W << 7 | LastPayload, OS); + emitByte(Kind == VEX3 ? 0xC4 : 0x8F, CB); + emitByte(FirstPayload | VEX_5M, CB); + emitByte(W << 7 | LastPayload, CB); return; case EVEX: assert(VEX_5M && !(VEX_5M & 0x8) && "invalid mmm fields for EVEX!"); - emitByte(0x62, OS); - emitByte(FirstPayload | ((~EVEX_R2) & 0x1) << 4 | VEX_5M, OS); - emitByte(W << 7 | ((~VEX_4V) & 0xf) << 3 | 1 << 2 | VEX_PP, OS); + emitByte(0x62, CB); + emitByte(FirstPayload | ((~EVEX_R2) & 0x1) << 4 | VEX_5M, CB); + emitByte(W << 7 | ((~VEX_4V) & 0xf) << 3 | 1 << 2 | VEX_PP, CB); emitByte(EVEX_z << 7 | EVEX_L2 << 6 | VEX_L << 5 | EVEX_b << 4 | ((~EVEX_V2) & 0x1) << 3 | EVEX_aaa, - OS); + CB); return; } } @@ -251,10 +250,10 @@ X86MCCodeEmitter &operator=(const X86MCCodeEmitter &) = delete; ~X86MCCodeEmitter() override = default; - void emitPrefix(const MCInst &MI, raw_ostream &OS, + void emitPrefix(const MCInst &MI, SmallVectorImpl &CB, const MCSubtargetInfo &STI) const override; - void encodeInstruction(const MCInst &MI, raw_ostream &OS, + void encodeInstruction(const MCInst &MI, SmallVectorImpl &CB, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const override; @@ -264,36 +263,40 @@ unsigned getX86RegEncoding(const MCInst &MI, unsigned OpNum) const; void emitImmediate(const MCOperand &Disp, SMLoc Loc, unsigned ImmSize, - MCFixupKind FixupKind, uint64_t StartByte, raw_ostream &OS, + MCFixupKind FixupKind, uint64_t StartByte, + SmallVectorImpl &CB, SmallVectorImpl &Fixups, int ImmOffset = 0) const; void emitRegModRMByte(const MCOperand &ModRMReg, unsigned RegOpcodeFld, - raw_ostream &OS) const; + SmallVectorImpl &CB) const; void emitSIBByte(unsigned SS, unsigned Index, unsigned Base, - raw_ostream &OS) const; + SmallVectorImpl &CB) const; void emitMemModRMByte(const MCInst &MI, unsigned Op, unsigned RegOpcodeField, uint64_t TSFlags, PrefixKind Kind, uint64_t StartByte, - raw_ostream &OS, SmallVectorImpl &Fixups, + SmallVectorImpl &CB, + SmallVectorImpl &Fixups, const MCSubtargetInfo &STI, bool ForceSIB = false) const; PrefixKind emitPrefixImpl(unsigned &CurOp, const MCInst &MI, - const MCSubtargetInfo &STI, raw_ostream &OS) const; + const MCSubtargetInfo &STI, + SmallVectorImpl &CB) const; PrefixKind emitVEXOpcodePrefix(int MemOperand, const MCInst &MI, - raw_ostream &OS) const; + SmallVectorImpl &CB) const; void emitSegmentOverridePrefix(unsigned SegOperand, const MCInst &MI, - raw_ostream &OS) const; + SmallVectorImpl &CB) const; PrefixKind emitOpcodePrefix(int MemOperand, const MCInst &MI, const MCSubtargetInfo &STI, - raw_ostream &OS) const; + SmallVectorImpl &CB) const; PrefixKind emitREXPrefix(int MemOperand, const MCInst &MI, - const MCSubtargetInfo &STI, raw_ostream &OS) const; + const MCSubtargetInfo &STI, + SmallVectorImpl &CB) const; }; } // end anonymous namespace @@ -303,10 +306,11 @@ return RM | (RegOpcode << 3) | (Mod << 6); } -static void emitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) { +static void emitConstant(uint64_t Val, unsigned Size, + SmallVectorImpl &CB) { // Output the constant in little endian byte order. for (unsigned i = 0; i != Size; ++i) { - emitByte(Val & 255, OS); + emitByte(Val & 255, CB); Val >>= 8; } } @@ -416,7 +420,8 @@ void X86MCCodeEmitter::emitImmediate(const MCOperand &DispOp, SMLoc Loc, unsigned Size, MCFixupKind FixupKind, - uint64_t StartByte, raw_ostream &OS, + uint64_t StartByte, + SmallVectorImpl &CB, SmallVectorImpl &Fixups, int ImmOffset) const { const MCExpr *Expr = nullptr; @@ -425,7 +430,7 @@ // relocation, emit it now. if (FixupKind != FK_PCRel_1 && FixupKind != FK_PCRel_2 && FixupKind != FK_PCRel_4) { - emitConstant(DispOp.getImm() + ImmOffset, Size, OS); + emitConstant(DispOp.getImm() + ImmOffset, Size, CB); return; } Expr = MCConstantExpr::create(DispOp.getImm(), Ctx); @@ -448,7 +453,7 @@ } if (Kind == GOT_Normal) - ImmOffset = static_cast(OS.tell() - StartByte); + ImmOffset = static_cast(CB.size() - StartByte); } else if (Expr->getKind() == MCExpr::SymbolRef) { if (hasSecRelSymbolRef(Expr)) { FixupKind = MCFixupKind(FK_SecRel_4); @@ -487,27 +492,28 @@ Ctx); // Emit a symbolic constant as a fixup and 4 zeros. - Fixups.push_back(MCFixup::create(static_cast(OS.tell() - StartByte), + Fixups.push_back(MCFixup::create(static_cast(CB.size() - StartByte), Expr, FixupKind, Loc)); - emitConstant(0, Size, OS); + emitConstant(0, Size, CB); } void X86MCCodeEmitter::emitRegModRMByte(const MCOperand &ModRMReg, unsigned RegOpcodeFld, - raw_ostream &OS) const { - emitByte(modRMByte(3, RegOpcodeFld, getX86RegNum(ModRMReg)), OS); + SmallVectorImpl &CB) const { + emitByte(modRMByte(3, RegOpcodeFld, getX86RegNum(ModRMReg)), CB); } void X86MCCodeEmitter::emitSIBByte(unsigned SS, unsigned Index, unsigned Base, - raw_ostream &OS) const { + SmallVectorImpl &CB) const { // SIB byte is in the same format as the modRMByte. - emitByte(modRMByte(SS, Index, Base), OS); + emitByte(modRMByte(SS, Index, Base), CB); } void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op, unsigned RegOpcodeField, uint64_t TSFlags, PrefixKind Kind, - uint64_t StartByte, raw_ostream &OS, + uint64_t StartByte, + SmallVectorImpl &CB, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI, bool ForceSIB) const { @@ -524,7 +530,7 @@ "Rip-relative addressing requires 64-bit mode"); assert(IndexReg.getReg() == 0 && !ForceSIB && "Invalid rip-relative address"); - emitByte(modRMByte(0, RegOpcodeField, 5), OS); + emitByte(modRMByte(0, RegOpcodeField, 5), CB); unsigned Opcode = MI.getOpcode(); unsigned FixupKind = [&]() { @@ -582,7 +588,7 @@ ? X86II::getSizeOfImm(TSFlags) : 0; - emitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(FixupKind), StartByte, OS, + emitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(FixupKind), StartByte, CB, Fixups, -ImmSize); return; } @@ -629,24 +635,24 @@ if (Disp.isImm() && isInt<8>(Disp.getImm())) { if (Disp.getImm() == 0 && RMfield != 6) { // There is no displacement; just the register. - emitByte(modRMByte(0, RegOpcodeField, RMfield), OS); + emitByte(modRMByte(0, RegOpcodeField, RMfield), CB); return; } // Use the [REG]+disp8 form, including for [BP] which cannot be encoded. - emitByte(modRMByte(1, RegOpcodeField, RMfield), OS); - emitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, StartByte, OS, Fixups); + emitByte(modRMByte(1, RegOpcodeField, RMfield), CB); + emitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, StartByte, CB, Fixups); return; } // This is the [REG]+disp16 case. - emitByte(modRMByte(2, RegOpcodeField, RMfield), OS); + emitByte(modRMByte(2, RegOpcodeField, RMfield), CB); } else { assert(IndexReg.getReg() == 0 && "Unexpected index register!"); // There is no BaseReg; this is the plain [disp16] case. - emitByte(modRMByte(0, RegOpcodeField, 6), OS); + emitByte(modRMByte(0, RegOpcodeField, 6), CB); } // Emit 16-bit displacement for plain disp16 or [REG]+disp16 cases. - emitImmediate(Disp, MI.getLoc(), 2, FK_Data_2, StartByte, OS, Fixups); + emitImmediate(Disp, MI.getLoc(), 2, FK_Data_2, StartByte, CB, Fixups); return; } @@ -672,8 +678,8 @@ (!STI.hasFeature(X86::Is64Bit) || BaseReg != 0)) { if (BaseReg == 0) { // [disp32] in X86-32 mode - emitByte(modRMByte(0, RegOpcodeField, 5), OS); - emitImmediate(Disp, MI.getLoc(), 4, FK_Data_4, StartByte, OS, Fixups); + emitByte(modRMByte(0, RegOpcodeField, 5), CB); + emitImmediate(Disp, MI.getLoc(), 4, FK_Data_4, StartByte, CB, Fixups); return; } @@ -683,7 +689,7 @@ // handle it by emitting a displacement of 0 later. if (BaseRegNo != N86::EBP) { if (Disp.isImm() && Disp.getImm() == 0 && AllowNoDisp) { - emitByte(modRMByte(0, RegOpcodeField, BaseRegNo), OS); + emitByte(modRMByte(0, RegOpcodeField, BaseRegNo), CB); return; } @@ -694,7 +700,7 @@ // This is exclusively used by call *a@tlscall(base). The relocation // (R_386_TLSCALL or R_X86_64_TLSCALL) applies to the beginning. Fixups.push_back(MCFixup::create(0, Sym, FK_NONE, MI.getLoc())); - emitByte(modRMByte(0, RegOpcodeField, BaseRegNo), OS); + emitByte(modRMByte(0, RegOpcodeField, BaseRegNo), CB); return; } } @@ -707,8 +713,8 @@ if (Disp.isImm() && AllowDisp8) { int ImmOffset = 0; if (isDispOrCDisp8(TSFlags, Disp.getImm(), ImmOffset)) { - emitByte(modRMByte(1, RegOpcodeField, BaseRegNo), OS); - emitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, StartByte, OS, Fixups, + emitByte(modRMByte(1, RegOpcodeField, BaseRegNo), CB); + emitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, StartByte, CB, Fixups, ImmOffset); return; } @@ -717,11 +723,11 @@ // Otherwise, emit the most general non-SIB encoding: [REG+disp32]. // Displacement may be 0 for [EBP] or [R13] case if {disp32} pseudo prefix // prevented using disp8 above. - emitByte(modRMByte(2, RegOpcodeField, BaseRegNo), OS); + emitByte(modRMByte(2, RegOpcodeField, BaseRegNo), CB); unsigned Opcode = MI.getOpcode(); unsigned FixupKind = Opcode == X86::MOV32rm ? X86::reloc_signed_4byte_relax : X86::reloc_signed_4byte; - emitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(FixupKind), StartByte, OS, + emitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(FixupKind), StartByte, CB, Fixups); return; } @@ -737,7 +743,7 @@ // 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. BaseRegNo = 5; - emitByte(modRMByte(0, RegOpcodeField, 4), OS); + emitByte(modRMByte(0, RegOpcodeField, 4), CB); ForceDisp32 = true; } else if (Disp.isImm() && Disp.getImm() == 0 && AllowNoDisp && // Base reg can't be EBP/RBP/R13 as that would end up with '5' as @@ -746,17 +752,17 @@ // displacement instead. BaseRegNo != N86::EBP) { // Emit no displacement ModR/M byte - emitByte(modRMByte(0, RegOpcodeField, 4), OS); + emitByte(modRMByte(0, RegOpcodeField, 4), CB); } else if (Disp.isImm() && AllowDisp8 && isDispOrCDisp8(TSFlags, Disp.getImm(), ImmOffset)) { // Displacement fits in a byte or matches an EVEX compressed disp8, use // disp8 encoding. This also handles EBP/R13 base with 0 displacement unless // {disp32} pseudo prefix was used. - emitByte(modRMByte(1, RegOpcodeField, 4), OS); + emitByte(modRMByte(1, RegOpcodeField, 4), CB); ForceDisp8 = true; } else { // Otherwise, emit the normal disp32 encoding. - emitByte(modRMByte(2, RegOpcodeField, 4), OS); + emitByte(modRMByte(2, RegOpcodeField, 4), CB); ForceDisp32 = true; } @@ -766,15 +772,15 @@ unsigned IndexRegNo = IndexReg.getReg() ? getX86RegNum(IndexReg) : 4; - emitSIBByte(SS, IndexRegNo, BaseRegNo, OS); + emitSIBByte(SS, IndexRegNo, BaseRegNo, CB); // Do we need to output a displacement? if (ForceDisp8) - emitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, StartByte, OS, Fixups, + emitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, StartByte, CB, Fixups, ImmOffset); else if (ForceDisp32) emitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(X86::reloc_signed_4byte), - StartByte, OS, Fixups); + StartByte, CB, Fixups); } /// Emit all instruction prefixes. @@ -783,27 +789,27 @@ /// otherwise returns None. PrefixKind X86MCCodeEmitter::emitPrefixImpl(unsigned &CurOp, const MCInst &MI, const MCSubtargetInfo &STI, - raw_ostream &OS) const { + SmallVectorImpl &CB) const { uint64_t TSFlags = MCII.get(MI.getOpcode()).TSFlags; // Determine where the memory operand starts, if present. int MemoryOperand = X86II::getMemoryOperandNo(TSFlags); // Emit segment override opcode prefix as needed. if (MemoryOperand != -1) { MemoryOperand += CurOp; - emitSegmentOverridePrefix(MemoryOperand + X86::AddrSegmentReg, MI, OS); + emitSegmentOverridePrefix(MemoryOperand + X86::AddrSegmentReg, MI, CB); } // Emit the repeat opcode prefix as needed. unsigned Flags = MI.getFlags(); if (TSFlags & X86II::REP || Flags & X86::IP_HAS_REPEAT) - emitByte(0xF3, OS); + emitByte(0xF3, CB); if (Flags & X86::IP_HAS_REPEAT_NE) - emitByte(0xF2, OS); + emitByte(0xF2, CB); // Emit the address size opcode prefix as needed. if (X86_MC::needsAddressSizeOverride(MI, STI, MemoryOperand, TSFlags) || Flags & X86::IP_HAS_AD_SIZE) - emitByte(0x67, OS); + emitByte(0x67, CB); uint64_t Form = TSFlags & X86II::FormMask; switch (Form) { @@ -812,14 +818,14 @@ case X86II::RawFrmDstSrc: { // Emit segment override opcode prefix as needed (not for %ds). if (MI.getOperand(2).getReg() != X86::DS) - emitSegmentOverridePrefix(2, MI, OS); + emitSegmentOverridePrefix(2, MI, CB); CurOp += 3; // Consume operands. break; } case X86II::RawFrmSrc: { // Emit segment override opcode prefix as needed (not for %ds). if (MI.getOperand(1).getReg() != X86::DS) - emitSegmentOverridePrefix(1, MI, OS); + emitSegmentOverridePrefix(1, MI, CB); CurOp += 2; // Consume operands. break; } @@ -829,7 +835,7 @@ } case X86II::RawFrmMemOffs: { // Emit segment override opcode prefix as needed. - emitSegmentOverridePrefix(1, MI, OS); + emitSegmentOverridePrefix(1, MI, CB); break; } } @@ -837,8 +843,8 @@ // REX prefix is optional, but if used must be immediately before the opcode // Encoding type for this instruction. return (TSFlags & X86II::EncodingMask) - ? emitVEXOpcodePrefix(MemoryOperand, MI, OS) - : emitOpcodePrefix(MemoryOperand, MI, STI, OS); + ? emitVEXOpcodePrefix(MemoryOperand, MI, CB) + : emitOpcodePrefix(MemoryOperand, MI, STI, CB); } // AVX instructions are encoded using an encoding scheme that combines @@ -856,7 +862,7 @@ /// \returns the used prefix. PrefixKind X86MCCodeEmitter::emitVEXOpcodePrefix(int MemOperand, const MCInst &MI, - raw_ostream &OS) const { + SmallVectorImpl &CB) const { const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); uint64_t TSFlags = Desc.TSFlags; @@ -1144,7 +1150,7 @@ Prefix.setL2(EVEX_rc & 0x2); } PrefixKind Kind = Prefix.determineOptimalKind(); - Prefix.emit(OS); + Prefix.emit(CB); return Kind; } @@ -1156,7 +1162,7 @@ /// \returns the used prefix (REX or None). PrefixKind X86MCCodeEmitter::emitREXPrefix(int MemOperand, const MCInst &MI, const MCSubtargetInfo &STI, - raw_ostream &OS) const { + SmallVectorImpl &CB) const { if (!STI.hasFeature(X86::Is64Bit)) return None; X86OpcodePrefixHelper Prefix(*Ctx.getRegisterInfo()); @@ -1259,17 +1265,17 @@ if (Kind && UsesHighByteReg) report_fatal_error( "Cannot encode high byte register in REX-prefixed instruction"); - Prefix.emit(OS); + Prefix.emit(CB); return Kind; } /// Emit segment override opcode prefix as needed. void X86MCCodeEmitter::emitSegmentOverridePrefix(unsigned SegOperand, const MCInst &MI, - raw_ostream &OS) const { + SmallVectorImpl &CB) const { // Check for explicit segment override on memory operand. if (unsigned Reg = MI.getOperand(SegOperand).getReg()) - emitByte(X86::getSegmentOverridePrefixForReg(Reg), OS); + emitByte(X86::getSegmentOverridePrefixForReg(Reg), CB); } /// Emit all instruction prefixes prior to the opcode. @@ -1280,39 +1286,39 @@ /// \returns the used prefix (REX or None). PrefixKind X86MCCodeEmitter::emitOpcodePrefix(int MemOperand, const MCInst &MI, const MCSubtargetInfo &STI, - raw_ostream &OS) const { + SmallVectorImpl &CB) const { const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); uint64_t TSFlags = Desc.TSFlags; // Emit the operand size opcode prefix as needed. if ((TSFlags & X86II::OpSizeMask) == (STI.hasFeature(X86::Is16Bit) ? X86II::OpSize32 : X86II::OpSize16)) - emitByte(0x66, OS); + emitByte(0x66, CB); // Emit the LOCK opcode prefix. if (TSFlags & X86II::LOCK || MI.getFlags() & X86::IP_HAS_LOCK) - emitByte(0xF0, OS); + emitByte(0xF0, CB); // Emit the NOTRACK opcode prefix. if (TSFlags & X86II::NOTRACK || MI.getFlags() & X86::IP_HAS_NOTRACK) - emitByte(0x3E, OS); + emitByte(0x3E, CB); switch (TSFlags & X86II::OpPrefixMask) { case X86II::PD: // 66 - emitByte(0x66, OS); + emitByte(0x66, CB); break; case X86II::XS: // F3 - emitByte(0xF3, OS); + emitByte(0xF3, CB); break; case X86II::XD: // F2 - emitByte(0xF2, OS); + emitByte(0xF2, CB); break; } // Handle REX prefix. assert((STI.hasFeature(X86::Is64Bit) || !(TSFlags & X86II::REX_W)) && "REX.W requires 64bit mode."); - PrefixKind Kind = emitREXPrefix(MemOperand, MI, STI, OS); + PrefixKind Kind = emitREXPrefix(MemOperand, MI, STI, CB); // 0x0F escape code must be emitted just before the opcode. switch (TSFlags & X86II::OpMapMask) { @@ -1320,23 +1326,23 @@ case X86II::T8: // 0F 38 case X86II::TA: // 0F 3A case X86II::ThreeDNow: // 0F 0F, second 0F emitted by caller. - emitByte(0x0F, OS); + emitByte(0x0F, CB); break; } switch (TSFlags & X86II::OpMapMask) { case X86II::T8: // 0F 38 - emitByte(0x38, OS); + emitByte(0x38, CB); break; case X86II::TA: // 0F 3A - emitByte(0x3A, OS); + emitByte(0x3A, CB); break; } return Kind; } -void X86MCCodeEmitter::emitPrefix(const MCInst &MI, raw_ostream &OS, +void X86MCCodeEmitter::emitPrefix(const MCInst &MI, SmallVectorImpl &CB, const MCSubtargetInfo &STI) const { unsigned Opcode = MI.getOpcode(); const MCInstrDesc &Desc = MCII.get(Opcode); @@ -1348,10 +1354,11 @@ unsigned CurOp = X86II::getOperandBias(Desc); - emitPrefixImpl(CurOp, MI, STI, OS); + emitPrefixImpl(CurOp, MI, STI, CB); } -void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, +void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, + SmallVectorImpl &CB, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const { unsigned Opcode = MI.getOpcode(); @@ -1365,9 +1372,9 @@ unsigned NumOps = Desc.getNumOperands(); unsigned CurOp = X86II::getOperandBias(Desc); - uint64_t StartByte = OS.tell(); + uint64_t StartByte = CB.size(); - PrefixKind Kind = emitPrefixImpl(CurOp, MI, STI, OS); + PrefixKind Kind = emitPrefixImpl(CurOp, MI, STI, CB); // It uses the VEX.VVVV field? bool HasVEX_4V = TSFlags & X86II::VEX_4V; @@ -1398,7 +1405,7 @@ case X86II::RawFrmSrc: case X86II::RawFrmDst: case X86II::PrefixByte: - emitByte(BaseOpcode, OS); + emitByte(BaseOpcode, CB); break; case X86II::AddCCFrm: { // This will be added to the opcode in the fallthrough. @@ -1407,47 +1414,47 @@ --NumOps; // Drop the operand from the end. [[fallthrough]]; case X86II::RawFrm: - emitByte(BaseOpcode + OpcodeOffset, OS); + emitByte(BaseOpcode + OpcodeOffset, CB); if (!STI.hasFeature(X86::Is64Bit) || !isPCRel32Branch(MI, MCII)) break; const MCOperand &Op = MI.getOperand(CurOp++); emitImmediate(Op, MI.getLoc(), X86II::getSizeOfImm(TSFlags), - MCFixupKind(X86::reloc_branch_4byte_pcrel), StartByte, OS, + MCFixupKind(X86::reloc_branch_4byte_pcrel), StartByte, CB, Fixups); break; } case X86II::RawFrmMemOffs: - emitByte(BaseOpcode, OS); + emitByte(BaseOpcode, CB); emitImmediate(MI.getOperand(CurOp++), MI.getLoc(), X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), - StartByte, OS, Fixups); + StartByte, CB, Fixups); ++CurOp; // skip segment operand break; case X86II::RawFrmImm8: - emitByte(BaseOpcode, OS); + emitByte(BaseOpcode, CB); emitImmediate(MI.getOperand(CurOp++), MI.getLoc(), X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), - StartByte, OS, Fixups); + StartByte, CB, Fixups); emitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1, FK_Data_1, StartByte, - OS, Fixups); + CB, Fixups); break; case X86II::RawFrmImm16: - emitByte(BaseOpcode, OS); + emitByte(BaseOpcode, CB); emitImmediate(MI.getOperand(CurOp++), MI.getLoc(), X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), - StartByte, OS, Fixups); + StartByte, CB, Fixups); emitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 2, FK_Data_2, StartByte, - OS, Fixups); + CB, Fixups); break; case X86II::AddRegFrm: - emitByte(BaseOpcode + getX86RegNum(MI.getOperand(CurOp++)), OS); + emitByte(BaseOpcode + getX86RegNum(MI.getOperand(CurOp++)), CB); break; case X86II::MRMDestReg: { - emitByte(BaseOpcode, OS); + emitByte(BaseOpcode, CB); unsigned SrcRegNum = CurOp + 1; if (HasEVEX_K) // Skip writemask @@ -1457,22 +1464,22 @@ ++SrcRegNum; emitRegModRMByte(MI.getOperand(CurOp), - getX86RegNum(MI.getOperand(SrcRegNum)), OS); + getX86RegNum(MI.getOperand(SrcRegNum)), CB); CurOp = SrcRegNum + 1; break; } case X86II::MRMDestMem4VOp3CC: { unsigned CC = MI.getOperand(8).getImm(); - emitByte(BaseOpcode + CC, OS); + emitByte(BaseOpcode + CC, CB); unsigned SrcRegNum = CurOp + X86::AddrNumOperands; emitMemModRMByte(MI, CurOp + 1, getX86RegNum(MI.getOperand(0)), TSFlags, - Kind, StartByte, OS, Fixups, STI, false); + Kind, StartByte, CB, Fixups, STI, false); CurOp = SrcRegNum + 3; // skip reg, VEX_V4 and CC break; } case X86II::MRMDestMemFSIB: case X86II::MRMDestMem: { - emitByte(BaseOpcode, OS); + emitByte(BaseOpcode, CB); unsigned SrcRegNum = CurOp + X86::AddrNumOperands; if (HasEVEX_K) // Skip writemask @@ -1483,12 +1490,12 @@ bool ForceSIB = (Form == X86II::MRMDestMemFSIB); emitMemModRMByte(MI, CurOp, getX86RegNum(MI.getOperand(SrcRegNum)), TSFlags, - Kind, StartByte, OS, Fixups, STI, ForceSIB); + Kind, StartByte, CB, Fixups, STI, ForceSIB); CurOp = SrcRegNum + 1; break; } case X86II::MRMSrcReg: { - emitByte(BaseOpcode, OS); + emitByte(BaseOpcode, CB); unsigned SrcRegNum = CurOp + 1; if (HasEVEX_K) // Skip writemask @@ -1498,7 +1505,7 @@ ++SrcRegNum; emitRegModRMByte(MI.getOperand(SrcRegNum), - getX86RegNum(MI.getOperand(CurOp)), OS); + getX86RegNum(MI.getOperand(CurOp)), CB); CurOp = SrcRegNum + 1; if (HasVEX_I8Reg) I8RegNum = getX86RegEncoding(MI, CurOp++); @@ -1508,17 +1515,17 @@ break; } case X86II::MRMSrcReg4VOp3: { - emitByte(BaseOpcode, OS); + emitByte(BaseOpcode, CB); unsigned SrcRegNum = CurOp + 1; emitRegModRMByte(MI.getOperand(SrcRegNum), - getX86RegNum(MI.getOperand(CurOp)), OS); + getX86RegNum(MI.getOperand(CurOp)), CB); CurOp = SrcRegNum + 1; ++CurOp; // Encoded in VEX.VVVV break; } case X86II::MRMSrcRegOp4: { - emitByte(BaseOpcode, OS); + emitByte(BaseOpcode, CB); unsigned SrcRegNum = CurOp + 1; // Skip 1st src (which is encoded in VEX_VVVV) @@ -1529,7 +1536,7 @@ I8RegNum = getX86RegEncoding(MI, SrcRegNum++); emitRegModRMByte(MI.getOperand(SrcRegNum), - getX86RegNum(MI.getOperand(CurOp)), OS); + getX86RegNum(MI.getOperand(CurOp)), CB); CurOp = SrcRegNum + 1; break; } @@ -1538,10 +1545,10 @@ unsigned SecondOp = CurOp++; unsigned CC = MI.getOperand(CurOp++).getImm(); - emitByte(BaseOpcode + CC, OS); + emitByte(BaseOpcode + CC, CB); emitRegModRMByte(MI.getOperand(SecondOp), - getX86RegNum(MI.getOperand(FirstOp)), OS); + getX86RegNum(MI.getOperand(FirstOp)), CB); break; } case X86II::MRMSrcMemFSIB: @@ -1554,11 +1561,11 @@ if (HasVEX_4V) ++FirstMemOp; // Skip the register source (which is encoded in VEX_VVVV). - emitByte(BaseOpcode, OS); + emitByte(BaseOpcode, CB); bool ForceSIB = (Form == X86II::MRMSrcMemFSIB); emitMemModRMByte(MI, FirstMemOp, getX86RegNum(MI.getOperand(CurOp)), - TSFlags, Kind, StartByte, OS, Fixups, STI, ForceSIB); + TSFlags, Kind, StartByte, CB, Fixups, STI, ForceSIB); CurOp = FirstMemOp + X86::AddrNumOperands; if (HasVEX_I8Reg) I8RegNum = getX86RegEncoding(MI, CurOp++); @@ -1567,10 +1574,10 @@ case X86II::MRMSrcMem4VOp3: { unsigned FirstMemOp = CurOp + 1; - emitByte(BaseOpcode, OS); + emitByte(BaseOpcode, CB); emitMemModRMByte(MI, FirstMemOp, getX86RegNum(MI.getOperand(CurOp)), - TSFlags, Kind, StartByte, OS, Fixups, STI); + TSFlags, Kind, StartByte, CB, Fixups, STI); CurOp = FirstMemOp + X86::AddrNumOperands; ++CurOp; // Encoded in VEX.VVVV. break; @@ -1584,10 +1591,10 @@ assert(HasVEX_I8Reg && "MRMSrcRegOp4 should imply VEX_I8Reg"); I8RegNum = getX86RegEncoding(MI, FirstMemOp++); - emitByte(BaseOpcode, OS); + emitByte(BaseOpcode, CB); emitMemModRMByte(MI, FirstMemOp, getX86RegNum(MI.getOperand(CurOp)), - TSFlags, Kind, StartByte, OS, Fixups, STI); + TSFlags, Kind, StartByte, CB, Fixups, STI); CurOp = FirstMemOp + X86::AddrNumOperands; break; } @@ -1597,10 +1604,10 @@ CurOp = FirstMemOp + X86::AddrNumOperands; unsigned CC = MI.getOperand(CurOp++).getImm(); - emitByte(BaseOpcode + CC, OS); + emitByte(BaseOpcode + CC, CB); emitMemModRMByte(MI, FirstMemOp, getX86RegNum(MI.getOperand(RegOp)), - TSFlags, Kind, StartByte, OS, Fixups, STI); + TSFlags, Kind, StartByte, CB, Fixups, STI); break; } @@ -1608,8 +1615,8 @@ unsigned RegOp = CurOp++; unsigned CC = MI.getOperand(CurOp++).getImm(); - emitByte(BaseOpcode + CC, OS); - emitRegModRMByte(MI.getOperand(RegOp), 0, OS); + emitByte(BaseOpcode + CC, CB); + emitRegModRMByte(MI.getOperand(RegOp), 0, CB); break; } @@ -1626,13 +1633,13 @@ ++CurOp; if (HasEVEX_K) // Skip writemask ++CurOp; - emitByte(BaseOpcode, OS); + emitByte(BaseOpcode, CB); emitRegModRMByte(MI.getOperand(CurOp++), - (Form == X86II::MRMXr) ? 0 : Form - X86II::MRM0r, OS); + (Form == X86II::MRMXr) ? 0 : Form - X86II::MRM0r, CB); break; case X86II::MRMr0: - emitByte(BaseOpcode, OS); - emitByte(modRMByte(3, getX86RegNum(MI.getOperand(CurOp++)),0), OS); + emitByte(BaseOpcode, CB); + emitByte(modRMByte(3, getX86RegNum(MI.getOperand(CurOp++)),0), CB); break; case X86II::MRMXmCC: { @@ -1640,9 +1647,9 @@ CurOp = FirstMemOp + X86::AddrNumOperands; unsigned CC = MI.getOperand(CurOp++).getImm(); - emitByte(BaseOpcode + CC, OS); + emitByte(BaseOpcode + CC, CB); - emitMemModRMByte(MI, FirstMemOp, 0, TSFlags, Kind, StartByte, OS, Fixups, + emitMemModRMByte(MI, FirstMemOp, 0, TSFlags, Kind, StartByte, CB, Fixups, STI); break; } @@ -1660,10 +1667,10 @@ ++CurOp; if (HasEVEX_K) // Skip writemask ++CurOp; - emitByte(BaseOpcode, OS); + emitByte(BaseOpcode, CB); emitMemModRMByte(MI, CurOp, (Form == X86II::MRMXm) ? 0 : Form - X86II::MRM0m, TSFlags, - Kind, StartByte, OS, Fixups, STI); + Kind, StartByte, CB, Fixups, STI); CurOp += X86::AddrNumOperands; break; @@ -1675,8 +1682,8 @@ case X86II::MRM5X: case X86II::MRM6X: case X86II::MRM7X: - emitByte(BaseOpcode, OS); - emitByte(0xC0 + ((Form - X86II::MRM0X) << 3), OS); + emitByte(BaseOpcode, CB); + emitByte(0xC0 + ((Form - X86II::MRM0X) << 3), CB); break; case X86II::MRM_C0: @@ -1743,8 +1750,8 @@ case X86II::MRM_FD: case X86II::MRM_FE: case X86II::MRM_FF: - emitByte(BaseOpcode, OS); - emitByte(0xC0 + Form - X86II::MRM_C0, OS); + emitByte(BaseOpcode, CB); + emitByte(0xC0 + Form - X86II::MRM_C0, CB); break; } @@ -1759,7 +1766,7 @@ I8RegNum |= Val; } emitImmediate(MCOperand::createImm(I8RegNum), MI.getLoc(), 1, FK_Data_1, - StartByte, OS, Fixups); + StartByte, CB, Fixups); } else { // If there is a remaining operand, it must be a trailing immediate. Emit it // according to the right size for the instruction. Some instructions @@ -1767,14 +1774,14 @@ while (CurOp != NumOps && NumOps - CurOp <= 2) { emitImmediate(MI.getOperand(CurOp++), MI.getLoc(), X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), - StartByte, OS, Fixups); + StartByte, CB, Fixups); } } if ((TSFlags & X86II::OpMapMask) == X86II::ThreeDNow) - emitByte(X86II::getBaseOpcodeFor(TSFlags), OS); + emitByte(X86II::getBaseOpcodeFor(TSFlags), CB); - assert(OS.tell() - StartByte <= 15 && + assert(CB.size() - StartByte <= 15 && "The size of instruction must be no longer than 15."); #ifndef NDEBUG // FIXME: Verify.