5 changes: 5 additions & 0 deletions clang/test/Driver/x86-target-features.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,11 @@
// AVX512FP16: "-target-feature" "+avx512fp16"
// NO-AVX512FP16: "-target-feature" "-avx512fp16"

// RUN: %clang --target=x86_64 -mcmpccxadd %s -### -o %t.o 2>&1 | FileCheck -check-prefix=CMPCCXADD %s
// RUN: %clang --target=x86_64 -mno-cmpccxadd %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-CMPCCXADD %s
// CMPCCXADD: "-target-feature" "+cmpccxadd"
// NO-CMPCCXADD: "-target-feature" "-cmpccxadd"

// RUN: %clang --target=i386 -march=i386 -mcrc32 %s -### 2>&1 | FileCheck -check-prefix=CRC32 %s
// RUN: %clang --target=i386 -march=i386 -mno-crc32 %s -### 2>&1 | FileCheck -check-prefix=NO-CRC32 %s
// CRC32: "-target-feature" "+crc32"
Expand Down
8 changes: 8 additions & 0 deletions clang/test/Preprocessor/x86_target_features.c
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,14 @@
// AVX512FP16NOAVX512DQ-NOT: #define __AVX512DQ__ 1
// AVX512FP16NOAVX512DQ-NOT: #define __AVX512FP16__ 1

// RUN: %clang -target x86_64-unknown-linux-gnu -march=atom -mcmpccxadd -x c -E -dM -o - %s | FileCheck -check-prefix=CMPCCXADD %s

// CMPCCXADD: #define __CMPCCXADD__ 1

// RUN: %clang -target x86_64-unknown-linux-gnu -march=atom -mno-cmpccxadd -x c -E -dM -o - %s | FileCheck -check-prefix=NO-CMPCCXADD %s

// NO-CMPCCXADD-NOT: #define __CMPCCXADD__ 1

// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mcrc32 -x c -E -dM -o - %s | FileCheck -check-prefix=CRC32 %s

// CRC32: #define __CRC32__ 1
Expand Down
1 change: 1 addition & 0 deletions llvm/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ Changes to the X86 Backend
* Add support for the ``RDMSRLIST and WRMSRLIST`` instructions.
* Add support for the ``WRMSRNS`` instruction.
* Support ISA of ``AMX-FP16`` which contains ``tdpfp16ps`` instruction.
* Support ISA of ``CMPCCXADD``.

Changes to the OCaml bindings
-----------------------------
Expand Down
13 changes: 13 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsX86.td
Original file line number Diff line number Diff line change
Expand Up @@ -5115,6 +5115,19 @@ let TargetPrefix = "x86" in {
Intrinsic<[llvm_anyvector_ty], [llvm_x86amx_ty], [IntrNoMem]>;
}

let TargetPrefix = "x86" in {
def int_x86_cmpccxadd32
: ClangBuiltin<"__builtin_ia32_cmpccxadd32">,
Intrinsic<[llvm_i32_ty],
[llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrArgMemOnly, ImmArg<ArgIndex<3>>]>;

def int_x86_cmpccxadd64
: ClangBuiltin<"__builtin_ia32_cmpccxadd64">,
Intrinsic<[llvm_i64_ty],
[llvm_ptr_ty, llvm_i64_ty, llvm_i64_ty, llvm_i32_ty],
[IntrArgMemOnly, ImmArg<ArgIndex<3>>]>;
}
//===----------------------------------------------------------------------===//
let TargetPrefix = "x86" in {
// AMX_FP16 - Intel FP16 AMX extensions
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/Support/X86TargetParser.def
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ X86_FEATURE (XSAVES, "xsaves")
X86_FEATURE (HRESET, "hreset")
X86_FEATURE (AVX512FP16, "avx512fp16")
X86_FEATURE (AMX_FP16, "amx-fp16")
X86_FEATURE (CMPCCXADD, "cmpccxadd")
X86_FEATURE (AVXVNNI, "avxvnni")
// These features aren't really CPU features, but the frontend can set them.
X86_FEATURE (RETPOLINE_EXTERNAL_THUNK, "retpoline-external-thunk")
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Support/Host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1808,6 +1808,7 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
Features["avxvnni"] = HasLeaf7Subleaf1 && ((EAX >> 4) & 1) && HasAVXSave;
Features["avx512bf16"] = HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save;
Features["amx-fp16"] = HasLeaf7Subleaf1 && ((EAX >> 21) & 1) && HasAMXSave;
Features["cmpccxadd"] = HasLeaf7Subleaf1 && ((EAX >> 7) & 1);
Features["hreset"] = HasLeaf7Subleaf1 && ((EAX >> 22) & 1);
Features["prefetchi"] = HasLeaf7Subleaf1 && ((EDX >> 14) & 1);

Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Support/X86TargetParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,7 @@ constexpr FeatureBitset ImpliedFeaturesAMX_INT8 = FeatureAMX_TILE;
constexpr FeatureBitset ImpliedFeaturesHRESET = {};

constexpr FeatureBitset ImpliedFeaturesPREFETCHI = {};
constexpr FeatureBitset ImpliedFeaturesCMPCCXADD = {};
constexpr FeatureBitset ImpliedFeaturesAVX512FP16 =
FeatureAVX512BW | FeatureAVX512DQ | FeatureAVX512VL;
// Key Locker Features
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,11 @@ namespace X86II {
/// byte like data16 or rep.
PrefixByte = 10,

/// MRMDestMem4VOp3CC - This form is used for instructions that use the Mod/RM
/// byte to specify a destination which in this case is memory and operand 3
/// with VEX.VVVV, and also encodes a condition code.
MRMDestMem4VOp3CC = 20,

/// MRM[0-7][rm] - These forms are used to represent instructions that use
/// a Mod/RM byte, and use the middle field to hold extended opcode
/// information. In the intel manual these are represented as /0, /1, ...
Expand Down Expand Up @@ -1125,6 +1130,7 @@ namespace X86II {
// Skip registers encoded in reg, VEX_VVVV, and I8IMM.
return 3;
case X86II::MRMSrcMemCC:
case X86II::MRMDestMem4VOp3CC:
// Start from 1, skip any registers encoded in VEX_VVVV or I8IMM, or a
// mask register.
return 1;
Expand Down
14 changes: 8 additions & 6 deletions llvm/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,26 @@ using namespace llvm;
void X86InstPrinterCommon::printCondCode(const MCInst *MI, unsigned Op,
raw_ostream &O) {
int64_t Imm = MI->getOperand(Op).getImm();
bool Flavor = MI->getOpcode() == X86::CMPCCXADDmr32 ||
MI->getOpcode() == X86::CMPCCXADDmr64;
switch (Imm) {
default: llvm_unreachable("Invalid condcode argument!");
case 0: O << "o"; break;
case 1: O << "no"; break;
case 2: O << "b"; break;
case 3: O << "ae"; break;
case 4: O << "e"; break;
case 5: O << "ne"; break;
case 3: O << (Flavor ? "nb" : "ae"); break;
case 4: O << (Flavor ? "z" : "e"); break;
case 5: O << (Flavor ? "nz" : "ne"); break;
case 6: O << "be"; break;
case 7: O << "a"; break;
case 7: O << (Flavor ? "nbe" : "a"); break;
case 8: O << "s"; break;
case 9: O << "ns"; break;
case 0xa: O << "p"; break;
case 0xb: O << "np"; break;
case 0xc: O << "l"; break;
case 0xd: O << "ge"; break;
case 0xd: O << (Flavor ? "nl" : "ge"); break;
case 0xe: O << "le"; break;
case 0xf: O << "g"; break;
case 0xf: O << (Flavor ? "nle" : "g"); break;
}
}

Expand Down
26 changes: 26 additions & 0 deletions llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,23 @@ void X86MCCodeEmitter::emitVEXOpcodePrefix(int MemOperand, const MCInst &MI,
switch (TSFlags & X86II::FormMask) {
default:
llvm_unreachable("Unexpected form in emitVEXOpcodePrefix!");
case X86II::MRMDestMem4VOp3CC: {
// MemAddr, src1(ModR/M), src2(VEX_4V)
unsigned BaseRegEnc = getX86RegEncoding(MI, MemOperand + X86::AddrBaseReg);
VEX_B = ~(BaseRegEnc >> 3) & 1;
unsigned IndexRegEnc =
getX86RegEncoding(MI, MemOperand + X86::AddrIndexReg);
VEX_X = ~(IndexRegEnc >> 3) & 1;

CurOp += X86::AddrNumOperands;

unsigned RegEnc = getX86RegEncoding(MI, ++CurOp);
VEX_R = ~(RegEnc >> 3) & 1;

unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
VEX_4V = ~VRegEnc & 0xf;
break;
}
case X86II::MRM_C0:
case X86II::RawFrm:
case X86II::PrefixByte:
Expand Down Expand Up @@ -1429,6 +1446,15 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
CurOp = SrcRegNum + 1;
break;
}
case X86II::MRMDestMem4VOp3CC: {
unsigned CC = MI.getOperand(8).getImm();
emitByte(BaseOpcode + CC, OS);
unsigned SrcRegNum = CurOp + X86::AddrNumOperands;
emitMemModRMByte(MI, CurOp + 1, getX86RegNum(MI.getOperand(0)), TSFlags,
HasREX, StartByte, OS, Fixups, STI, false);
CurOp = SrcRegNum + 3; // skip reg, VEX_V4 and CC
break;
}
case X86II::MRMDestMemFSIB:
case X86II::MRMDestMem: {
emitByte(BaseOpcode, OS);
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/X86/X86.td
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,8 @@ def FeatureAMXBF16 : SubtargetFeature<"amx-bf16", "HasAMXBF16", "true",
def FeatureAMXFP16 : SubtargetFeature<"amx-fp16", "HasAMXFP16", "true",
"Support AMX amx-fp16 instructions",
[FeatureAMXTILE]>;

def FeatureCMPCCXADD : SubtargetFeature<"cmpccxadd", "HasCMPCCXADD", "true",
"Support CMPCCXADD instructions">;
def FeatureINVPCID : SubtargetFeature<"invpcid", "HasINVPCID", "true",
"Invalidate Process-Context Identifier">;
def FeatureSGX : SubtargetFeature<"sgx", "HasSGX", "true",
Expand Down
17 changes: 17 additions & 0 deletions llvm/lib/Target/X86/X86ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5628,6 +5628,8 @@ bool X86TargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
Info.align = Align(1);
Info.flags |= MachineMemOperand::MOLoad;
return true;
case Intrinsic::x86_cmpccxadd32:
case Intrinsic::x86_cmpccxadd64:
case Intrinsic::x86_atomic_bts:
case Intrinsic::x86_atomic_btc:
case Intrinsic::x86_atomic_btr: {
Expand Down Expand Up @@ -28234,6 +28236,20 @@ static SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, const X86Subtarget &Subtarget,
DAG.getShiftAmountConstant(Imm, VT, DL));
return DAG.getNode(ISD::MERGE_VALUES, DL, Op->getVTList(), Res, Chain);
}
case Intrinsic::x86_cmpccxadd32:
case Intrinsic::x86_cmpccxadd64: {
SDLoc DL(Op);
SDValue Chain = Op.getOperand(0);
SDValue Addr = Op.getOperand(2);
SDValue Src1 = Op.getOperand(3);
SDValue Src2 = Op.getOperand(4);
SDValue CC = Op.getOperand(5);
MachineMemOperand *MMO = cast<MemIntrinsicSDNode>(Op)->getMemOperand();
SDValue Operation = DAG.getMemIntrinsicNode(
X86ISD::CMPCCXADD, DL, Op->getVTList(), {Chain, Addr, Src1, Src2, CC},
MVT::i32, MMO);
return Operation;
}
}
return SDValue();
}
Expand Down Expand Up @@ -34154,6 +34170,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
NODE_NAME_CASE(AESDECWIDE128KL)
NODE_NAME_CASE(AESENCWIDE256KL)
NODE_NAME_CASE(AESDECWIDE256KL)
NODE_NAME_CASE(CMPCCXADD)
NODE_NAME_CASE(TESTUI)
}
return nullptr;
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/X86/X86ISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,12 @@ namespace llvm {
AESENCWIDE256KL,
AESDECWIDE256KL,

/// Compare and Add if Condition is Met. Compare value in operand 2 with
/// value in memory of operand 1. If condition of operand 4 is met, add value
/// operand 3 to m32 and write new value in operand 1. Operand 2 is
/// always updated with the original value from operand 1.
CMPCCXADD,

// Save xmm argument registers to the stack, according to %al. An operator
// is needed so that this can be expanded with control flow.
VASTART_SAVE_XMM_REGS,
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/X86/X86InstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def RawFrmImm8 : Format<7>;
def RawFrmImm16 : Format<8>;
def AddCCFrm : Format<9>;
def PrefixByte : Format<10>;
def MRMDestMem4VOp3CC : Format<20>;
def MRMr0 : Format<21>;
def MRMSrcMemFSIB : Format<22>;
def MRMDestMemFSIB : Format<23>;
Expand Down
60 changes: 60 additions & 0 deletions llvm/lib/Target/X86/X86InstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ def SDT_X86AESENCDECKL : SDTypeProfile<2, 2, [SDTCisVT<0, v2i64>,
SDTCisVT<2, v2i64>,
SDTCisPtrTy<3>]>;

def SDTX86Cmpccxadd : SDTypeProfile<1, 4, [SDTCisSameAs<0, 2>,
SDTCisPtrTy<1>, SDTCisSameAs<2, 3>,
SDTCisVT<4, i8>]>;

def X86MemBarrier : SDNode<"X86ISD::MEMBARRIER", SDT_X86MEMBARRIER,
[SDNPHasChain,SDNPSideEffect]>;
def X86MFence : SDNode<"X86ISD::MFENCE", SDT_X86MEMBARRIER,
Expand Down Expand Up @@ -341,6 +345,10 @@ def X86aesdec256kl : SDNode<"X86ISD::AESDEC256KL", SDT_X86AESENCDECKL,
[SDNPHasChain, SDNPMayLoad, SDNPSideEffect,
SDNPMemOperand]>;

def X86cmpccxadd : SDNode<"X86ISD::CMPCCXADD", SDTX86Cmpccxadd,
[SDNPHasChain, SDNPMayLoad, SDNPMayStore,
SDNPMemOperand]>;

//===----------------------------------------------------------------------===//
// X86 Operand Definitions.
//
Expand Down Expand Up @@ -981,6 +989,7 @@ def HasCX16 : Predicate<"Subtarget->hasCX16()">;
def HasPCONFIG : Predicate<"Subtarget->hasPCONFIG()">;
def HasENQCMD : Predicate<"Subtarget->hasENQCMD()">;
def HasAMXFP16 : Predicate<"Subtarget->hasAMXFP16()">;
def HasCMPCCXADD : Predicate<"Subtarget->hasCMPCCXADD()">;
def HasKL : Predicate<"Subtarget->hasKL()">;
def HasWIDEKL : Predicate<"Subtarget->hasWIDEKL()">;
def HasHRESET : Predicate<"Subtarget->hasHRESET()">;
Expand Down Expand Up @@ -3010,6 +3019,57 @@ let Predicates = [HasPREFETCHI, In64BitMode], SchedRW = [WriteLoad] in {
"prefetchit1\t$src", [(prefetch addr:$src, (i32 0), (i32 2), (i32 0))]>, TB;
}

//===----------------------------------------------------------------------===//
// CMPCCXADD Instructions
//
let isCodeGenOnly = 1, ForceDisassemble = 1, mayLoad = 1, mayStore = 1,
Predicates = [HasCMPCCXADD, In64BitMode], Defs = [EFLAGS],
Constraints = "$dstsrc1 = $dst" in {
def CMPCCXADDmr32 : I<0xe0, MRMDestMem4VOp3CC, (outs GR32:$dst),
(ins GR32:$dstsrc1, i32mem:$dstsrc2, GR32:$src3, ccode:$cond),
"cmp${cond}xadd\t{$src3, $dst, $dstsrc2|$dstsrc2, $dst, $src3}",
[(set GR32:$dst, (X86cmpccxadd addr:$dstsrc2,
GR32:$dstsrc1, GR32:$src3, timm:$cond))]>,
VEX_4V, T8PD, Sched<[WriteXCHG]>;

def CMPCCXADDmr64 : I<0xe0, MRMDestMem4VOp3CC, (outs GR64:$dst),
(ins GR64:$dstsrc1, i64mem:$dstsrc2, GR64:$src3, ccode:$cond),
"cmp${cond}xadd\t{$src3, $dst, $dstsrc2|$dstsrc2, $dst, $src3}",
[(set GR64:$dst, (X86cmpccxadd addr:$dstsrc2,
GR64:$dstsrc1, GR64:$src3, timm:$cond))]>,
VEX_4V, VEX_W, T8PD, Sched<[WriteXCHG]>;
}

multiclass CMPCCXADD_Aliases<string Cond, int CC> {
def : InstAlias<"cmp"#Cond#"xadd"#"\t{$src3, $dst, $dstsrc2|$dstsrc2, $dst, $src3}",
(CMPCCXADDmr32 GR32:$dst, i32mem:$dstsrc2, GR32:$src3, CC), 0>;
def : InstAlias<"cmp"#Cond#"xadd"#"\t{$src3, $dst, $dstsrc2|$dstsrc2, $dst, $src3}",
(CMPCCXADDmr64 GR64:$dst, i64mem:$dstsrc2, GR64:$src3, CC), 0>;
}

defm : CMPCCXADD_Aliases<"o" , 0>;
defm : CMPCCXADD_Aliases<"no", 1>;
defm : CMPCCXADD_Aliases<"b" , 2>;
defm : CMPCCXADD_Aliases<"ae", 3>;
defm : CMPCCXADD_Aliases<"nb", 3>;
defm : CMPCCXADD_Aliases<"e" , 4>;
defm : CMPCCXADD_Aliases<"z" , 4>;
defm : CMPCCXADD_Aliases<"ne", 5>;
defm : CMPCCXADD_Aliases<"nz", 5>;
defm : CMPCCXADD_Aliases<"be", 6>;
defm : CMPCCXADD_Aliases<"nbe", 7>;
defm : CMPCCXADD_Aliases<"a", 7>;
defm : CMPCCXADD_Aliases<"s" , 8>;
defm : CMPCCXADD_Aliases<"ns", 9>;
defm : CMPCCXADD_Aliases<"p" , 10>;
defm : CMPCCXADD_Aliases<"np", 11>;
defm : CMPCCXADD_Aliases<"l" , 12>;
defm : CMPCCXADD_Aliases<"ge", 13>;
defm : CMPCCXADD_Aliases<"nl", 13>;
defm : CMPCCXADD_Aliases<"le", 14>;
defm : CMPCCXADD_Aliases<"g", 15>;
defm : CMPCCXADD_Aliases<"nle",15>;

//===----------------------------------------------------------------------===//
// Pattern fragments to auto generate TBM instructions.
//===----------------------------------------------------------------------===//
Expand Down
358 changes: 358 additions & 0 deletions llvm/test/CodeGen/X86/cmpccxadd-intrinsics.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,358 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -verify-machineinstrs -mtriple=x86_64-unknown-unknown --show-mc-encoding -mattr=+cmpccxadd | FileCheck %s

define dso_local i32 @test_cmpbexadd32(i8* %__A, i32 %__B, i32 %__C) nounwind {
; CHECK-LABEL: test_cmpbexadd32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl %esi, %eax # encoding: [0x89,0xf0]
; CHECK-NEXT: cmpoxadd %edx, %eax, (%rdi) # encoding: [0xc4,0xe2,0x69,0xe0,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i32 @llvm.x86.cmpccxadd32(i8* %__A, i32 %__B, i32 %__C, i32 0)
ret i32 %0
}

declare i32 @llvm.x86.cmpccxadd32(i8*, i32, i32, i32 immarg)

define dso_local i64 @test_cmpbexadd64(i8* %__A, i64 %__B, i64 %__C) nounwind {
; CHECK-LABEL: test_cmpbexadd64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rax # encoding: [0x48,0x89,0xf0]
; CHECK-NEXT: cmpoxadd %rdx, %rax, (%rdi) # encoding: [0xc4,0xe2,0xe9,0xe0,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i64 @llvm.x86.cmpccxadd64(i8* %__A, i64 %__B, i64 %__C, i32 0)
ret i64 %0
}

declare i64 @llvm.x86.cmpccxadd64(i8*, i64, i64, i32 immarg)

define dso_local i32 @test_cmpbxadd32(i8* %__A, i32 %__B, i32 %__C) nounwind {
; CHECK-LABEL: test_cmpbxadd32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl %esi, %eax # encoding: [0x89,0xf0]
; CHECK-NEXT: cmpnoxadd %edx, %eax, (%rdi) # encoding: [0xc4,0xe2,0x69,0xe1,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i32 @llvm.x86.cmpccxadd32(i8* %__A, i32 %__B, i32 %__C, i32 1)
ret i32 %0
}

define dso_local i64 @test_cmpbxadd64(i8* %__A, i64 %__B, i64 %__C) nounwind {
; CHECK-LABEL: test_cmpbxadd64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rax # encoding: [0x48,0x89,0xf0]
; CHECK-NEXT: cmpnoxadd %rdx, %rax, (%rdi) # encoding: [0xc4,0xe2,0xe9,0xe1,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i64 @llvm.x86.cmpccxadd64(i8* %__A, i64 %__B, i64 %__C, i32 1)
ret i64 %0
}

define dso_local i32 @test_cmplexadd32(i8* %__A, i32 %__B, i32 %__C) nounwind {
; CHECK-LABEL: test_cmplexadd32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl %esi, %eax # encoding: [0x89,0xf0]
; CHECK-NEXT: cmpbxadd %edx, %eax, (%rdi) # encoding: [0xc4,0xe2,0x69,0xe2,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i32 @llvm.x86.cmpccxadd32(i8* %__A, i32 %__B, i32 %__C, i32 2)
ret i32 %0
}

define dso_local i64 @test_cmplexadd64(i8* %__A, i64 %__B, i64 %__C) nounwind {
; CHECK-LABEL: test_cmplexadd64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rax # encoding: [0x48,0x89,0xf0]
; CHECK-NEXT: cmpbxadd %rdx, %rax, (%rdi) # encoding: [0xc4,0xe2,0xe9,0xe2,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i64 @llvm.x86.cmpccxadd64(i8* %__A, i64 %__B, i64 %__C, i32 2)
ret i64 %0
}

define dso_local i32 @test_cmplxadd32(i8* %__A, i32 %__B, i32 %__C) nounwind {
; CHECK-LABEL: test_cmplxadd32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl %esi, %eax # encoding: [0x89,0xf0]
; CHECK-NEXT: cmpnbxadd %edx, %eax, (%rdi) # encoding: [0xc4,0xe2,0x69,0xe3,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i32 @llvm.x86.cmpccxadd32(i8* %__A, i32 %__B, i32 %__C, i32 3)
ret i32 %0
}

define dso_local i64 @test_cmplxadd64(i8* %__A, i64 %__B, i64 %__C) nounwind {
; CHECK-LABEL: test_cmplxadd64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rax # encoding: [0x48,0x89,0xf0]
; CHECK-NEXT: cmpnbxadd %rdx, %rax, (%rdi) # encoding: [0xc4,0xe2,0xe9,0xe3,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i64 @llvm.x86.cmpccxadd64(i8* %__A, i64 %__B, i64 %__C, i32 3)
ret i64 %0
}

define dso_local i32 @test_cmpnbexadd32(i8* %__A, i32 %__B, i32 %__C) nounwind {
; CHECK-LABEL: test_cmpnbexadd32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl %esi, %eax # encoding: [0x89,0xf0]
; CHECK-NEXT: cmpzxadd %edx, %eax, (%rdi) # encoding: [0xc4,0xe2,0x69,0xe4,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i32 @llvm.x86.cmpccxadd32(i8* %__A, i32 %__B, i32 %__C, i32 4)
ret i32 %0
}

define dso_local i64 @test_cmpnbexadd64(i8* %__A, i64 %__B, i64 %__C) nounwind {
; CHECK-LABEL: test_cmpnbexadd64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rax # encoding: [0x48,0x89,0xf0]
; CHECK-NEXT: cmpzxadd %rdx, %rax, (%rdi) # encoding: [0xc4,0xe2,0xe9,0xe4,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i64 @llvm.x86.cmpccxadd64(i8* %__A, i64 %__B, i64 %__C, i32 4)
ret i64 %0
}

define dso_local i32 @test_cmpnbxadd32(i8* %__A, i32 %__B, i32 %__C) nounwind {
; CHECK-LABEL: test_cmpnbxadd32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl %esi, %eax # encoding: [0x89,0xf0]
; CHECK-NEXT: cmpnzxadd %edx, %eax, (%rdi) # encoding: [0xc4,0xe2,0x69,0xe5,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i32 @llvm.x86.cmpccxadd32(i8* %__A, i32 %__B, i32 %__C, i32 5)
ret i32 %0
}

define dso_local i64 @test_cmpnbxadd64(i8* %__A, i64 %__B, i64 %__C) nounwind {
; CHECK-LABEL: test_cmpnbxadd64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rax # encoding: [0x48,0x89,0xf0]
; CHECK-NEXT: cmpnzxadd %rdx, %rax, (%rdi) # encoding: [0xc4,0xe2,0xe9,0xe5,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i64 @llvm.x86.cmpccxadd64(i8* %__A, i64 %__B, i64 %__C, i32 5)
ret i64 %0
}

define dso_local i32 @test_cmpnlexadd32(i8* %__A, i32 %__B, i32 %__C) nounwind {
; CHECK-LABEL: test_cmpnlexadd32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl %esi, %eax # encoding: [0x89,0xf0]
; CHECK-NEXT: cmpbexadd %edx, %eax, (%rdi) # encoding: [0xc4,0xe2,0x69,0xe6,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i32 @llvm.x86.cmpccxadd32(i8* %__A, i32 %__B, i32 %__C, i32 6)
ret i32 %0
}

define dso_local i64 @test_cmpnlexadd64(i8* %__A, i64 %__B, i64 %__C) nounwind {
; CHECK-LABEL: test_cmpnlexadd64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rax # encoding: [0x48,0x89,0xf0]
; CHECK-NEXT: cmpbexadd %rdx, %rax, (%rdi) # encoding: [0xc4,0xe2,0xe9,0xe6,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i64 @llvm.x86.cmpccxadd64(i8* %__A, i64 %__B, i64 %__C, i32 6)
ret i64 %0
}

define dso_local i32 @test_cmpnlxadd32(i8* %__A, i32 %__B, i32 %__C) nounwind {
; CHECK-LABEL: test_cmpnlxadd32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl %esi, %eax # encoding: [0x89,0xf0]
; CHECK-NEXT: cmpnbexadd %edx, %eax, (%rdi) # encoding: [0xc4,0xe2,0x69,0xe7,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i32 @llvm.x86.cmpccxadd32(i8* %__A, i32 %__B, i32 %__C, i32 7)
ret i32 %0
}

define dso_local i64 @test_cmpnlxadd64(i8* %__A, i64 %__B, i64 %__C) nounwind {
; CHECK-LABEL: test_cmpnlxadd64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rax # encoding: [0x48,0x89,0xf0]
; CHECK-NEXT: cmpnbexadd %rdx, %rax, (%rdi) # encoding: [0xc4,0xe2,0xe9,0xe7,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i64 @llvm.x86.cmpccxadd64(i8* %__A, i64 %__B, i64 %__C, i32 7)
ret i64 %0
}

define dso_local i32 @test_cmpnoxadd32(i8* %__A, i32 %__B, i32 %__C) nounwind {
; CHECK-LABEL: test_cmpnoxadd32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl %esi, %eax # encoding: [0x89,0xf0]
; CHECK-NEXT: cmpsxadd %edx, %eax, (%rdi) # encoding: [0xc4,0xe2,0x69,0xe8,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i32 @llvm.x86.cmpccxadd32(i8* %__A, i32 %__B, i32 %__C, i32 8)
ret i32 %0
}

define dso_local i64 @test_cmpnoxadd64(i8* %__A, i64 %__B, i64 %__C) nounwind {
; CHECK-LABEL: test_cmpnoxadd64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rax # encoding: [0x48,0x89,0xf0]
; CHECK-NEXT: cmpsxadd %rdx, %rax, (%rdi) # encoding: [0xc4,0xe2,0xe9,0xe8,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i64 @llvm.x86.cmpccxadd64(i8* %__A, i64 %__B, i64 %__C, i32 8)
ret i64 %0
}

define dso_local i32 @test_cmpnpxadd32(i8* %__A, i32 %__B, i32 %__C) nounwind {
; CHECK-LABEL: test_cmpnpxadd32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl %esi, %eax # encoding: [0x89,0xf0]
; CHECK-NEXT: cmpnsxadd %edx, %eax, (%rdi) # encoding: [0xc4,0xe2,0x69,0xe9,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i32 @llvm.x86.cmpccxadd32(i8* %__A, i32 %__B, i32 %__C, i32 9)
ret i32 %0
}

define dso_local i64 @test_cmpnpxadd64(i8* %__A, i64 %__B, i64 %__C) nounwind {
; CHECK-LABEL: test_cmpnpxadd64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rax # encoding: [0x48,0x89,0xf0]
; CHECK-NEXT: cmpnsxadd %rdx, %rax, (%rdi) # encoding: [0xc4,0xe2,0xe9,0xe9,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i64 @llvm.x86.cmpccxadd64(i8* %__A, i64 %__B, i64 %__C, i32 9)
ret i64 %0
}

define dso_local i32 @test_cmpnsxadd32(i8* %__A, i32 %__B, i32 %__C) nounwind {
; CHECK-LABEL: test_cmpnsxadd32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl %esi, %eax # encoding: [0x89,0xf0]
; CHECK-NEXT: cmppxadd %edx, %eax, (%rdi) # encoding: [0xc4,0xe2,0x69,0xea,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i32 @llvm.x86.cmpccxadd32(i8* %__A, i32 %__B, i32 %__C, i32 10)
ret i32 %0
}

define dso_local i64 @test_cmpnsxadd64(i8* %__A, i64 %__B, i64 %__C) nounwind {
; CHECK-LABEL: test_cmpnsxadd64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rax # encoding: [0x48,0x89,0xf0]
; CHECK-NEXT: cmppxadd %rdx, %rax, (%rdi) # encoding: [0xc4,0xe2,0xe9,0xea,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i64 @llvm.x86.cmpccxadd64(i8* %__A, i64 %__B, i64 %__C, i32 10)
ret i64 %0
}

define dso_local i32 @test_cmpnzxadd32(i8* %__A, i32 %__B, i32 %__C) nounwind {
; CHECK-LABEL: test_cmpnzxadd32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl %esi, %eax # encoding: [0x89,0xf0]
; CHECK-NEXT: cmpnpxadd %edx, %eax, (%rdi) # encoding: [0xc4,0xe2,0x69,0xeb,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i32 @llvm.x86.cmpccxadd32(i8* %__A, i32 %__B, i32 %__C, i32 11)
ret i32 %0
}

define dso_local i64 @test_cmpnzxadd64(i8* %__A, i64 %__B, i64 %__C) nounwind {
; CHECK-LABEL: test_cmpnzxadd64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rax # encoding: [0x48,0x89,0xf0]
; CHECK-NEXT: cmpnpxadd %rdx, %rax, (%rdi) # encoding: [0xc4,0xe2,0xe9,0xeb,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i64 @llvm.x86.cmpccxadd64(i8* %__A, i64 %__B, i64 %__C, i32 11)
ret i64 %0
}

define dso_local i32 @test_cmpoxadd32(i8* %__A, i32 %__B, i32 %__C) nounwind {
; CHECK-LABEL: test_cmpoxadd32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl %esi, %eax # encoding: [0x89,0xf0]
; CHECK-NEXT: cmplxadd %edx, %eax, (%rdi) # encoding: [0xc4,0xe2,0x69,0xec,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i32 @llvm.x86.cmpccxadd32(i8* %__A, i32 %__B, i32 %__C, i32 12)
ret i32 %0
}

define dso_local i64 @test_cmpoxadd64(i8* %__A, i64 %__B, i64 %__C) nounwind {
; CHECK-LABEL: test_cmpoxadd64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rax # encoding: [0x48,0x89,0xf0]
; CHECK-NEXT: cmplxadd %rdx, %rax, (%rdi) # encoding: [0xc4,0xe2,0xe9,0xec,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i64 @llvm.x86.cmpccxadd64(i8* %__A, i64 %__B, i64 %__C, i32 12)
ret i64 %0
}

define dso_local i32 @test_cmppxadd32(i8* %__A, i32 %__B, i32 %__C) nounwind {
; CHECK-LABEL: test_cmppxadd32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl %esi, %eax # encoding: [0x89,0xf0]
; CHECK-NEXT: cmpnlxadd %edx, %eax, (%rdi) # encoding: [0xc4,0xe2,0x69,0xed,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i32 @llvm.x86.cmpccxadd32(i8* %__A, i32 %__B, i32 %__C, i32 13)
ret i32 %0
}

define dso_local i64 @test_cmppxadd64(i8* %__A, i64 %__B, i64 %__C) nounwind {
; CHECK-LABEL: test_cmppxadd64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rax # encoding: [0x48,0x89,0xf0]
; CHECK-NEXT: cmpnlxadd %rdx, %rax, (%rdi) # encoding: [0xc4,0xe2,0xe9,0xed,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i64 @llvm.x86.cmpccxadd64(i8* %__A, i64 %__B, i64 %__C, i32 13)
ret i64 %0
}

define dso_local i32 @test_cmpsxadd32(i8* %__A, i32 %__B, i32 %__C) nounwind {
; CHECK-LABEL: test_cmpsxadd32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl %esi, %eax # encoding: [0x89,0xf0]
; CHECK-NEXT: cmplexadd %edx, %eax, (%rdi) # encoding: [0xc4,0xe2,0x69,0xee,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i32 @llvm.x86.cmpccxadd32(i8* %__A, i32 %__B, i32 %__C, i32 14)
ret i32 %0
}

define dso_local i64 @test_cmpsxadd64(i8* %__A, i64 %__B, i64 %__C) nounwind {
; CHECK-LABEL: test_cmpsxadd64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rax # encoding: [0x48,0x89,0xf0]
; CHECK-NEXT: cmplexadd %rdx, %rax, (%rdi) # encoding: [0xc4,0xe2,0xe9,0xee,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i64 @llvm.x86.cmpccxadd64(i8* %__A, i64 %__B, i64 %__C, i32 14)
ret i64 %0
}

define dso_local i32 @test_cmpzxadd32(i8* %__A, i32 %__B, i32 %__C) nounwind {
; CHECK-LABEL: test_cmpzxadd32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl %esi, %eax # encoding: [0x89,0xf0]
; CHECK-NEXT: cmpnlexadd %edx, %eax, (%rdi) # encoding: [0xc4,0xe2,0x69,0xef,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i32 @llvm.x86.cmpccxadd32(i8* %__A, i32 %__B, i32 %__C, i32 15)
ret i32 %0
}

define dso_local i64 @test_cmpzxadd64(i8* %__A, i64 %__B, i64 %__C) nounwind {
; CHECK-LABEL: test_cmpzxadd64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rax # encoding: [0x48,0x89,0xf0]
; CHECK-NEXT: cmpnlexadd %rdx, %rax, (%rdi) # encoding: [0xc4,0xe2,0xe9,0xef,0x07]
; CHECK-NEXT: retq # encoding: [0xc3]
entry:
%0 = tail call i64 @llvm.x86.cmpccxadd64(i8* %__A, i64 %__B, i64 %__C, i32 15)
ret i64 %0
}
771 changes: 771 additions & 0 deletions llvm/test/MC/Disassembler/X86/cmpccxadd-64.txt

Large diffs are not rendered by default.

26 changes: 26 additions & 0 deletions llvm/test/MC/X86/cmpccxadd-att-64-alias.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// RUN: llvm-mc -triple x86_64 --show-encoding %s | FileCheck %s

// CHECK: cmpnbxadd %eax, %ecx, (%rip)
// CHECK: encoding: [0xc4,0xe2,0x79,0xe3,0x0d,0x00,0x00,0x00,0x00]
cmpaexadd %eax, %ecx, (%rip)

// CHECK: cmpzxadd %eax, %ecx, (%rip)
// CHECK: encoding: [0xc4,0xe2,0x79,0xe4,0x0d,0x00,0x00,0x00,0x00]
cmpexadd %eax, %ecx, (%rip)

// CHECK: cmpnzxadd %eax, %ecx, (%rip)
// CHECK: encoding: [0xc4,0xe2,0x79,0xe5,0x0d,0x00,0x00,0x00,0x00]
cmpnexadd %eax, %ecx, (%rip)

// CHECK: cmpnbexadd %eax, %ecx, (%rip)
// CHECK: encoding: [0xc4,0xe2,0x79,0xe7,0x0d,0x00,0x00,0x00,0x00]
cmpaxadd %eax, %ecx, (%rip)

// CHECK: cmpnlxadd %eax, %ecx, (%rip)
// CHECK: encoding: [0xc4,0xe2,0x79,0xed,0x0d,0x00,0x00,0x00,0x00]
cmpgexadd %eax, %ecx, (%rip)

// CHECK: cmpnlexadd %eax, %ecx, (%rip)
// CHECK: encoding: [0xc4,0xe2,0x79,0xef,0x0d,0x00,0x00,0x00,0x00]
cmpgxadd %eax, %ecx, (%rip)

770 changes: 770 additions & 0 deletions llvm/test/MC/X86/cmpccxadd-att-64.s

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions llvm/test/MC/X86/cmpccxadd-intel-64-alias.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// RUN: llvm-mc -triple x86_64 -x86-asm-syntax=intel -output-asm-variant=1 --show-encoding %s | FileCheck %s

// CHECK: cmpnbxadd dword ptr [rip], ecx, eax
// CHECK: encoding: [0xc4,0xe2,0x79,0xe3,0x0d,0x00,0x00,0x00,0x00]
cmpaexadd dword ptr [rip], ecx, eax

// CHECK: cmpzxadd dword ptr [rip], ecx, eax
// CHECK: encoding: [0xc4,0xe2,0x79,0xe4,0x0d,0x00,0x00,0x00,0x00]
cmpexadd dword ptr [rip], ecx, eax

// CHECK: cmpnzxadd dword ptr [rip], ecx, eax
// CHECK: encoding: [0xc4,0xe2,0x79,0xe5,0x0d,0x00,0x00,0x00,0x00]
cmpnexadd dword ptr [rip], ecx, eax

// CHECK: cmpnbexadd dword ptr [rip], ecx, eax
// CHECK: encoding: [0xc4,0xe2,0x79,0xe7,0x0d,0x00,0x00,0x00,0x00]
cmpaxadd dword ptr [rip], ecx, eax

// CHECK: cmpnlxadd dword ptr [rip], ecx, eax
// CHECK: encoding: [0xc4,0xe2,0x79,0xed,0x0d,0x00,0x00,0x00,0x00]
cmpgexadd dword ptr [rip], ecx, eax

// CHECK: cmpnlexadd dword ptr [rip], ecx, eax
// CHECK: encoding: [0xc4,0xe2,0x79,0xef,0x0d,0x00,0x00,0x00,0x00]
cmpgxadd dword ptr [rip], ecx, eax
770 changes: 770 additions & 0 deletions llvm/test/MC/X86/cmpccxadd-intel-64.s

Large diffs are not rendered by default.

16 changes: 15 additions & 1 deletion llvm/utils/TableGen/X86RecognizableInstr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,18 @@ void RecognizableInstr::emitInstructionSpecifier() {
HANDLE_OPERAND(roRegister)
HANDLE_OPTIONAL(immediate)
break;
case X86Local::MRMDestMem4VOp3CC:
// Operand 1 is a register operand in the Reg/Opcode field.
// Operand 2 is a register operand in the R/M field.
// Operand 3 is VEX.vvvv
// Operand 4 is condition code.
assert(numPhysicalOperands == 4 &&
"Unexpected number of operands for MRMDestMem4VOp3CC");
HANDLE_OPERAND(roRegister)
HANDLE_OPERAND(memory)
HANDLE_OPERAND(vvvvRegister)
HANDLE_OPERAND(opcodeModifier)
break;
case X86Local::MRMDestMem:
case X86Local::MRMDestMemFSIB:
// Operand 1 is a memory operand (possibly SIB-extended)
Expand Down Expand Up @@ -808,6 +820,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
filter = std::make_unique<ModFilter>(true);
break;
case X86Local::MRMDestMem:
case X86Local::MRMDestMem4VOp3CC:
case X86Local::MRMDestMemFSIB:
case X86Local::MRMSrcMem:
case X86Local::MRMSrcMemFSIB:
Expand Down Expand Up @@ -858,7 +871,8 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {

if (Form == X86Local::AddRegFrm || Form == X86Local::MRMSrcRegCC ||
Form == X86Local::MRMSrcMemCC || Form == X86Local::MRMXrCC ||
Form == X86Local::MRMXmCC || Form == X86Local::AddCCFrm) {
Form == X86Local::MRMXmCC || Form == X86Local::AddCCFrm ||
Form == X86Local::MRMDestMem4VOp3CC) {
uint8_t Count = Form == X86Local::AddRegFrm ? 8 : 16;
assert(((opcodeToSet % Count) == 0) && "ADDREG_FRM opcode not aligned");

Expand Down
1 change: 1 addition & 0 deletions llvm/utils/TableGen/X86RecognizableInstr.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ namespace X86Local {
RawFrmImm16 = 8,
AddCCFrm = 9,
PrefixByte = 10,
MRMDestMem4VOp3CC = 20,
MRMr0 = 21,
MRMSrcMemFSIB = 22,
MRMDestMemFSIB = 23,
Expand Down