Skip to content

[X86][MC] Support Enc/Dec for NF BMI instructions #76709

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1134,6 +1134,27 @@ static int getInstructionIDWithAttrMask(uint16_t *instructionID,
return 0;
}

static bool isNF(InternalInstruction *insn) {
if (!nfFromEVEX4of4(insn->vectorExtensionPrefix[3]))
return false;
if (insn->opcodeType == MAP4)
return true;
// Below NF instructions are not in map4.
if (insn->opcodeType == THREEBYTE_38 &&
ppFromEVEX3of4(insn->vectorExtensionPrefix[2]) == VEX_PREFIX_NONE) {
switch (insn->opcode) {
case 0xf2: // ANDN
case 0xf3: // BLSI, BLSR, BLSMSK
case 0xf5: // BZHI
case 0xf7: // BEXTR
return true;
default:
break;
}
}
return false;
}

// Determine the ID of an instruction, consuming the ModR/M byte as appropriate
// for extended and escape opcodes. Determines the attributes and context for
// the instruction before doing so.
Expand Down Expand Up @@ -1169,9 +1190,7 @@ static int getInstructionID(struct InternalInstruction *insn,
attrMask |= ATTR_EVEXKZ;
if (bFromEVEX4of4(insn->vectorExtensionPrefix[3]))
attrMask |= ATTR_EVEXB;
// nf bit is the MSB of aaa
if (nfFromEVEX4of4(insn->vectorExtensionPrefix[3]) &&
insn->opcodeType == MAP4)
if (isNF(insn)) // NF bit is the MSB of aaa.
attrMask |= ATTR_EVEXNF;
else if (aaaFromEVEX4of4(insn->vectorExtensionPrefix[3]))
attrMask |= ATTR_EVEXK;
Expand Down
22 changes: 11 additions & 11 deletions llvm/lib/Target/X86/X86InstrArithmetic.td
Original file line number Diff line number Diff line change
Expand Up @@ -1312,30 +1312,30 @@ def : Pat<(X86testpat (loadi64 addr:$src1), i64relocImmSExt32_su:$src2),
//===----------------------------------------------------------------------===//
// ANDN Instruction
//
multiclass AndN<X86TypeInfo t, string suffix> {
multiclass AndN<X86TypeInfo t, SDPatternOperator node, string suffix = ""> {
defvar andn_rr_p =
[(set t.RegClass:$dst, EFLAGS, (X86and_flag (not t.RegClass:$src1),
[(set t.RegClass:$dst, EFLAGS, (node (not t.RegClass:$src1),
t.RegClass:$src2))];
defvar andn_rm_p =
[(set t.RegClass:$dst, EFLAGS, (X86and_flag (not t.RegClass:$src1),
[(set t.RegClass:$dst, EFLAGS, (node (not t.RegClass:$src1),
(t.LoadNode addr:$src2)))];
def rr#suffix : ITy<0xF2, MRMSrcReg, t, (outs t.RegClass:$dst),
(ins t.RegClass:$src1, t.RegClass:$src2), "andn",
binop_ndd_args, andn_rr_p>, VVVV, Sched<[WriteALU]>,
T8, DefEFLAGS;
binop_ndd_args, andn_rr_p>, VVVV, Sched<[WriteALU]>, T8;
def rm#suffix : ITy<0xF2, MRMSrcMem, t, (outs t.RegClass:$dst),
(ins t.RegClass:$src1, t.MemOperand:$src2), "andn",
binop_ndd_args, andn_rm_p>, VVVV,
Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>,
T8, DefEFLAGS;
Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>, T8;
}

// Complexity is reduced to give and with immediate a chance to match first.
let AddedComplexity = -6 in {
defm ANDN32 : AndN<Xi32, "">, VEX, Requires<[HasBMI, NoEGPR]>;
defm ANDN64 : AndN<Xi64, "">, VEX, REX_W, Requires<[HasBMI, NoEGPR]>;
defm ANDN32 : AndN<Xi32, "_EVEX">, EVEX, Requires<[HasBMI, HasEGPR, In64BitMode]>;
defm ANDN64 : AndN<Xi64, "_EVEX">, EVEX, REX_W, Requires<[HasBMI, HasEGPR, In64BitMode]>;
defm ANDN32 : AndN<Xi32, X86and_flag>, VEX, Requires<[HasBMI, NoEGPR]>, DefEFLAGS;
defm ANDN64 : AndN<Xi64, X86and_flag>, VEX, Requires<[HasBMI, NoEGPR]>, DefEFLAGS;
defm ANDN32 : AndN<Xi32, X86and_flag, "_EVEX">, EVEX, Requires<[HasBMI, HasEGPR, In64BitMode]>, DefEFLAGS;
defm ANDN64 : AndN<Xi64, X86and_flag, "_EVEX">, EVEX, Requires<[HasBMI, HasEGPR, In64BitMode]>, DefEFLAGS;
defm ANDN32 : AndN<Xi32, null_frag, "_NF">, EVEX, EVEX_NF, Requires<[In64BitMode]>;
defm ANDN64 : AndN<Xi64, null_frag, "_NF">, EVEX, EVEX_NF, Requires<[In64BitMode]>;
}

multiclass Andn_Pats<string suffix> {
Expand Down
20 changes: 18 additions & 2 deletions llvm/lib/Target/X86/X86InstrMisc.td
Original file line number Diff line number Diff line change
Expand Up @@ -1223,7 +1223,7 @@ multiclass Bls<string m, Format RegMRM, Format MemMRM, X86TypeInfo t, string Suf
(outs t.RegClass:$dst), []>, T8, VVVV;
}

let Predicates = [HasBMI], Defs = [EFLAGS] in {
let Defs = [EFLAGS] in {
defm BLSR32 : Bls<"blsr", MRM1r, MRM1m, Xi32>, VEX;
defm BLSR64 : Bls<"blsr", MRM1r, MRM1m, Xi64>, VEX;
defm BLSMSK32 : Bls<"blsmsk", MRM2r, MRM2m, Xi32>, VEX;
Expand All @@ -1232,7 +1232,7 @@ let Predicates = [HasBMI], Defs = [EFLAGS] in {
defm BLSI64 : Bls<"blsi", MRM3r, MRM3m, Xi64>, VEX;
}

let Predicates = [HasBMI, In64BitMode], Defs = [EFLAGS] in {
let Predicates = [In64BitMode], Defs = [EFLAGS] in {
defm BLSR32 : Bls<"blsr", MRM1r, MRM1m, Xi32, "_EVEX">, EVEX;
defm BLSR64 : Bls<"blsr", MRM1r, MRM1m, Xi64, "_EVEX">, EVEX;
defm BLSMSK32 : Bls<"blsmsk", MRM2r, MRM2m, Xi32, "_EVEX">, EVEX;
Expand All @@ -1241,6 +1241,15 @@ let Predicates = [HasBMI, In64BitMode], Defs = [EFLAGS] in {
defm BLSI64 : Bls<"blsi", MRM3r, MRM3m, Xi64, "_EVEX">, EVEX;
}

let Predicates = [In64BitMode] in {
defm BLSR32 : Bls<"blsr", MRM1r, MRM1m, Xi32, "_NF">, EVEX, EVEX_NF;
defm BLSR64 : Bls<"blsr", MRM1r, MRM1m, Xi64, "_NF">, EVEX, EVEX_NF;
defm BLSMSK32 : Bls<"blsmsk", MRM2r, MRM2m, Xi32, "_NF">, EVEX, EVEX_NF;
defm BLSMSK64 : Bls<"blsmsk", MRM2r, MRM2m, Xi64, "_NF">, EVEX, EVEX_NF;
defm BLSI32 : Bls<"blsi", MRM3r, MRM3m, Xi32, "_NF">, EVEX, EVEX_NF;
defm BLSI64 : Bls<"blsi", MRM3r, MRM3m, Xi64, "_NF">, EVEX, EVEX_NF;
}

multiclass Bls_Pats<string suffix> {
// FIXME(1): patterns for the load versions are not implemented
// FIXME(2): By only matching `add_su` and `ineg_su` we may emit
Expand Down Expand Up @@ -1315,6 +1324,13 @@ let Predicates = [HasBMI2, HasEGPR, In64BitMode], Defs = [EFLAGS] in {
defm BZHI64 : Bmi4VOp3<0xF5, "bzhi", Xi64, X86bzhi, WriteBZHI, "_EVEX">, EVEX;
}

let Predicates = [In64BitMode] in {
defm BEXTR32 : Bmi4VOp3<0xF7, "bextr", Xi32, null_frag, WriteBEXTR, "_NF">, EVEX, EVEX_NF;
defm BEXTR64 : Bmi4VOp3<0xF7, "bextr", Xi64, null_frag, WriteBEXTR, "_NF">, EVEX, EVEX_NF;
defm BZHI32 : Bmi4VOp3<0xF5, "bzhi", Xi32, null_frag, WriteBZHI, "_NF">, EVEX, EVEX_NF;
defm BZHI64 : Bmi4VOp3<0xF5, "bzhi", Xi64, null_frag, WriteBZHI, "_NF">, EVEX, EVEX_NF;
}

def CountTrailingOnes : SDNodeXForm<imm, [{
// Count the trailing ones in the immediate.
return getI8Imm(llvm::countr_one(N->getZExtValue()), SDLoc(N));
Expand Down
32 changes: 32 additions & 0 deletions llvm/test/MC/Disassembler/X86/apx/andn.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,38 @@
# RUN: llvm-mc --disassemble %s -triple=x86_64 | FileCheck %s --check-prefixes=ATT
# RUN: llvm-mc --disassemble %s -triple=x86_64 -x86-asm-syntax=intel --output-asm-variant=1 | FileCheck %s --check-prefixes=INTEL

# ATT: {nf} andnl %ecx, %edx, %r10d
# INTEL: {nf} andn r10d, edx, ecx
0x62,0x72,0x6c,0x0c,0xf2,0xd1

# ATT: andnl %ecx, %edx, %r10d
# INTEL: andn r10d, edx, ecx
0x62,0x72,0x6c,0x08,0xf2,0xd1

# ATT: {nf} andnq %r9, %r15, %r11
# INTEL: {nf} andn r11, r15, r9
0x62,0x52,0x84,0x0c,0xf2,0xd9

# ATT: andnq %r9, %r15, %r11
# INTEL: andn r11, r15, r9
0x62,0x52,0x84,0x08,0xf2,0xd9

# ATT: {nf} andnl 123(%rax,%rbx,4), %ecx, %edx
# INTEL: {nf} andn edx, ecx, dword ptr [rax + 4*rbx + 123]
0x62,0xf2,0x74,0x0c,0xf2,0x54,0x98,0x7b

# ATT: andnl 123(%rax,%rbx,4), %ecx, %edx
# INTEL: andn edx, ecx, dword ptr [rax + 4*rbx + 123]
0x62,0xf2,0x74,0x08,0xf2,0x54,0x98,0x7b

# ATT: {nf} andnq 123(%rax,%rbx,4), %r9, %r15
# INTEL: {nf} andn r15, r9, qword ptr [rax + 4*rbx + 123]
0x62,0x72,0xb4,0x0c,0xf2,0x7c,0x98,0x7b

# ATT: andnq 123(%rax,%rbx,4), %r9, %r15
# INTEL: andn r15, r9, qword ptr [rax + 4*rbx + 123]
0x62,0x72,0xb4,0x08,0xf2,0x7c,0x98,0x7b

# ATT: andnl %r18d, %r22d, %r26d
# INTEL: andn r26d, r22d, r18d
0x62,0x6a,0x4c,0x00,0xf2,0xd2
Expand Down
32 changes: 32 additions & 0 deletions llvm/test/MC/Disassembler/X86/apx/bextr.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,38 @@
# RUN: llvm-mc --disassemble %s -triple=x86_64 | FileCheck %s --check-prefixes=ATT
# RUN: llvm-mc --disassemble %s -triple=x86_64 -x86-asm-syntax=intel --output-asm-variant=1 | FileCheck %s --check-prefixes=INTEL

# ATT: {nf} bextrl %ecx, %edx, %r10d
# INTEL: {nf} bextr r10d, edx, ecx
0x62,0x72,0x74,0x0c,0xf7,0xd2

# ATT: bextrl %ecx, %edx, %r10d
# INTEL: bextr r10d, edx, ecx
0x62,0x72,0x74,0x08,0xf7,0xd2

# ATT: {nf} bextrl %ecx, 123(%rax,%rbx,4), %edx
# INTEL: {nf} bextr edx, dword ptr [rax + 4*rbx + 123], ecx
0x62,0xf2,0x74,0x0c,0xf7,0x54,0x98,0x7b

# ATT: bextrl %ecx, 123(%rax,%rbx,4), %edx
# INTEL: bextr edx, dword ptr [rax + 4*rbx + 123], ecx
0x62,0xf2,0x74,0x08,0xf7,0x54,0x98,0x7b

# ATT: {nf} bextrq %r9, %r15, %r11
# INTEL: {nf} bextr r11, r15, r9
0x62,0x52,0xb4,0x0c,0xf7,0xdf

# ATT: bextrq %r9, %r15, %r11
# INTEL: bextr r11, r15, r9
0x62,0x52,0xb4,0x08,0xf7,0xdf

# ATT: {nf} bextrq %r9, 123(%rax,%rbx,4), %r15
# INTEL: {nf} bextr r15, qword ptr [rax + 4*rbx + 123], r9
0x62,0x72,0xb4,0x0c,0xf7,0x7c,0x98,0x7b

# ATT: bextrq %r9, 123(%rax,%rbx,4), %r15
# INTEL: bextr r15, qword ptr [rax + 4*rbx + 123], r9
0x62,0x72,0xb4,0x08,0xf7,0x7c,0x98,0x7b

# ATT: bextrl %r18d, %r22d, %r26d
# INTEL: bextr r26d, r22d, r18d
0x62,0x6a,0x6c,0x00,0xf7,0xd6
Expand Down
32 changes: 32 additions & 0 deletions llvm/test/MC/Disassembler/X86/apx/blsi.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,38 @@
# RUN: llvm-mc --disassemble %s -triple=x86_64 | FileCheck %s --check-prefixes=ATT
# RUN: llvm-mc --disassemble %s -triple=x86_64 -x86-asm-syntax=intel --output-asm-variant=1 | FileCheck %s --check-prefixes=INTEL

# ATT: {nf} blsil %ecx, %edx
# INTEL: {nf} blsi edx, ecx
0x62,0xf2,0x6c,0x0c,0xf3,0xd9

# ATT: blsil %ecx, %edx
# INTEL: blsi edx, ecx
0x62,0xf2,0x6c,0x08,0xf3,0xd9

# ATT: {nf} blsiq %r9, %r15
# INTEL: {nf} blsi r15, r9
0x62,0xd2,0x84,0x0c,0xf3,0xd9

# ATT: blsiq %r9, %r15
# INTEL: blsi r15, r9
0x62,0xd2,0x84,0x08,0xf3,0xd9

# ATT: {nf} blsil 123(%rax,%rbx,4), %ecx
# INTEL: {nf} blsi ecx, dword ptr [rax + 4*rbx + 123]
0x62,0xf2,0x74,0x0c,0xf3,0x5c,0x98,0x7b

# ATT: blsil 123(%rax,%rbx,4), %ecx
# INTEL: blsi ecx, dword ptr [rax + 4*rbx + 123]
0x62,0xf2,0x74,0x08,0xf3,0x5c,0x98,0x7b

# ATT: {nf} blsiq 123(%rax,%rbx,4), %r9
# INTEL: {nf} blsi r9, qword ptr [rax + 4*rbx + 123]
0x62,0xf2,0xb4,0x0c,0xf3,0x5c,0x98,0x7b

# ATT: blsiq 123(%rax,%rbx,4), %r9
# INTEL: blsi r9, qword ptr [rax + 4*rbx + 123]
0x62,0xf2,0xb4,0x08,0xf3,0x5c,0x98,0x7b

# ATT: blsil %r18d, %r22d
# INTEL: blsi r22d, r18d
0x62,0xfa,0x4c,0x00,0xf3,0xda
Expand Down
32 changes: 32 additions & 0 deletions llvm/test/MC/Disassembler/X86/apx/blsmsk.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,38 @@
# RUN: llvm-mc --disassemble %s -triple=x86_64 | FileCheck %s --check-prefixes=ATT
# RUN: llvm-mc --disassemble %s -triple=x86_64 -x86-asm-syntax=intel --output-asm-variant=1 | FileCheck %s --check-prefixes=INTEL

# ATT: {nf} blsmskl %ecx, %edx
# INTEL: {nf} blsmsk edx, ecx
0x62,0xf2,0x6c,0x0c,0xf3,0xd1

# ATT: blsmskl %ecx, %edx
# INTEL: blsmsk edx, ecx
0x62,0xf2,0x6c,0x08,0xf3,0xd1

# ATT: {nf} blsmskq %r9, %r15
# INTEL: {nf} blsmsk r15, r9
0x62,0xd2,0x84,0x0c,0xf3,0xd1

# ATT: blsmskq %r9, %r15
# INTEL: blsmsk r15, r9
0x62,0xd2,0x84,0x08,0xf3,0xd1

# ATT: {nf} blsmskl 123(%rax,%rbx,4), %ecx
# INTEL: {nf} blsmsk ecx, dword ptr [rax + 4*rbx + 123]
0x62,0xf2,0x74,0x0c,0xf3,0x54,0x98,0x7b

# ATT: blsmskl 123(%rax,%rbx,4), %ecx
# INTEL: blsmsk ecx, dword ptr [rax + 4*rbx + 123]
0x62,0xf2,0x74,0x08,0xf3,0x54,0x98,0x7b

# ATT: {nf} blsmskq 123(%rax,%rbx,4), %r9
# INTEL: {nf} blsmsk r9, qword ptr [rax + 4*rbx + 123]
0x62,0xf2,0xb4,0x0c,0xf3,0x54,0x98,0x7b

# ATT: blsmskq 123(%rax,%rbx,4), %r9
# INTEL: blsmsk r9, qword ptr [rax + 4*rbx + 123]
0x62,0xf2,0xb4,0x08,0xf3,0x54,0x98,0x7b

# ATT: blsmskl %r18d, %r22d
# INTEL: blsmsk r22d, r18d
0x62,0xfa,0x4c,0x00,0xf3,0xd2
Expand Down
32 changes: 32 additions & 0 deletions llvm/test/MC/Disassembler/X86/apx/blsr.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,38 @@
# RUN: llvm-mc --disassemble %s -triple=x86_64 | FileCheck %s --check-prefixes=ATT
# RUN: llvm-mc --disassemble %s -triple=x86_64 -x86-asm-syntax=intel --output-asm-variant=1 | FileCheck %s --check-prefixes=INTEL

# ATT: {nf} blsrl %ecx, %edx
# INTEL: {nf} blsr edx, ecx
0x62,0xf2,0x6c,0x0c,0xf3,0xc9

# ATT: blsrl %ecx, %edx
# INTEL: blsr edx, ecx
0x62,0xf2,0x6c,0x08,0xf3,0xc9

# ATT: {nf} blsrq %r9, %r15
# INTEL: {nf} blsr r15, r9
0x62,0xd2,0x84,0x0c,0xf3,0xc9

# ATT: blsrq %r9, %r15
# INTEL: blsr r15, r9
0x62,0xd2,0x84,0x08,0xf3,0xc9

# ATT: {nf} blsrl 123(%rax,%rbx,4), %ecx
# INTEL: {nf} blsr ecx, dword ptr [rax + 4*rbx + 123]
0x62,0xf2,0x74,0x0c,0xf3,0x4c,0x98,0x7b

# ATT: blsrl 123(%rax,%rbx,4), %ecx
# INTEL: blsr ecx, dword ptr [rax + 4*rbx + 123]
0x62,0xf2,0x74,0x08,0xf3,0x4c,0x98,0x7b

# ATT: {nf} blsrq 123(%rax,%rbx,4), %r9
# INTEL: {nf} blsr r9, qword ptr [rax + 4*rbx + 123]
0x62,0xf2,0xb4,0x0c,0xf3,0x4c,0x98,0x7b

# ATT: blsrq 123(%rax,%rbx,4), %r9
# INTEL: blsr r9, qword ptr [rax + 4*rbx + 123]
0x62,0xf2,0xb4,0x08,0xf3,0x4c,0x98,0x7b

# ATT: blsrl %r18d, %r22d
# INTEL: blsr r22d, r18d
0x62,0xfa,0x4c,0x00,0xf3,0xca
Expand Down
36 changes: 36 additions & 0 deletions llvm/test/MC/Disassembler/X86/apx/bzhi.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,42 @@
# RUN: llvm-mc --disassemble %s -triple=x86_64 | FileCheck %s --check-prefixes=ATT
# RUN: llvm-mc --disassemble %s -triple=x86_64 -x86-asm-syntax=intel --output-asm-variant=1 | FileCheck %s --check-prefixes=INTEL

# ATT: {nf} bzhil %ecx, %edx, %r10d
# INTEL: {nf} bzhi r10d, edx, ecx
0x62,0x72,0x74,0x0c,0xf5,0xd2

# ATT: bzhil %ecx, %edx, %r10d
# INTEL: bzhi r10d, edx, ecx
0x62,0x72,0x74,0x08,0xf5,0xd2

# ATT: {nf} bzhil %ecx, 123(%rax,%rbx,4), %edx
# INTEL: {nf} bzhi edx, dword ptr [rax + 4*rbx + 123], ecx
0x62,0xf2,0x74,0x0c,0xf5,0x54,0x98,0x7b

# ATT: bzhil %ecx, 123(%rax,%rbx,4), %edx
# INTEL: bzhi edx, dword ptr [rax + 4*rbx + 123], ecx
0x62,0xf2,0x74,0x08,0xf5,0x54,0x98,0x7b

# ATT: {nf} bzhiq %r9, %r15, %r11
# INTEL: {nf} bzhi r11, r15, r9
0x62,0x52,0xb4,0x0c,0xf5,0xdf

# ATT: bzhiq %r9, %r15, %r11
# INTEL: bzhi r11, r15, r9
0x62,0x52,0xb4,0x08,0xf5,0xdf

# ATT: {nf} bzhiq %r9, 123(%rax,%rbx,4), %r15
# INTEL: {nf} bzhi r15, qword ptr [rax + 4*rbx + 123], r9
0x62,0x72,0xb4,0x0c,0xf5,0x7c,0x98,0x7b

# ATT: bzhiq %r9, 123(%rax,%rbx,4), %r15
# INTEL: bzhi r15, qword ptr [rax + 4*rbx + 123], r9
0x62,0x72,0xb4,0x08,0xf5,0x7c,0x98,0x7b

# ATT: bzhiq %r9, 123(%rax,%rbx,4), %r15
# INTEL: bzhi r15, qword ptr [rax + 4*rbx + 123], r9
0x62,0x72,0xb4,0x08,0xf5,0xbc,0x98,0x7b,0x00,0x00,0x00

# ATT: bzhil %r18d, %r22d, %r26d
# INTEL: bzhi r26d, r22d, r18d
0x62,0x6a,0x6c,0x00,0xf5,0xd6
Expand Down
Loading