diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index a367fa1ff7439..19b4ea474f528 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -106,6 +106,9 @@ class X86AsmParser : public MCTargetAsmParser { DispEncoding ForcedDispEncoding = DispEncoding_Default; + // Does this instruction use apx extended register? + bool UseApxExtendedReg = false; + private: SMLoc consumeToken() { MCAsmParser &Parser = getParser(); @@ -1410,6 +1413,9 @@ bool X86AsmParser::MatchRegisterByName(MCRegister &RegNo, StringRef RegName, } } + if (X86II::isApxExtendedReg(RegNo)) + UseApxExtendedReg = true; + // If this is "db[0-15]", match it as an alias // for dr[0-15]. if (RegNo == 0 && RegName.startswith("db")) { @@ -3084,6 +3090,7 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, // Reset the forced VEX encoding. ForcedVEXEncoding = VEXEncoding_Default; ForcedDispEncoding = DispEncoding_Default; + UseApxExtendedReg = false; // Parse pseudo prefixes. while (true) { @@ -3954,6 +3961,9 @@ unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) { unsigned Opc = Inst.getOpcode(); const MCInstrDesc &MCID = MII.get(Opc); + if (UseApxExtendedReg && !X86II::canUseApxExtendedReg(MCID)) + return Match_Unsupported; + if (ForcedVEXEncoding == VEXEncoding_EVEX && (MCID.TSFlags & X86II::EncodingMask) != X86II::EVEX) return Match_Unsupported; diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h index 3ccc73398064b..4c57009e3bc08 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -1208,6 +1208,12 @@ namespace X86II { return RegNo >= X86::ZMM0 && RegNo <= X86::ZMM31; } + /// \returns true if \p RegNo is an apx extended register. + inline bool isApxExtendedReg(unsigned RegNo) { + assert(X86::R31WH - X86::R16 == 95 && "EGPRs are not continuous"); + return RegNo >= X86::R16 && RegNo <= X86::R31WH; + } + /// \returns true if the MachineOperand is a x86-64 extended (r8 or /// higher) register, e.g. r8, xmm8, xmm13, etc. inline bool isX86_64ExtendedReg(unsigned RegNo) { @@ -1218,6 +1224,9 @@ namespace X86II { (RegNo >= X86::ZMM8 && RegNo <= X86::ZMM31)) return true; + if (isApxExtendedReg(RegNo)) + return true; + switch (RegNo) { default: break; case X86::R8: case X86::R9: case X86::R10: case X86::R11: diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index b85404be3063d..c17e7e1834238 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -36,7 +36,7 @@ using namespace llvm; namespace { -enum PrefixKind { None, REX, XOP, VEX2, VEX3, EVEX }; +enum PrefixKind { None, REX, REX2, XOP, VEX2, VEX3, EVEX }; static void emitByte(uint8_t C, SmallVectorImpl &CB) { CB.push_back(C); } @@ -46,6 +46,11 @@ class X86OpcodePrefixHelper { // | 40H | | WRXB | // +-----+ +------+ + // REX2 (2 bytes) + // +-----+ +-------------------+ + // | D5H | | M | R'X'B' | WRXB | + // +-----+ +-------------------+ + // XOP (3-byte) // +-----+ +--------------+ +-------------------+ // | 8Fh | | RXB | m-mmmm | | W | vvvv | L | pp | @@ -106,9 +111,9 @@ class X86OpcodePrefixHelper { // 0b11: F2 // EVEX (4 bytes) - // +-----+ +--------------+ +-------------------+ +------------------------+ - // | 62h | | RXBR' | 0mmm | | W | vvvv | 1 | pp | | z | L'L | b | v' | aaa | - // +-----+ +--------------+ +-------------------+ +------------------------+ + // +-----+ +---------------+ +--------------------+ +------------------------+ + // | 62h | | RXBR' | B'mmm | | W | vvvv | X' | pp | | z | L'L | b | v' | aaa | + // +-----+ +---------------+ +--------------------+ +------------------------+ // EVEX_L2/VEX_L (Vector Length): // L2 L @@ -116,16 +121,39 @@ class X86OpcodePrefixHelper { // 0 1: 256-bit vector // 1 0: 512-bit vector + // 32-Register Support in 64-bit Mode Using EVEX with Embedded REX/REX2 Bits: + // + // +----------+---------+--------+-----------+---------+--------------+ + // | | 4 | 3 | [2:0] | Type | Common Usage | + // +----------+---------+--------+-----------+---------+--------------+ + // | REG | EVEX_R' | EVEX_R | modrm.reg | GPR, VR | Dest or Src | + // | VVVV | EVEX_v' | EVEX.vvvv | GPR, VR | Dest or Src | + // | RM (VR) | EVEX_X | EVEX_B | modrm.r/m | VR | Dest or Src | + // | RM (GPR) | EVEX_B' | EVEX_B | modrm.r/m | GPR | Dest or Src | + // | BASE | EVEX_B' | EVEX_B | modrm.r/m | GPR | MA | + // | INDEX | EVEX_X' | EVEX_X | sib.index | GPR | MA | + // | VIDX | EVEX_v' | EVEX_X | sib.index | VR | VSIB MA | + // +----------+---------+--------+-----------+---------+--------------+ + // + // * GPR - General-purpose register + // * VR - Vector register + // * VIDX - Vector index + // * VSIB - Vector SIB + // * MA - Memory addressing + private: unsigned W : 1; unsigned R : 1; unsigned X : 1; unsigned B : 1; + unsigned M : 1; + unsigned R2 : 1; + unsigned X2 : 1; + unsigned B2 : 1; unsigned VEX_4V : 4; unsigned VEX_L : 1; unsigned VEX_PP : 2; unsigned VEX_5M : 5; - unsigned EVEX_R2 : 1; unsigned EVEX_z : 1; unsigned EVEX_L2 : 1; unsigned EVEX_b : 1; @@ -139,7 +167,20 @@ class X86OpcodePrefixHelper { } void setR(unsigned Encoding) { R = Encoding >> 3 & 1; } - void setR2(unsigned Encoding) { EVEX_R2 = Encoding >> 4 & 1; } + void setR2(unsigned Encoding) { + R2 = Encoding >> 4 & 1; + assert((!R2 || (Kind <= REX2 || Kind == EVEX)) && "invalid setting"); + } + void setX(unsigned Encoding) { X = Encoding >> 3 & 1; } + void setX2(unsigned Encoding) { + assert((Kind <= REX2 || Kind == EVEX) && "invalid setting"); + X2 = Encoding >> 4 & 1; + } + void setB(unsigned Encoding) { B = Encoding >> 3 & 1; } + void setB2(unsigned Encoding) { + assert((Kind <= REX2 || Kind == EVEX) && "invalid setting"); + B2 = Encoding >> 4 & 1; + } void set4V(unsigned Encoding) { VEX_4V = Encoding & 0xf; } void setV2(unsigned Encoding) { EVEX_V2 = Encoding >> 4 & 1; } @@ -149,7 +190,12 @@ class X86OpcodePrefixHelper { setR(getRegEncoding(MI, OpNum)); } void setX(const MCInst &MI, unsigned OpNum, unsigned Shift = 3) { - X = getRegEncoding(MI, OpNum) >> Shift & 1; + unsigned Reg = MI.getOperand(OpNum).getReg(); + // X is used to extend vector register only when shift is not 3. + if (Shift != 3 && X86II::isApxExtendedReg(Reg)) + return; + unsigned Encoding = MRI.getEncodingValue(Reg); + X = Encoding >> Shift & 1; } void setB(const MCInst &MI, unsigned OpNum) { B = getRegEncoding(MI, OpNum) >> 3 & 1; @@ -168,11 +214,34 @@ class X86OpcodePrefixHelper { setR(Encoding); setR2(Encoding); } + void setM(bool V) { M = V; } + void setXX2(const MCInst &MI, unsigned OpNum) { + unsigned Reg = MI.getOperand(OpNum).getReg(); + unsigned Encoding = MRI.getEncodingValue(Reg); + setX(Encoding); + // Index can be a vector register while X2 is used to extend GPR only. + if (Kind <= REX2 || X86II::isApxExtendedReg(Reg)) + setX2(Encoding); + } + void setBB2(const MCInst &MI, unsigned OpNum) { + unsigned Reg = MI.getOperand(OpNum).getReg(); + unsigned Encoding = MRI.getEncodingValue(Reg); + setB(Encoding); + // Base can be a vector register while B2 is used to extend GPR only + if (Kind <= REX2 || X86II::isApxExtendedReg(Reg)) + setB2(Encoding); + } void setZ(bool V) { EVEX_z = V; } void setL2(bool V) { EVEX_L2 = V; } void setEVEX_b(bool V) { EVEX_b = V; } - void setV2(const MCInst &MI, unsigned OpNum) { - setV2(getRegEncoding(MI, OpNum)); + void setV2(const MCInst &MI, unsigned OpNum, bool HasVEX_4V) { + // Only needed with VSIB which don't use VVVV. + if (HasVEX_4V) + return; + unsigned Reg = MI.getOperand(OpNum).getReg(); + if (X86II::isApxExtendedReg(Reg)) + return; + setV2(MRI.getEncodingValue(Reg)); } void set4VV2(const MCInst &MI, unsigned OpNum) { unsigned Encoding = getRegEncoding(MI, OpNum); @@ -184,18 +253,24 @@ class X86OpcodePrefixHelper { } X86OpcodePrefixHelper(const MCRegisterInfo &MRI) - : W(0), R(0), X(0), B(0), VEX_4V(0), VEX_L(0), VEX_PP(0), VEX_5M(0), - EVEX_R2(0), EVEX_z(0), EVEX_L2(0), EVEX_b(0), EVEX_V2(0), EVEX_aaa(0), - MRI(MRI) {} + : W(0), R(0), X(0), B(0), M(0), R2(0), X2(0), B2(0), VEX_4V(0), VEX_L(0), + VEX_PP(0), VEX_5M(0), EVEX_z(0), EVEX_L2(0), EVEX_b(0), EVEX_V2(0), + EVEX_aaa(0), MRI(MRI) {} void setLowerBound(PrefixKind K) { Kind = K; } PrefixKind determineOptimalKind() { switch (Kind) { case None: - Kind = (W | R | X | B) ? REX : None; + // Not M bit here by intention b/c + // 1. No guarantee that REX2 is supported by arch w/o explict EGPR + // 2. REX2 is longer than 0FH + Kind = (R2 | X2 | B2) ? REX2 : (W | R | X | B) ? REX : None; break; case REX: + Kind = (R2 | X2 | B2) ? REX2 : REX; + break; + case REX2: case XOP: case VEX3: case EVEX: @@ -217,6 +292,12 @@ class X86OpcodePrefixHelper { case REX: emitByte(0x40 | W << 3 | R << 2 | X << 1 | B, CB); return; + case REX2: + emitByte(0xD5, CB); + emitByte(M << 7 | R2 << 6 | X2 << 5 | B2 << 4 | W << 3 | R << 2 | X << 1 | + B, + CB); + return; case VEX2: emitByte(0xC5, CB); emitByte(((~R) & 1) << 7 | LastPayload, CB); @@ -230,8 +311,9 @@ class X86OpcodePrefixHelper { case EVEX: assert(VEX_5M && !(VEX_5M & 0x8) && "invalid mmm fields for EVEX!"); 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(FirstPayload | ((~R2) & 0x1) << 4 | B2 << 3 | VEX_5M, CB); + emitByte(W << 7 | ((~VEX_4V) & 0xf) << 3 | ((~X2) & 0x1) << 2 | VEX_PP, + CB); emitByte(EVEX_z << 7 | EVEX_L2 << 6 | VEX_L << 5 | EVEX_b << 4 | ((~EVEX_V2) & 0x1) << 3 | EVEX_aaa, CB); @@ -548,7 +630,8 @@ void X86MCCodeEmitter::emitMemModRMByte( // movq loads is a subset of reloc_riprel_4byte_relax_rex. It is a // special case because COFF and Mach-O don't support ELF's more // flexible R_X86_64_REX_GOTPCRELX relaxation. - assert(Kind == REX); + // TODO: Support new relocation for REX2. + assert(Kind == REX || Kind == REX2); return X86::reloc_riprel_4byte_movq_load; case X86::ADC32rm: case X86::ADD32rm: @@ -572,8 +655,11 @@ void X86MCCodeEmitter::emitMemModRMByte( case X86::SBB64rm: case X86::SUB64rm: case X86::XOR64rm: - return Kind == REX ? X86::reloc_riprel_4byte_relax_rex - : X86::reloc_riprel_4byte_relax; + // We haven't support relocation for REX2 prefix, so temporarily use REX + // relocation. + // TODO: Support new relocation for REX2. + return (Kind == REX || Kind == REX2) ? X86::reloc_riprel_4byte_relax_rex + : X86::reloc_riprel_4byte_relax; } }(); @@ -666,11 +752,11 @@ void X86MCCodeEmitter::emitMemModRMByte( bool AllowDisp8 = !UseDisp32; // Determine whether a SIB byte is needed. - if (// The SIB byte must be used if there is an index register or the - // encoding requires a SIB byte. + if ( // The SIB byte must be used if there is an index register or the + // encoding requires a SIB byte. !ForceSIB && IndexReg.getReg() == 0 && - // 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 + // The SIB byte must be used if the base is ESP/RSP/R12/R20/R28, 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 @@ -683,10 +769,11 @@ void X86MCCodeEmitter::emitMemModRMByte( return; } - // If the base is not EBP/ESP/R12/R13 and there is no displacement, use - // simple indirect register encoding, this handles addresses like [EAX]. - // The encoding for [EBP] or[R13] with no displacement means [disp32] so we - // handle it by emitting a displacement of 0 later. + // If the base is not EBP/ESP/R12/R13/R20/R21/R28/R29 and there is no + // displacement, use simple indirect register encoding, this handles + // addresses like [EAX]. The encoding for [EBP], [R13], [R20], [R21], [R28] + // or [R29] with no displacement means [disp32] so we 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), CB); @@ -708,8 +795,8 @@ void X86MCCodeEmitter::emitMemModRMByte( // Otherwise, if the displacement fits in a byte, encode as [REG+disp8]. // Including a compressed disp8 for EVEX instructions that support it. - // This also handles the 0 displacement for [EBP] or [R13]. We can't use - // disp8 if the {disp32} pseudo prefix is present. + // This also handles the 0 displacement for [EBP], [R13], [R21] or [R29]. We + // can't use disp8 if the {disp32} pseudo prefix is present. if (Disp.isImm() && AllowDisp8) { int ImmOffset = 0; if (isDispOrCDisp8(TSFlags, Disp.getImm(), ImmOffset)) { @@ -721,8 +808,8 @@ void X86MCCodeEmitter::emitMemModRMByte( } // 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. + // Displacement may be 0 for [EBP], [R13], [R21], [R29] case if {disp32} + // pseudo prefix prevented using disp8 above. emitByte(modRMByte(2, RegOpcodeField, BaseRegNo), CB); unsigned Opcode = MI.getOpcode(); unsigned FixupKind = Opcode == X86::MOV32rm ? X86::reloc_signed_4byte_relax @@ -746,18 +833,18 @@ void X86MCCodeEmitter::emitMemModRMByte( 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 - // the base field, but that is the magic [*] nomenclature that - // indicates no base when mod=0. For these cases we'll emit a 0 - // displacement instead. + // Base reg can't be EBP/RBP/R13/R21/R29 as that would end up with + // '5' as the base field, but that is the magic [*] nomenclature + // that indicates no base when mod=0. For these cases we'll emit a + // 0 displacement instead. BaseRegNo != N86::EBP) { // Emit no displacement ModR/M byte 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. + // disp8 encoding. This also handles EBP/R13/R21/R29 base with 0 + // displacement unless {disp32} pseudo prefix was used. emitByte(modRMByte(1, RegOpcodeField, 4), CB); ForceDisp8 = true; } else { @@ -869,6 +956,20 @@ X86MCCodeEmitter::emitVEXOpcodePrefix(int MemOperand, const MCInst &MI, assert(!(TSFlags & X86II::LOCK) && "Can't have LOCK VEX."); +#ifndef NDEBUG + unsigned NumOps = MI.getNumOperands(); + for (unsigned I = NumOps ? X86II::getOperandBias(Desc) : 0; I != NumOps; + ++I) { + const MCOperand &MO = MI.getOperand(I); + if (!MO.isReg()) + continue; + unsigned Reg = MO.getReg(); + if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH) + report_fatal_error( + "Cannot encode high byte register in VEX/EVEX-prefixed instruction"); + } +#endif + X86OpcodePrefixHelper Prefix(*Ctx.getRegisterInfo()); switch (TSFlags & X86II::EncodingMask) { default: @@ -952,9 +1053,9 @@ X86MCCodeEmitter::emitVEXOpcodePrefix(int MemOperand, const MCInst &MI, llvm_unreachable("Unexpected form in emitVEXOpcodePrefix!"); case X86II::MRMDestMem4VOp3CC: { // src1(ModR/M), MemAddr, src2(VEX_4V) - Prefix.setR(MI, CurOp++); - Prefix.setB(MI, MemOperand + X86::AddrBaseReg); - Prefix.setX(MI, MemOperand + X86::AddrIndexReg); + Prefix.setRR2(MI, CurOp++); + Prefix.setBB2(MI, MemOperand + X86::AddrBaseReg); + Prefix.setXX2(MI, MemOperand + X86::AddrIndexReg); CurOp += X86::AddrNumOperands; Prefix.set4V(MI, CurOp++); break; @@ -969,10 +1070,9 @@ X86MCCodeEmitter::emitVEXOpcodePrefix(int MemOperand, const MCInst &MI, // MemAddr, src1(VEX_4V), src2(ModR/M) // MemAddr, src1(ModR/M), imm8 // - Prefix.setB(MI, MemOperand + X86::AddrBaseReg); - Prefix.setX(MI, MemOperand + X86::AddrIndexReg); - if (!HasVEX_4V) // Only needed with VSIB which don't use VVVV. - Prefix.setV2(MI, MemOperand + X86::AddrIndexReg); + Prefix.setBB2(MI, MemOperand + X86::AddrBaseReg); + Prefix.setXX2(MI, MemOperand + X86::AddrIndexReg); + Prefix.setV2(MI, MemOperand + X86::AddrIndexReg, HasVEX_4V); CurOp += X86::AddrNumOperands; @@ -1003,10 +1103,9 @@ X86MCCodeEmitter::emitVEXOpcodePrefix(int MemOperand, const MCInst &MI, if (HasVEX_4V) Prefix.set4VV2(MI, CurOp++); - Prefix.setB(MI, MemOperand + X86::AddrBaseReg); - Prefix.setX(MI, MemOperand + X86::AddrIndexReg); - if (!HasVEX_4V) // Only needed with VSIB which don't use VVVV. - Prefix.setV2(MI, MemOperand + X86::AddrIndexReg); + Prefix.setBB2(MI, MemOperand + X86::AddrBaseReg); + Prefix.setXX2(MI, MemOperand + X86::AddrIndexReg); + Prefix.setV2(MI, MemOperand + X86::AddrIndexReg, HasVEX_4V); break; } @@ -1014,8 +1113,8 @@ X86MCCodeEmitter::emitVEXOpcodePrefix(int MemOperand, const MCInst &MI, // Instruction format for 4VOp3: // src1(ModR/M), MemAddr, src3(VEX_4V) Prefix.setR(MI, CurOp++); - Prefix.setB(MI, MemOperand + X86::AddrBaseReg); - Prefix.setX(MI, MemOperand + X86::AddrIndexReg); + Prefix.setBB2(MI, MemOperand + X86::AddrBaseReg); + Prefix.setXX2(MI, MemOperand + X86::AddrIndexReg); Prefix.set4V(MI, CurOp + X86::AddrNumOperands); break; } @@ -1023,8 +1122,8 @@ X86MCCodeEmitter::emitVEXOpcodePrefix(int MemOperand, const MCInst &MI, // dst(ModR/M.reg), src1(VEX_4V), src2(Imm[7:4]), src3(ModR/M), Prefix.setR(MI, CurOp++); Prefix.set4V(MI, CurOp++); - Prefix.setB(MI, MemOperand + X86::AddrBaseReg); - Prefix.setX(MI, MemOperand + X86::AddrIndexReg); + Prefix.setBB2(MI, MemOperand + X86::AddrBaseReg); + Prefix.setXX2(MI, MemOperand + X86::AddrIndexReg); break; } case X86II::MRM0m: @@ -1044,10 +1143,9 @@ X86MCCodeEmitter::emitVEXOpcodePrefix(int MemOperand, const MCInst &MI, if (HasEVEX_K) Prefix.setAAA(MI, CurOp++); - Prefix.setB(MI, MemOperand + X86::AddrBaseReg); - Prefix.setX(MI, MemOperand + X86::AddrIndexReg); - if (!HasVEX_4V) // Only needed with VSIB which don't use VVVV. - Prefix.setV2(MI, MemOperand + X86::AddrIndexReg); + Prefix.setBB2(MI, MemOperand + X86::AddrBaseReg); + Prefix.setXX2(MI, MemOperand + X86::AddrIndexReg); + Prefix.setV2(MI, MemOperand + X86::AddrIndexReg, HasVEX_4V); break; } @@ -1067,7 +1165,7 @@ X86MCCodeEmitter::emitVEXOpcodePrefix(int MemOperand, const MCInst &MI, if (HasVEX_4V) Prefix.set4VV2(MI, CurOp++); - Prefix.setB(MI, CurOp); + Prefix.setBB2(MI, CurOp); Prefix.setX(MI, CurOp, 4); ++CurOp; @@ -1086,8 +1184,8 @@ X86MCCodeEmitter::emitVEXOpcodePrefix(int MemOperand, const MCInst &MI, case X86II::MRMSrcReg4VOp3: { // Instruction format for 4VOp3: // src1(ModR/M), src2(ModR/M), src3(VEX_4V) - Prefix.setR(MI, CurOp++); - Prefix.setB(MI, CurOp++); + Prefix.setRR2(MI, CurOp++); + Prefix.setBB2(MI, CurOp++); Prefix.set4V(MI, CurOp++); break; } @@ -1108,7 +1206,7 @@ X86MCCodeEmitter::emitVEXOpcodePrefix(int MemOperand, const MCInst &MI, // dst(ModR/M), src(ModR/M) // dst(ModR/M), src(ModR/M), imm8 // dst(ModR/M), src1(VEX_4V), src2(ModR/M) - Prefix.setB(MI, CurOp); + Prefix.setBB2(MI, CurOp); Prefix.setX(MI, CurOp, 4); ++CurOp; @@ -1146,7 +1244,7 @@ X86MCCodeEmitter::emitVEXOpcodePrefix(int MemOperand, const MCInst &MI, if (HasEVEX_K) Prefix.setAAA(MI, CurOp++); - Prefix.setB(MI, CurOp); + Prefix.setBB2(MI, CurOp); Prefix.setX(MI, CurOp, 4); ++CurOp; break; @@ -1218,29 +1316,29 @@ PrefixKind X86MCCodeEmitter::emitREXPrefix(int MemOperand, const MCInst &MI, case X86II::RawFrmDstSrc: break; case X86II::AddRegFrm: - Prefix.setB(MI, CurOp++); + Prefix.setBB2(MI, CurOp++); break; case X86II::MRMSrcReg: case X86II::MRMSrcRegCC: - Prefix.setR(MI, CurOp++); - Prefix.setB(MI, CurOp++); + Prefix.setRR2(MI, CurOp++); + Prefix.setBB2(MI, CurOp++); break; case X86II::MRMSrcMem: case X86II::MRMSrcMemCC: - Prefix.setR(MI, CurOp++); - Prefix.setB(MI, MemOperand + X86::AddrBaseReg); - Prefix.setX(MI, MemOperand + X86::AddrIndexReg); + Prefix.setRR2(MI, CurOp++); + Prefix.setBB2(MI, MemOperand + X86::AddrBaseReg); + Prefix.setXX2(MI, MemOperand + X86::AddrIndexReg); CurOp += X86::AddrNumOperands; break; case X86II::MRMDestReg: - Prefix.setB(MI, CurOp++); - Prefix.setR(MI, CurOp++); + Prefix.setBB2(MI, CurOp++); + Prefix.setRR2(MI, CurOp++); break; case X86II::MRMDestMem: - Prefix.setB(MI, MemOperand + X86::AddrBaseReg); - Prefix.setX(MI, MemOperand + X86::AddrIndexReg); + Prefix.setBB2(MI, MemOperand + X86::AddrBaseReg); + Prefix.setXX2(MI, MemOperand + X86::AddrIndexReg); CurOp += X86::AddrNumOperands; - Prefix.setR(MI, CurOp++); + Prefix.setRR2(MI, CurOp++); break; case X86II::MRMXmCC: case X86II::MRMXm: @@ -1252,8 +1350,8 @@ PrefixKind X86MCCodeEmitter::emitREXPrefix(int MemOperand, const MCInst &MI, case X86II::MRM5m: case X86II::MRM6m: case X86II::MRM7m: - Prefix.setB(MI, MemOperand + X86::AddrBaseReg); - Prefix.setX(MI, MemOperand + X86::AddrIndexReg); + Prefix.setBB2(MI, MemOperand + X86::AddrBaseReg); + Prefix.setXX2(MI, MemOperand + X86::AddrIndexReg); break; case X86II::MRMXrCC: case X86II::MRMXr: @@ -1265,9 +1363,10 @@ PrefixKind X86MCCodeEmitter::emitREXPrefix(int MemOperand, const MCInst &MI, case X86II::MRM5r: case X86II::MRM6r: case X86II::MRM7r: - Prefix.setB(MI, CurOp++); + Prefix.setBB2(MI, CurOp++); break; } + Prefix.setM((TSFlags & X86II::OpMapMask) == X86II::TB); PrefixKind Kind = Prefix.determineOptimalKind(); if (Kind && UsesHighByteReg) report_fatal_error( @@ -1329,6 +1428,10 @@ PrefixKind X86MCCodeEmitter::emitOpcodePrefix(int MemOperand, const MCInst &MI, // 0x0F escape code must be emitted just before the opcode. switch (TSFlags & X86II::OpMapMask) { case X86II::TB: // Two-byte opcode map + // Encoded by M bit in REX2 + if (Kind == REX2) + break; + [[fallthrough]]; case X86II::T8: // 0F 38 case X86II::TA: // 0F 3A case X86II::ThreeDNow: // 0F 0F, second 0F emitted by caller. diff --git a/llvm/test/MC/X86/apx/evex-format-att.s b/llvm/test/MC/X86/apx/evex-format-att.s new file mode 100644 index 0000000000000..aedd09e7e698d --- /dev/null +++ b/llvm/test/MC/X86/apx/evex-format-att.s @@ -0,0 +1,67 @@ +## NOTE: This file needs to be updated after promoted instruction is supported +# RUN: llvm-mc -triple x86_64 -show-encoding %s | FileCheck %s + +## MRMDestMem + +# CHECK: vextractf32x4 $1, %zmm0, (%r16,%r17) +# CHECK: encoding: [0x62,0xfb,0x79,0x48,0x19,0x04,0x08,0x01] + vextractf32x4 $1, %zmm0, (%r16,%r17) + +## MRMSrcMem + +# CHECK: vbroadcasti32x4 (%r16,%r17), %zmm0 +# CHECK: encoding: [0x62,0xfa,0x79,0x48,0x5a,0x04,0x08] + vbroadcasti32x4 (%r16,%r17), %zmm0 + +## MRM0m + +# CHECK: vprorq $0, (%r16,%r17), %zmm0 +# CHECK: encoding: [0x62,0xf9,0xf9,0x48,0x72,0x04,0x08,0x00] + vprorq $0, (%r16,%r17), %zmm0 + +## MRM1m + +# CHECK: vprolq $0, (%r16,%r17), %zmm0 +# CHECK: encoding: [0x62,0xf9,0xf9,0x48,0x72,0x0c,0x08,0x00] + vprolq $0, (%r16,%r17), %zmm0 +## MRM2m + +# CHECK: vpsrlq $0, (%r16,%r17), %zmm0 +# CHECK: encoding: [0x62,0xf9,0xf9,0x48,0x73,0x14,0x08,0x00] + vpsrlq $0, (%r16,%r17), %zmm0 + +## MRM3m + +# CHECK: vpsrldq $0, (%r16,%r17), %zmm0 +# CHECK: encoding: [0x62,0xf9,0x79,0x48,0x73,0x1c,0x08,0x00] + vpsrldq $0, (%r16,%r17), %zmm0 + +## MRM4m + +# CHECK: vpsraq $0, (%r16,%r17), %zmm0 +# CHECK: encoding: [0x62,0xf9,0xf9,0x48,0x72,0x24,0x08,0x00] + vpsraq $0, (%r16,%r17), %zmm0 + +## MRM5m + +# CHECK: vscatterpf0dps (%r16,%zmm0) {%k1} +# CHECK: encoding: [0x62,0xfa,0x7d,0x49,0xc6,0x2c,0x00] + vscatterpf0dps (%r16,%zmm0) {%k1} + +## MRM6m + +# CHECK: vpsllq $0, (%r16,%r17), %zmm0 +# CHECK: encoding: [0x62,0xf9,0xf9,0x48,0x73,0x34,0x08,0x00] + vpsllq $0, (%r16,%r17), %zmm0 + +## MRM7m + +# CHECK: vpslldq $0, (%r16,%r17), %zmm0 +# CHECK: encoding: [0x62,0xf9,0x79,0x48,0x73,0x3c,0x08,0x00] + vpslldq $0, (%r16,%r17), %zmm0 + +## MRMDestReg + +# CHECK: vextractps $1, %xmm16, %r16d +# CHECK: encoding: [0x62,0xeb,0x7d,0x08,0x17,0xc0,0x01] + vextractps $1, %xmm16, %r16d diff --git a/llvm/test/MC/X86/apx/evex-format-intel.s b/llvm/test/MC/X86/apx/evex-format-intel.s new file mode 100644 index 0000000000000..aa11a879f4b4c --- /dev/null +++ b/llvm/test/MC/X86/apx/evex-format-intel.s @@ -0,0 +1,67 @@ +## NOTE: This file needs to be updated after promoted instruction is supported +# RUN: llvm-mc -triple x86_64 -show-encoding -x86-asm-syntax=intel -output-asm-variant=1 %s | FileCheck %s + +## MRMDestMem + +# CHECK: vextractf32x4 xmmword ptr [r16 + r17], zmm0, 1 +# CHECK: encoding: [0x62,0xfb,0x79,0x48,0x19,0x04,0x08,0x01] + vextractf32x4 xmmword ptr [r16 + r17], zmm0, 1 + +## MRMSrcMem + +# CHECK: vbroadcasti32x4 zmm0, xmmword ptr [r16 + r17] +# CHECK: encoding: [0x62,0xfa,0x79,0x48,0x5a,0x04,0x08] + vbroadcasti32x4 zmm0, xmmword ptr [r16 + r17] + +## MRM0m + +# CHECK: vprorq zmm0, zmmword ptr [r16 + r17], 0 +# CHECK: encoding: [0x62,0xf9,0xf9,0x48,0x72,0x04,0x08,0x00] + vprorq zmm0, zmmword ptr [r16 + r17], 0 + +## MRM1m + +# CHECK: vprolq zmm0, zmmword ptr [r16 + r17], 0 +# CHECK: encoding: [0x62,0xf9,0xf9,0x48,0x72,0x0c,0x08,0x00] + vprolq zmm0, zmmword ptr [r16 + r17], 0 + +## MRM2m + +# CHECK: vpsrlq zmm0, zmmword ptr [r16 + r17], 0 +# CHECK: encoding: [0x62,0xf9,0xf9,0x48,0x73,0x14,0x08,0x00] + vpsrlq zmm0, zmmword ptr [r16 + r17], 0 + +## MRM3m + +# CHECK: vpsrldq zmm0, zmmword ptr [r16 + r17], 0 +# CHECK: encoding: [0x62,0xf9,0x79,0x48,0x73,0x1c,0x08,0x00] + vpsrldq zmm0, zmmword ptr [r16 + r17], 0 +## MRM4m + +# CHECK: vpsraq zmm0, zmmword ptr [r16 + r17], 0 +# CHECK: encoding: [0x62,0xf9,0xf9,0x48,0x72,0x24,0x08,0x00] + vpsraq zmm0, zmmword ptr [r16 + r17], 0 + +## MRM5m +## AsmParser is buggy for this KNC instruction +# C;HECK: vscatterpf0dps {k1}, zmmword ptr [r16 + zmm0] +# C;HECK: encoding: [0x62,0xfa,0x7d,0x49,0xc6,0x2c,0x00] +# vscatterpf0dps {k1}, zmmword ptr [r16 + zmm0] + +## MRM6m + +# CHECK: vpsllq zmm0, zmmword ptr [r16 + r17], 0 +# CHECK: encoding: [0x62,0xf9,0xf9,0x48,0x73,0x34,0x08,0x00] + vpsllq zmm0, zmmword ptr [r16 + r17], 0 + +## MRM7m + +# CHECK: vpslldq zmm0, zmmword ptr [r16 + r17], 0 +# CHECK: encoding: [0x62,0xf9,0x79,0x48,0x73,0x3c,0x08,0x00] + vpslldq zmm0, zmmword ptr [r16 + r17], 0 + +## MRMDestReg + +# CHECK: vextractps r16d, xmm16, 1 +# CHECK: encoding: [0x62,0xeb,0x7d,0x08,0x17,0xc0,0x01] + vextractps r16d, xmm16, 1 diff --git a/llvm/test/MC/X86/apx/rex2-bit-att.s b/llvm/test/MC/X86/apx/rex2-bit-att.s new file mode 100644 index 0000000000000..8ae99699eb50e --- /dev/null +++ b/llvm/test/MC/X86/apx/rex2-bit-att.s @@ -0,0 +1,240 @@ +# RUN: llvm-mc -triple x86_64 -show-encoding %s | FileCheck %s +# RUN: not llvm-mc -triple i386 -show-encoding %s 2>&1 | FileCheck %s --check-prefix=ERROR + +# ERROR-COUNT-56: error: +# ERROR-NOT: error: +## R bit + +# CHECK: leal (%rax), %r16d +# CHECK: encoding: [0xd5,0x40,0x8d,0x00] + leal (%rax), %r16d + +# CHECK: leal (%rax), %r17d +# CHECK: encoding: [0xd5,0x40,0x8d,0x08] + leal (%rax), %r17d + +# CHECK: leal (%rax), %r18d +# CHECK: encoding: [0xd5,0x40,0x8d,0x10] + leal (%rax), %r18d + +# CHECK: leal (%rax), %r19d +# CHECK: encoding: [0xd5,0x40,0x8d,0x18] + leal (%rax), %r19d + +# CHECK: leal (%rax), %r20d +# CHECK: encoding: [0xd5,0x40,0x8d,0x20] + leal (%rax), %r20d + +# CHECK: leal (%rax), %r21d +# CHECK: encoding: [0xd5,0x40,0x8d,0x28] + leal (%rax), %r21d + +# CHECK: leal (%rax), %r22d +# CHECK: encoding: [0xd5,0x40,0x8d,0x30] + leal (%rax), %r22d + +# CHECK: leal (%rax), %r23d +# CHECK: encoding: [0xd5,0x40,0x8d,0x38] + leal (%rax), %r23d + +# CHECK: leal (%rax), %r24d +# CHECK: encoding: [0xd5,0x44,0x8d,0x00] + leal (%rax), %r24d + +# CHECK: leal (%rax), %r25d +# CHECK: encoding: [0xd5,0x44,0x8d,0x08] + leal (%rax), %r25d + +# CHECK: leal (%rax), %r26d +# CHECK: encoding: [0xd5,0x44,0x8d,0x10] + leal (%rax), %r26d + +# CHECK: leal (%rax), %r27d +# CHECK: encoding: [0xd5,0x44,0x8d,0x18] + leal (%rax), %r27d + +# CHECK: leal (%rax), %r28d +# CHECK: encoding: [0xd5,0x44,0x8d,0x20] + leal (%rax), %r28d + +# CHECK: leal (%rax), %r29d +# CHECK: encoding: [0xd5,0x44,0x8d,0x28] + leal (%rax), %r29d + +# CHECK: leal (%rax), %r30d +# CHECK: encoding: [0xd5,0x44,0x8d,0x30] + leal (%rax), %r30d + +# CHECK: leal (%rax), %r31d +# CHECK: encoding: [0xd5,0x44,0x8d,0x38] + leal (%rax), %r31d + +## X bit + +# CHECK: leal (,%r16), %eax +# CHECK: encoding: [0xd5,0x20,0x8d,0x04,0x05,0x00,0x00,0x00,0x00] + leal (,%r16), %eax + +# CHECK: leal (,%r17), %eax +# CHECK: encoding: [0xd5,0x20,0x8d,0x04,0x0d,0x00,0x00,0x00,0x00] + leal (,%r17), %eax + +# CHECK: leal (,%r18), %eax +# CHECK: encoding: [0xd5,0x20,0x8d,0x04,0x15,0x00,0x00,0x00,0x00] + leal (,%r18), %eax + +# CHECK: leal (,%r19), %eax +# CHECK: encoding: [0xd5,0x20,0x8d,0x04,0x1d,0x00,0x00,0x00,0x00] + leal (,%r19), %eax + +# CHECK: leal (,%r20), %eax +# CHECK: encoding: [0xd5,0x20,0x8d,0x04,0x25,0x00,0x00,0x00,0x00] + leal (,%r20), %eax + +# CHECK: leal (,%r21), %eax +# CHECK: encoding: [0xd5,0x20,0x8d,0x04,0x2d,0x00,0x00,0x00,0x00] + leal (,%r21), %eax + +# CHECK: leal (,%r22), %eax +# CHECK: encoding: [0xd5,0x20,0x8d,0x04,0x35,0x00,0x00,0x00,0x00] + leal (,%r22), %eax + +# CHECK: leal (,%r23), %eax +# CHECK: encoding: [0xd5,0x20,0x8d,0x04,0x3d,0x00,0x00,0x00,0x00] + leal (,%r23), %eax + +# CHECK: leal (,%r24), %eax +# CHECK: encoding: [0xd5,0x22,0x8d,0x04,0x05,0x00,0x00,0x00,0x00] + leal (,%r24), %eax + +# CHECK: leal (,%r25), %eax +# CHECK: encoding: [0xd5,0x22,0x8d,0x04,0x0d,0x00,0x00,0x00,0x00] + leal (,%r25), %eax + +# CHECK: leal (,%r26), %eax +# CHECK: encoding: [0xd5,0x22,0x8d,0x04,0x15,0x00,0x00,0x00,0x00] + leal (,%r26), %eax + +# CHECK: leal (,%r27), %eax +# CHECK: encoding: [0xd5,0x22,0x8d,0x04,0x1d,0x00,0x00,0x00,0x00] + leal (,%r27), %eax + +# CHECK: leal (,%r28), %eax +# CHECK: encoding: [0xd5,0x22,0x8d,0x04,0x25,0x00,0x00,0x00,0x00] + leal (,%r28), %eax + +# CHECK: leal (,%r29), %eax +# CHECK: encoding: [0xd5,0x22,0x8d,0x04,0x2d,0x00,0x00,0x00,0x00] + leal (,%r29), %eax + +# CHECK: leal (,%r30), %eax +# CHECK: encoding: [0xd5,0x22,0x8d,0x04,0x35,0x00,0x00,0x00,0x00] + leal (,%r30), %eax + +# CHECK: leal (,%r31), %eax +# CHECK: encoding: [0xd5,0x22,0x8d,0x04,0x3d,0x00,0x00,0x00,0x00] + leal (,%r31), %eax + +## B bit + +# CHECK: leal (%r16), %eax +# CHECK: encoding: [0xd5,0x10,0x8d,0x00] + leal (%r16), %eax + +# CHECK: leal (%r17), %eax +# CHECK: encoding: [0xd5,0x10,0x8d,0x01] + leal (%r17), %eax + +# CHECK: leal (%r18), %eax +# CHECK: encoding: [0xd5,0x10,0x8d,0x02] + leal (%r18), %eax + +# CHECK: leal (%r19), %eax +# CHECK: encoding: [0xd5,0x10,0x8d,0x03] + leal (%r19), %eax + +# CHECK: leal (%r20), %eax +# CHECK: encoding: [0xd5,0x10,0x8d,0x04,0x24] + leal (%r20), %eax + +# CHECK: leal (%r21), %eax +# CHECK: encoding: [0xd5,0x10,0x8d,0x45,0x00] + leal (%r21), %eax + +# CHECK: leal (%r22), %eax +# CHECK: encoding: [0xd5,0x10,0x8d,0x06] + leal (%r22), %eax + +# CHECK: leal (%r23), %eax +# CHECK: encoding: [0xd5,0x10,0x8d,0x07] + leal (%r23), %eax + +# CHECK: leal (%r24), %eax +# CHECK: encoding: [0xd5,0x11,0x8d,0x00] + leal (%r24), %eax + +# CHECK: leal (%r25), %eax +# CHECK: encoding: [0xd5,0x11,0x8d,0x01] + leal (%r25), %eax + +# CHECK: leal (%r26), %eax +# CHECK: encoding: [0xd5,0x11,0x8d,0x02] + leal (%r26), %eax + +# CHECK: leal (%r27), %eax +# CHECK: encoding: [0xd5,0x11,0x8d,0x03] + leal (%r27), %eax + +# CHECK: leal (%r28), %eax +# CHECK: encoding: [0xd5,0x11,0x8d,0x04,0x24] + leal (%r28), %eax + +# CHECK: leal (%r29), %eax +# CHECK: encoding: [0xd5,0x11,0x8d,0x45,0x00] + leal (%r29), %eax + +# CHECK: leal (%r30), %eax +# CHECK: encoding: [0xd5,0x11,0x8d,0x06] + leal (%r30), %eax + +# CHECK: leal (%r31), %eax +# CHECK: encoding: [0xd5,0x11,0x8d,0x07] + leal (%r31), %eax + +## SIB + +# CHECK: leal 1(%r20), %eax +# CHECK: encoding: [0xd5,0x10,0x8d,0x44,0x24,0x01] + leal 1(%r20), %eax + +# CHECK: leal 1(%r28), %eax +# CHECK: encoding: [0xd5,0x11,0x8d,0x44,0x24,0x01] + leal 1(%r28), %eax + +# CHECK: leal 129(%r20), %eax +# CHECK: encoding: [0xd5,0x10,0x8d,0x84,0x24,0x81,0x00,0x00,0x00] + leal 129(%r20), %eax + +# CHECK: leal 129(%r28), %eax +# CHECK: encoding: [0xd5,0x11,0x8d,0x84,0x24,0x81,0x00,0x00,0x00] + leal 129(%r28), %eax + +## W bit + +# CHECK: leaq (%rax), %r16 +# CHECK: encoding: [0xd5,0x48,0x8d,0x00] + leaq (%rax), %r16 + +# CHECK: leaq (%r16), %rax +# CHECK: encoding: [0xd5,0x18,0x8d,0x00] + leaq (%r16), %rax + +# CHECK: leaq (,%r16), %rax +# CHECK: encoding: [0xd5,0x28,0x8d,0x04,0x05,0x00,0x00,0x00,0x00] + leaq (,%r16), %rax + +## M bit + +# CHECK: imull %eax, %r16d +# CHECK: encoding: [0xd5,0xc0,0xaf,0xc0] + imull %eax, %r16d diff --git a/llvm/test/MC/X86/apx/rex2-bit-intel.s b/llvm/test/MC/X86/apx/rex2-bit-intel.s new file mode 100644 index 0000000000000..492c599a3662d --- /dev/null +++ b/llvm/test/MC/X86/apx/rex2-bit-intel.s @@ -0,0 +1,237 @@ +# RUN: llvm-mc -triple x86_64 -show-encoding -x86-asm-syntax=intel -output-asm-variant=1 %s | FileCheck %s + +## R bit + +# CHECK: lea r16d, [rax] +# CHECK: encoding: [0xd5,0x40,0x8d,0x00] + lea r16d, [rax] + +# CHECK: lea r17d, [rax] +# CHECK: encoding: [0xd5,0x40,0x8d,0x08] + lea r17d, [rax] + +# CHECK: lea r18d, [rax] +# CHECK: encoding: [0xd5,0x40,0x8d,0x10] + lea r18d, [rax] + +# CHECK: lea r19d, [rax] +# CHECK: encoding: [0xd5,0x40,0x8d,0x18] + lea r19d, [rax] + +# CHECK: lea r20d, [rax] +# CHECK: encoding: [0xd5,0x40,0x8d,0x20] + lea r20d, [rax] + +# CHECK: lea r21d, [rax] +# CHECK: encoding: [0xd5,0x40,0x8d,0x28] + lea r21d, [rax] + +# CHECK: lea r22d, [rax] +# CHECK: encoding: [0xd5,0x40,0x8d,0x30] + lea r22d, [rax] + +# CHECK: lea r23d, [rax] +# CHECK: encoding: [0xd5,0x40,0x8d,0x38] + lea r23d, [rax] + +# CHECK: lea r24d, [rax] +# CHECK: encoding: [0xd5,0x44,0x8d,0x00] + lea r24d, [rax] + +# CHECK: lea r25d, [rax] +# CHECK: encoding: [0xd5,0x44,0x8d,0x08] + lea r25d, [rax] + +# CHECK: lea r26d, [rax] +# CHECK: encoding: [0xd5,0x44,0x8d,0x10] + lea r26d, [rax] + +# CHECK: lea r27d, [rax] +# CHECK: encoding: [0xd5,0x44,0x8d,0x18] + lea r27d, [rax] + +# CHECK: lea r28d, [rax] +# CHECK: encoding: [0xd5,0x44,0x8d,0x20] + lea r28d, [rax] + +# CHECK: lea r29d, [rax] +# CHECK: encoding: [0xd5,0x44,0x8d,0x28] + lea r29d, [rax] + +# CHECK: lea r30d, [rax] +# CHECK: encoding: [0xd5,0x44,0x8d,0x30] + lea r30d, [rax] + +# CHECK: lea r31d, [rax] +# CHECK: encoding: [0xd5,0x44,0x8d,0x38] + lea r31d, [rax] + +## X bit + +# CHECK: lea eax, [1*r16] +# CHECK: encoding: [0xd5,0x20,0x8d,0x04,0x05,0x00,0x00,0x00,0x00] + lea eax, [1*r16] + +# CHECK: lea eax, [1*r17] +# CHECK: encoding: [0xd5,0x20,0x8d,0x04,0x0d,0x00,0x00,0x00,0x00] + lea eax, [1*r17] + +# CHECK: lea eax, [1*r18] +# CHECK: encoding: [0xd5,0x20,0x8d,0x04,0x15,0x00,0x00,0x00,0x00] + lea eax, [1*r18] + +# CHECK: lea eax, [1*r19] +# CHECK: encoding: [0xd5,0x20,0x8d,0x04,0x1d,0x00,0x00,0x00,0x00] + lea eax, [1*r19] + +# CHECK: lea eax, [1*r20] +# CHECK: encoding: [0xd5,0x20,0x8d,0x04,0x25,0x00,0x00,0x00,0x00] + lea eax, [1*r20] + +# CHECK: lea eax, [1*r21] +# CHECK: encoding: [0xd5,0x20,0x8d,0x04,0x2d,0x00,0x00,0x00,0x00] + lea eax, [1*r21] + +# CHECK: lea eax, [1*r22] +# CHECK: encoding: [0xd5,0x20,0x8d,0x04,0x35,0x00,0x00,0x00,0x00] + lea eax, [1*r22] + +# CHECK: lea eax, [1*r23] +# CHECK: encoding: [0xd5,0x20,0x8d,0x04,0x3d,0x00,0x00,0x00,0x00] + lea eax, [1*r23] + +# CHECK: lea eax, [1*r24] +# CHECK: encoding: [0xd5,0x22,0x8d,0x04,0x05,0x00,0x00,0x00,0x00] + lea eax, [1*r24] + +# CHECK: lea eax, [1*r25] +# CHECK: encoding: [0xd5,0x22,0x8d,0x04,0x0d,0x00,0x00,0x00,0x00] + lea eax, [1*r25] + +# CHECK: lea eax, [1*r26] +# CHECK: encoding: [0xd5,0x22,0x8d,0x04,0x15,0x00,0x00,0x00,0x00] + lea eax, [1*r26] + +# CHECK: lea eax, [1*r27] +# CHECK: encoding: [0xd5,0x22,0x8d,0x04,0x1d,0x00,0x00,0x00,0x00] + lea eax, [1*r27] + +# CHECK: lea eax, [1*r28] +# CHECK: encoding: [0xd5,0x22,0x8d,0x04,0x25,0x00,0x00,0x00,0x00] + lea eax, [1*r28] + +# CHECK: lea eax, [1*r29] +# CHECK: encoding: [0xd5,0x22,0x8d,0x04,0x2d,0x00,0x00,0x00,0x00] + lea eax, [1*r29] + +# CHECK: lea eax, [1*r30] +# CHECK: encoding: [0xd5,0x22,0x8d,0x04,0x35,0x00,0x00,0x00,0x00] + lea eax, [1*r30] + +# CHECK: lea eax, [1*r31] +# CHECK: encoding: [0xd5,0x22,0x8d,0x04,0x3d,0x00,0x00,0x00,0x00] + lea eax, [1*r31] + +## B bit + +# CHECK: lea eax, [r16] +# CHECK: encoding: [0xd5,0x10,0x8d,0x00] + lea eax, [r16] + +# CHECK: lea eax, [r17] +# CHECK: encoding: [0xd5,0x10,0x8d,0x01] + lea eax, [r17] + +# CHECK: lea eax, [r18] +# CHECK: encoding: [0xd5,0x10,0x8d,0x02] + lea eax, [r18] + +# CHECK: lea eax, [r19] +# CHECK: encoding: [0xd5,0x10,0x8d,0x03] + lea eax, [r19] + +# CHECK: lea eax, [r20] +# CHECK: encoding: [0xd5,0x10,0x8d,0x04,0x24] + lea eax, [r20] + +# CHECK: lea eax, [r21] +# CHECK: encoding: [0xd5,0x10,0x8d,0x45,0x00] + lea eax, [r21] + +# CHECK: lea eax, [r22] +# CHECK: encoding: [0xd5,0x10,0x8d,0x06] + lea eax, [r22] + +# CHECK: lea eax, [r23] +# CHECK: encoding: [0xd5,0x10,0x8d,0x07] + lea eax, [r23] + +# CHECK: lea eax, [r24] +# CHECK: encoding: [0xd5,0x11,0x8d,0x00] + lea eax, [r24] + +# CHECK: lea eax, [r25] +# CHECK: encoding: [0xd5,0x11,0x8d,0x01] + lea eax, [r25] + +# CHECK: lea eax, [r26] +# CHECK: encoding: [0xd5,0x11,0x8d,0x02] + lea eax, [r26] + +# CHECK: lea eax, [r27] +# CHECK: encoding: [0xd5,0x11,0x8d,0x03] + lea eax, [r27] + +# CHECK: lea eax, [r28] +# CHECK: encoding: [0xd5,0x11,0x8d,0x04,0x24] + lea eax, [r28] + +# CHECK: lea eax, [r29] +# CHECK: encoding: [0xd5,0x11,0x8d,0x45,0x00] + lea eax, [r29] + +# CHECK: lea eax, [r30] +# CHECK: encoding: [0xd5,0x11,0x8d,0x06] + lea eax, [r30] + +# CHECK: lea eax, [r31] +# CHECK: encoding: [0xd5,0x11,0x8d,0x07] + lea eax, [r31] + +## SIB + +# CHECK: lea eax, [r20 + 1] +# CHECK: encoding: [0xd5,0x10,0x8d,0x44,0x24,0x01] + lea eax, [r20 + 1] + +# CHECK: lea eax, [r28 + 1] +# CHECK: encoding: [0xd5,0x11,0x8d,0x44,0x24,0x01] + lea eax, [r28 + 1] + +# CHECK: lea eax, [r20 + 129] +# CHECK: encoding: [0xd5,0x10,0x8d,0x84,0x24,0x81,0x00,0x00,0x00] + lea eax, [r20 + 129] + +# CHECK: lea eax, [r28 + 129] +# CHECK: encoding: [0xd5,0x11,0x8d,0x84,0x24,0x81,0x00,0x00,0x00] + lea eax, [r28 + 129] + +## W bit + +# CHECK: lea r16, [rax] +# CHECK: encoding: [0xd5,0x48,0x8d,0x00] + lea r16, [rax] + +# CHECK: lea rax, [r16] +# CHECK: encoding: [0xd5,0x18,0x8d,0x00] + lea rax, [r16] + +# CHECK: lea rax, [1*r16] +# CHECK: encoding: [0xd5,0x28,0x8d,0x04,0x05,0x00,0x00,0x00,0x00] + lea rax, [1*r16] + +## M bit + +# CHECK: imul r16d, eax +# CHECK: encoding: [0xd5,0xc0,0xaf,0xc0] + imul r16d, eax diff --git a/llvm/test/MC/X86/apx/rex2-format-att.s b/llvm/test/MC/X86/apx/rex2-format-att.s new file mode 100644 index 0000000000000..3dacd2a82876a --- /dev/null +++ b/llvm/test/MC/X86/apx/rex2-format-att.s @@ -0,0 +1,343 @@ +# RUN: llvm-mc -triple x86_64 -show-encoding %s | FileCheck %s + +## AddRegFrm + +# CHECK: movl $1, %r16d +# CHECK: encoding: [0xd5,0x10,0xb8,0x01,0x00,0x00,0x00] + movl $1, %r16d + +## MRMSrcReg + +# CHECK: movslq %r16d, %rax +# CHECK: encoding: [0xd5,0x18,0x63,0xc0] + movslq %r16d, %rax + +# CHECK: movslq %eax, %r16 +# CHECK: encoding: [0xd5,0x48,0x63,0xc0] + movslq %eax, %r16 + +# CHECK: movslq %r16d, %r17 +# CHECK: encoding: [0xd5,0x58,0x63,0xc8] + movslq %r16d, %r17 + +## MRMSrcRegCC + +# CHECK: cmovll %r16d, %eax +# CHECK: encoding: [0xd5,0x90,0x4c,0xc0] + cmovll %r16d, %eax + +# CHECK: cmovll %eax, %r16d +# CHECK: encoding: [0xd5,0xc0,0x4c,0xc0] + cmovll %eax, %r16d + +# CHECK: cmovll %r16d, %r17d +# CHECK: encoding: [0xd5,0xd0,0x4c,0xc8] + cmovll %r16d, %r17d + +## MRMSrcMem + +# CHECK: imull (%r16,%rax), %ebx +# CHECK: encoding: [0xd5,0x90,0xaf,0x1c,0x00] + imull (%r16,%rax), %ebx + +# CHECK: imull (%rax,%r16), %ebx +# CHECK: encoding: [0xd5,0xa0,0xaf,0x1c,0x00] + imull (%rax,%r16), %ebx + +# CHECK: imull (%rax,%rbx), %r16d +# CHECK: encoding: [0xd5,0xc0,0xaf,0x04,0x18] + imull (%rax,%rbx), %r16d + +# CHECK: imull (%r16,%r17), %eax +# CHECK: encoding: [0xd5,0xb0,0xaf,0x04,0x08] + imull (%r16,%r17), %eax + +# CHECK: imull (%rax,%r16), %r17d +# CHECK: encoding: [0xd5,0xe0,0xaf,0x0c,0x00] + imull (%rax,%r16), %r17d + +# CHECK: imull (%r16,%rax), %r17d +# CHECK: encoding: [0xd5,0xd0,0xaf,0x0c,0x00] + imull (%r16,%rax), %r17d + +# CHECK: imull (%r16,%r17), %r18d +# CHECK: encoding: [0xd5,0xf0,0xaf,0x14,0x08] + imull (%r16,%r17), %r18d + +## MRMSrcMemCC + +# CHECK: cmovll (%r16,%rax), %ebx +# CHECK: encoding: [0xd5,0x90,0x4c,0x1c,0x00] + cmovll (%r16,%rax), %ebx + +# CHECK: cmovll (%rax,%r16), %ebx +# CHECK: encoding: [0xd5,0xa0,0x4c,0x1c,0x00] + cmovll (%rax,%r16), %ebx + +# CHECK: cmovll (%rax,%rbx), %r16d +# CHECK: encoding: [0xd5,0xc0,0x4c,0x04,0x18] + cmovll (%rax,%rbx), %r16d + +# CHECK: cmovll (%r16,%r17), %eax +# CHECK: encoding: [0xd5,0xb0,0x4c,0x04,0x08] + cmovll (%r16,%r17), %eax + +# CHECK: cmovll (%rax,%r16), %r17d +# CHECK: encoding: [0xd5,0xe0,0x4c,0x0c,0x00] + cmovll (%rax,%r16), %r17d + +# CHECK: cmovll (%r16,%rax), %r17d +# CHECK: encoding: [0xd5,0xd0,0x4c,0x0c,0x00] + cmovll (%r16,%rax), %r17d + +# CHECK: cmovll (%r16,%r17), %r18d +# CHECK: encoding: [0xd5,0xf0,0x4c,0x14,0x08] + cmovll (%r16,%r17), %r18d + +## MRMDestReg + +# CHECK: movl %eax, %r16d +# CHECK: encoding: [0xd5,0x10,0x89,0xc0] + movl %eax, %r16d + +# CHECK: movl %r16d, %eax +# CHECK: encoding: [0xd5,0x40,0x89,0xc0] + movl %r16d, %eax + +# CHECK: movl %r16d, %r17d +# CHECK: encoding: [0xd5,0x50,0x89,0xc1] + movl %r16d, %r17d + +## MRMDestMem + +# CHECK: movl %ebx, (%r16,%rax) +# CHECK: encoding: [0xd5,0x10,0x89,0x1c,0x00] + movl %ebx, (%r16,%rax) + +# CHECK: movl %ebx, (%rax,%r16) +# CHECK: encoding: [0xd5,0x20,0x89,0x1c,0x00] + movl %ebx, (%rax,%r16) + +# CHECK: movl %r16d, (%rax,%rbx) +# CHECK: encoding: [0xd5,0x40,0x89,0x04,0x18] + movl %r16d, (%rax,%rbx) + +# CHECK: movl %eax, (%r16,%r17) +# CHECK: encoding: [0xd5,0x30,0x89,0x04,0x08] + movl %eax, (%r16,%r17) + +# CHECK: movl %r17d, (%rax,%r16) +# CHECK: encoding: [0xd5,0x60,0x89,0x0c,0x00] + movl %r17d, (%rax,%r16) + +# CHECK: movl %r17d, (%r16,%rax) +# CHECK: encoding: [0xd5,0x50,0x89,0x0c,0x00] + movl %r17d, (%r16,%rax) + +# CHECK: movl %r18d, (%r16,%r17) +# CHECK: encoding: [0xd5,0x70,0x89,0x14,0x08] + movl %r18d, (%r16,%r17) + +# CHECK: movb %bpl, (%r16,%r14) +# CHECK: encoding: [0xd5,0x12,0x88,0x2c,0x30] + movb %bpl, (%r16,%r14) + +## MRMXmCC + +# CHECK: sete (%rax,%r16) +# CHECK: encoding: [0xd5,0xa0,0x94,0x04,0x00] + sete (%rax,%r16) + +# CHECK: sete (%r16,%rax) +# CHECK: encoding: [0xd5,0x90,0x94,0x04,0x00] + sete (%r16,%rax) + +# CHECK: sete (%r16,%r17) +# CHECK: encoding: [0xd5,0xb0,0x94,0x04,0x08] + sete (%r16,%r17) + +## MRMXm + +# CHECK: nopl (%rax,%r16) +# CHECK: encoding: [0xd5,0xa0,0x1f,0x04,0x00] + nopl (%rax,%r16) + +# CHECK: nopl (%r16,%rax) +# CHECK: encoding: [0xd5,0x90,0x1f,0x04,0x00] + nopl (%r16,%rax) + +# CHECK: nopl (%r16,%r17) +# CHECK: encoding: [0xd5,0xb0,0x1f,0x04,0x08] + nopl (%r16,%r17) + +## MRM0m + +# CHECK: incl (%rax,%r16) +# CHECK: encoding: [0xd5,0x20,0xff,0x04,0x00] + incl (%rax,%r16) + +# CHECK: incl (%r16,%rax) +# CHECK: encoding: [0xd5,0x10,0xff,0x04,0x00] + incl (%r16,%rax) + +# CHECK: incl (%r16,%r17) +# CHECK: encoding: [0xd5,0x30,0xff,0x04,0x08] + incl (%r16,%r17) + +## MRM1m + +# CHECK: decl (%rax,%r16) +# CHECK: encoding: [0xd5,0x20,0xff,0x0c,0x00] + decl (%rax,%r16) + +# CHECK: decl (%r16,%rax) +# CHECK: encoding: [0xd5,0x10,0xff,0x0c,0x00] + decl (%r16,%rax) + +# CHECK: decl (%r16,%r17) +# CHECK: encoding: [0xd5,0x30,0xff,0x0c,0x08] + decl (%r16,%r17) + +## MRM2m + +# CHECK: notl (%rax,%r16) +# CHECK: encoding: [0xd5,0x20,0xf7,0x14,0x00] + notl (%rax,%r16) + +# CHECK: notl (%r16,%rax) +# CHECK: encoding: [0xd5,0x10,0xf7,0x14,0x00] + notl (%r16,%rax) + +# CHECK: notl (%r16,%r17) +# CHECK: encoding: [0xd5,0x30,0xf7,0x14,0x08] + notl (%r16,%r17) + +## MRM3m + +# CHECK: negl (%rax,%r16) +# CHECK: encoding: [0xd5,0x20,0xf7,0x1c,0x00] + negl (%rax,%r16) + +# CHECK: negl (%r16,%rax) +# CHECK: encoding: [0xd5,0x10,0xf7,0x1c,0x00] + negl (%r16,%rax) + +# CHECK: negl (%r16,%r17) +# CHECK: encoding: [0xd5,0x30,0xf7,0x1c,0x08] + negl (%r16,%r17) + +## MRM4m + +# CHECK: mull (%rax,%r16) +# CHECK: encoding: [0xd5,0x20,0xf7,0x24,0x00] + mull (%rax,%r16) + +# CHECK: mull (%r16,%rax) +# CHECK: encoding: [0xd5,0x10,0xf7,0x24,0x00] + mull (%r16,%rax) + +# CHECK: mull (%r16,%r17) +# CHECK: encoding: [0xd5,0x30,0xf7,0x24,0x08] + mull (%r16,%r17) + +## MRM5m + +# CHECK: imull (%rax,%r16) +# CHECK: encoding: [0xd5,0x20,0xf7,0x2c,0x00] + imull (%rax,%r16) + +# CHECK: imull (%r16,%rax) +# CHECK: encoding: [0xd5,0x10,0xf7,0x2c,0x00] + imull (%r16,%rax) + +# CHECK: imull (%r16,%r17) +# CHECK: encoding: [0xd5,0x30,0xf7,0x2c,0x08] + imull (%r16,%r17) + +## MRM6m + +# CHECK: divl (%rax,%r16) +# CHECK: encoding: [0xd5,0x20,0xf7,0x34,0x00] + divl (%rax,%r16) + +# CHECK: divl (%r16,%rax) +# CHECK: encoding: [0xd5,0x10,0xf7,0x34,0x00] + divl (%r16,%rax) + +# CHECK: divl (%r16,%r17) +# CHECK: encoding: [0xd5,0x30,0xf7,0x34,0x08] + divl (%r16,%r17) + +## MRM7m + +# CHECK: idivl (%rax,%r16) +# CHECK: encoding: [0xd5,0x20,0xf7,0x3c,0x00] + idivl (%rax,%r16) + +# CHECK: idivl (%r16,%rax) +# CHECK: encoding: [0xd5,0x10,0xf7,0x3c,0x00] + idivl (%r16,%rax) + +# CHECK: idivl (%r16,%r17) +# CHECK: encoding: [0xd5,0x30,0xf7,0x3c,0x08] + idivl (%r16,%r17) + +## MRMXrCC + +# CHECK: sete %r16b +# CHECK: encoding: [0xd5,0x90,0x94,0xc0] + sete %r16b + +## MRMXr + +# CHECK: nopl %r16d +# CHECK: encoding: [0xd5,0x90,0x1f,0xc0] + nopl %r16d + +## MRM0r + +# CHECK: incl %r16d +# CHECK: encoding: [0xd5,0x10,0xff,0xc0] + incl %r16d + +## MRM1r + +# CHECK: decl %r16d +# CHECK: encoding: [0xd5,0x10,0xff,0xc8] + decl %r16d + +## MRM2r + +# CHECK: notl %r16d +# CHECK: encoding: [0xd5,0x10,0xf7,0xd0] + notl %r16d + +## MRM3r + +# CHECK: negl %r16d +# CHECK: encoding: [0xd5,0x10,0xf7,0xd8] + negl %r16d + +## MRM4r + +# CHECK: mull %r16d +# CHECK: encoding: [0xd5,0x10,0xf7,0xe0] + mull %r16d + +## MRM5r + +# CHECK: imull %r16d +# CHECK: encoding: [0xd5,0x10,0xf7,0xe8] + imull %r16d + +## MRM6r + +# CHECK: divl %r16d +# CHECK: encoding: [0xd5,0x10,0xf7,0xf0] + divl %r16d + +## MRM7r + +# CHECK: idivl %r16d +# CHECK: encoding: [0xd5,0x10,0xf7,0xf8] + idivl %r16d diff --git a/llvm/test/MC/X86/apx/rex2-format-intel.s b/llvm/test/MC/X86/apx/rex2-format-intel.s new file mode 100644 index 0000000000000..935bd86537af1 --- /dev/null +++ b/llvm/test/MC/X86/apx/rex2-format-intel.s @@ -0,0 +1,343 @@ +# RUN: llvm-mc -triple x86_64 -show-encoding -x86-asm-syntax=intel -output-asm-variant=1 %s | FileCheck %s + +## AddRegFrm + +# CHECK: mov r16d, 1 +# CHECK: encoding: [0xd5,0x10,0xb8,0x01,0x00,0x00,0x00] + mov r16d, 1 + +## MRMSrcReg + +# CHECK: movsxd rax, r16d +# CHECK: encoding: [0xd5,0x18,0x63,0xc0] + movsxd rax, r16d + +# CHECK: movsxd r16, eax +# CHECK: encoding: [0xd5,0x48,0x63,0xc0] + movsxd r16, eax + +# CHECK: movsxd r17, r16d +# CHECK: encoding: [0xd5,0x58,0x63,0xc8] + movsxd r17, r16d + +## MRMSrcRegCC + +# CHECK: cmovl eax, r16d +# CHECK: encoding: [0xd5,0x90,0x4c,0xc0] + cmovl eax, r16d + +# CHECK: cmovl r16d, eax +# CHECK: encoding: [0xd5,0xc0,0x4c,0xc0] + cmovl r16d, eax + +# CHECK: cmovl r17d, r16d +# CHECK: encoding: [0xd5,0xd0,0x4c,0xc8] + cmovl r17d, r16d + +## MRMSrcMem + +# CHECK: imul ebx, dword ptr [r16 + rax] +# CHECK: encoding: [0xd5,0x90,0xaf,0x1c,0x00] + imul ebx, dword ptr [r16 + rax] + +# CHECK: imul ebx, dword ptr [rax + r16] +# CHECK: encoding: [0xd5,0xa0,0xaf,0x1c,0x00] + imul ebx, dword ptr [rax + r16] + +# CHECK: imul r16d, dword ptr [rax + rbx] +# CHECK: encoding: [0xd5,0xc0,0xaf,0x04,0x18] + imul r16d, dword ptr [rax + rbx] + +# CHECK: imul eax, dword ptr [r16 + r17] +# CHECK: encoding: [0xd5,0xb0,0xaf,0x04,0x08] + imul eax, dword ptr [r16 + r17] + +# CHECK: imul r17d, dword ptr [rax + r16] +# CHECK: encoding: [0xd5,0xe0,0xaf,0x0c,0x00] + imul r17d, dword ptr [rax + r16] + +# CHECK: imul r17d, dword ptr [r16 + rax] +# CHECK: encoding: [0xd5,0xd0,0xaf,0x0c,0x00] + imul r17d, dword ptr [r16 + rax] + +# CHECK: imul r18d, dword ptr [r16 + r17] +# CHECK: encoding: [0xd5,0xf0,0xaf,0x14,0x08] + imul r18d, dword ptr [r16 + r17] + +## MRMSrcMemCC + +# CHECK: cmovl ebx, dword ptr [r16 + rax] +# CHECK: encoding: [0xd5,0x90,0x4c,0x1c,0x00] + cmovl ebx, dword ptr [r16 + rax] + +# CHECK: cmovl ebx, dword ptr [rax + r16] +# CHECK: encoding: [0xd5,0xa0,0x4c,0x1c,0x00] + cmovl ebx, dword ptr [rax + r16] + +# CHECK: cmovl r16d, dword ptr [rax + rbx] +# CHECK: encoding: [0xd5,0xc0,0x4c,0x04,0x18] + cmovl r16d, dword ptr [rax + rbx] + +# CHECK: cmovl eax, dword ptr [r16 + r17] +# CHECK: encoding: [0xd5,0xb0,0x4c,0x04,0x08] + cmovl eax, dword ptr [r16 + r17] + +# CHECK: cmovl r17d, dword ptr [rax + r16] +# CHECK: encoding: [0xd5,0xe0,0x4c,0x0c,0x00] + cmovl r17d, dword ptr [rax + r16] + +# CHECK: cmovl r17d, dword ptr [r16 + rax] +# CHECK: encoding: [0xd5,0xd0,0x4c,0x0c,0x00] + cmovl r17d, dword ptr [r16 + rax] + +# CHECK: cmovl r18d, dword ptr [r16 + r17] +# CHECK: encoding: [0xd5,0xf0,0x4c,0x14,0x08] + cmovl r18d, dword ptr [r16 + r17] + +## MRMDestReg + +# CHECK: mov r16d, eax +# CHECK: encoding: [0xd5,0x10,0x89,0xc0] + mov r16d, eax + +# CHECK: mov eax, r16d +# CHECK: encoding: [0xd5,0x40,0x89,0xc0] + mov eax, r16d + +# CHECK: mov r17d, r16d +# CHECK: encoding: [0xd5,0x50,0x89,0xc1] + mov r17d, r16d + +## MRMDestMem + +# CHECK: mov dword ptr [r16 + rax], ebx +# CHECK: encoding: [0xd5,0x10,0x89,0x1c,0x00] + mov dword ptr [r16 + rax], ebx + +# CHECK: mov dword ptr [rax + r16], ebx +# CHECK: encoding: [0xd5,0x20,0x89,0x1c,0x00] + mov dword ptr [rax + r16], ebx + +# CHECK: mov dword ptr [rax + rbx], r16d +# CHECK: encoding: [0xd5,0x40,0x89,0x04,0x18] + mov dword ptr [rax + rbx], r16d + +# CHECK: mov dword ptr [r16 + r17], eax +# CHECK: encoding: [0xd5,0x30,0x89,0x04,0x08] + mov dword ptr [r16 + r17], eax + +# CHECK: mov dword ptr [rax + r16], r17d +# CHECK: encoding: [0xd5,0x60,0x89,0x0c,0x00] + mov dword ptr [rax + r16], r17d + +# CHECK: mov dword ptr [r16 + rax], r17d +# CHECK: encoding: [0xd5,0x50,0x89,0x0c,0x00] + mov dword ptr [r16 + rax], r17d + +# CHECK: mov dword ptr [r16 + r17], r18d +# CHECK: encoding: [0xd5,0x70,0x89,0x14,0x08] + mov dword ptr [r16 + r17], r18d + +# CHECK: mov byte ptr [r16 + r14], bpl +# CHECK: encoding: [0xd5,0x12,0x88,0x2c,0x30] + mov byte ptr [r16 + r14], bpl + +## MRMXmCC + +# CHECK: sete byte ptr [rax + r16] +# CHECK: encoding: [0xd5,0xa0,0x94,0x04,0x00] + sete byte ptr [rax + r16] + +# CHECK: sete byte ptr [r16 + rax] +# CHECK: encoding: [0xd5,0x90,0x94,0x04,0x00] + sete byte ptr [r16 + rax] + +# CHECK: sete byte ptr [r16 + r17] +# CHECK: encoding: [0xd5,0xb0,0x94,0x04,0x08] + sete byte ptr [r16 + r17] + +## MRMXm + +# CHECK: nop dword ptr [rax + r16] +# CHECK: encoding: [0xd5,0xa0,0x1f,0x04,0x00] + nop dword ptr [rax + r16] + +# CHECK: nop dword ptr [r16 + rax] +# CHECK: encoding: [0xd5,0x90,0x1f,0x04,0x00] + nop dword ptr [r16 + rax] + +# CHECK: nop dword ptr [r16 + r17] +# CHECK: encoding: [0xd5,0xb0,0x1f,0x04,0x08] + nop dword ptr [r16 + r17] + +## MRM0m + +# CHECK: inc dword ptr [rax + r16] +# CHECK: encoding: [0xd5,0x20,0xff,0x04,0x00] + inc dword ptr [rax + r16] + +# CHECK: inc dword ptr [r16 + rax] +# CHECK: encoding: [0xd5,0x10,0xff,0x04,0x00] + inc dword ptr [r16 + rax] + +# CHECK: inc dword ptr [r16 + r17] +# CHECK: encoding: [0xd5,0x30,0xff,0x04,0x08] + inc dword ptr [r16 + r17] + +## MRM1m + +# CHECK: dec dword ptr [rax + r16] +# CHECK: encoding: [0xd5,0x20,0xff,0x0c,0x00] + dec dword ptr [rax + r16] + +# CHECK: dec dword ptr [r16 + rax] +# CHECK: encoding: [0xd5,0x10,0xff,0x0c,0x00] + dec dword ptr [r16 + rax] + +# CHECK: dec dword ptr [r16 + r17] +# CHECK: encoding: [0xd5,0x30,0xff,0x0c,0x08] + dec dword ptr [r16 + r17] + +## MRM2m + +# CHECK: not dword ptr [rax + r16] +# CHECK: encoding: [0xd5,0x20,0xf7,0x14,0x00] + not dword ptr [rax + r16] + +# CHECK: not dword ptr [r16 + rax] +# CHECK: encoding: [0xd5,0x10,0xf7,0x14,0x00] + not dword ptr [r16 + rax] + +# CHECK: not dword ptr [r16 + r17] +# CHECK: encoding: [0xd5,0x30,0xf7,0x14,0x08] + not dword ptr [r16 + r17] + +## MRM3m + +# CHECK: neg dword ptr [rax + r16] +# CHECK: encoding: [0xd5,0x20,0xf7,0x1c,0x00] + neg dword ptr [rax + r16] + +# CHECK: neg dword ptr [r16 + rax] +# CHECK: encoding: [0xd5,0x10,0xf7,0x1c,0x00] + neg dword ptr [r16 + rax] + +# CHECK: neg dword ptr [r16 + r17] +# CHECK: encoding: [0xd5,0x30,0xf7,0x1c,0x08] + neg dword ptr [r16 + r17] + +## MRM4m + +# CHECK: mul dword ptr [rax + r16] +# CHECK: encoding: [0xd5,0x20,0xf7,0x24,0x00] + mul dword ptr [rax + r16] + +# CHECK: mul dword ptr [r16 + rax] +# CHECK: encoding: [0xd5,0x10,0xf7,0x24,0x00] + mul dword ptr [r16 + rax] + +# CHECK: mul dword ptr [r16 + r17] +# CHECK: encoding: [0xd5,0x30,0xf7,0x24,0x08] + mul dword ptr [r16 + r17] + +## MRM5m + +# CHECK: imul dword ptr [rax + r16] +# CHECK: encoding: [0xd5,0x20,0xf7,0x2c,0x00] + imul dword ptr [rax + r16] + +# CHECK: imul dword ptr [r16 + rax] +# CHECK: encoding: [0xd5,0x10,0xf7,0x2c,0x00] + imul dword ptr [r16 + rax] + +# CHECK: imul dword ptr [r16 + r17] +# CHECK: encoding: [0xd5,0x30,0xf7,0x2c,0x08] + imul dword ptr [r16 + r17] + +## MRM6m + +# CHECK: div dword ptr [rax + r16] +# CHECK: encoding: [0xd5,0x20,0xf7,0x34,0x00] + div dword ptr [rax + r16] + +# CHECK: div dword ptr [r16 + rax] +# CHECK: encoding: [0xd5,0x10,0xf7,0x34,0x00] + div dword ptr [r16 + rax] + +# CHECK: div dword ptr [r16 + r17] +# CHECK: encoding: [0xd5,0x30,0xf7,0x34,0x08] + div dword ptr [r16 + r17] + +## MRM7m + +# CHECK: idiv dword ptr [rax + r16] +# CHECK: encoding: [0xd5,0x20,0xf7,0x3c,0x00] + idiv dword ptr [rax + r16] + +# CHECK: idiv dword ptr [r16 + rax] +# CHECK: encoding: [0xd5,0x10,0xf7,0x3c,0x00] + idiv dword ptr [r16 + rax] + +# CHECK: idiv dword ptr [r16 + r17] +# CHECK: encoding: [0xd5,0x30,0xf7,0x3c,0x08] + idiv dword ptr [r16 + r17] + +## MRMXrCC + +# CHECK: sete r16b +# CHECK: encoding: [0xd5,0x90,0x94,0xc0] + sete r16b + +## MRMXr + +# CHECK: nop r16d +# CHECK: encoding: [0xd5,0x90,0x1f,0xc0] + nop r16d + +## MRM0r + +# CHECK: inc r16d +# CHECK: encoding: [0xd5,0x10,0xff,0xc0] + inc r16d + +## MRM1r + +# CHECK: dec r16d +# CHECK: encoding: [0xd5,0x10,0xff,0xc8] + dec r16d + +## MRM2r + +# CHECK: not r16d +# CHECK: encoding: [0xd5,0x10,0xf7,0xd0] + not r16d + +## MRM3r + +# CHECK: neg r16d +# CHECK: encoding: [0xd5,0x10,0xf7,0xd8] + neg r16d + +## MRM4r + +# CHECK: mul r16d +# CHECK: encoding: [0xd5,0x10,0xf7,0xe0] + mul r16d + +## MRM5r + +# CHECK: imul r16d +# CHECK: encoding: [0xd5,0x10,0xf7,0xe8] + imul r16d + +## MRM6r + +# CHECK: div r16d +# CHECK: encoding: [0xd5,0x10,0xf7,0xf0] + div r16d + +## MRM7r + +# CHECK: idiv r16d +# CHECK: encoding: [0xd5,0x10,0xf7,0xf8] + idiv r16d