Add Intel BMI1, BMI2, INVPCID, LZCNT instructions.

Reference: http://www.intel.com/software/avx rev11 spec

Also add appropriate CPU bits and directive handling for these.

Currently we have no good way of handling an "or" of instruction bits
(in this case needed for LZCNT, where it's either AMD or LZCNT).  For
now, make it LZCNT only.

Contributed by: Mark Charney <mark.charney@intel.com>

Part of [#227].
This commit is contained in:
Peter Johnson 2011-07-03 01:48:44 -07:00
parent 0614dede9b
commit 47f693fd89
12 changed files with 721 additions and 3 deletions

View file

@ -43,7 +43,8 @@ ordered_cpu_features = [
"FPU", "Cyrix", "AMD", "MMX", "3DNow", "SMM", "SSE", "SSE2",
"SSE3", "SVM", "PadLock", "SSSE3", "SSE41", "SSE42", "SSE4a", "SSE5",
"AVX", "FMA", "AES", "CLMUL", "MOVBE", "XOP", "FMA4", "F16C",
"FSGSBASE", "RDRAND", "XSAVEOPT", "EPTVPID", "SMX"]
"FSGSBASE", "RDRAND", "XSAVEOPT", "EPTVPID", "SMX", "AVX2", "BMI1",
"BMI2", "INVPCID", "LZCNT"]
unordered_cpu_features = ["Priv", "Prot", "Undoc", "Obs"]
# Predefined VEX prefix field values
@ -6607,7 +6608,7 @@ add_group("vfma_ps",
Operand(type="SIMDReg", size=256, dest="VEX"),
Operand(type="SIMDRM", size=256, relaxed=True, dest="EA")])
### 128/256b FMA PD(W=1)
### 128/256b FMA PD(W=1)
add_group("vfma_pd",
cpu=["FMA"],
modifiers=["Op2Add"],
@ -7352,6 +7353,115 @@ for sz in (16, 32, 64):
Operand(type="Reg", size=sz, dest="Spare")])
add_insn("movbe", "movbe")
#####################################################################
# Intel advanced bit manipulations (BMI1/2)
#####################################################################
add_insn("tzcnt", "cnt", modifiers=[0xBC], cpu=["BMI1"])
# LZCNT is present as AMD ext
for sfx, sz in zip("wlq", [32, 64]):
add_group("vex_gpr_ndd_rm_0F38_regext",
suffix=sfx,
modifiers=["PreAdd", "Op2Add", "SpAdd" ],
opersize=sz,
prefix=0x00,
opcode=[0x0F, 0x38, 0x00],
vex=0, ## VEX.L=0
operands=[Operand(type="Reg", size=sz, dest="VEX"),
Operand(type="RM", size=sz, relaxed=True, dest="EA")])
add_insn("blsr", "vex_gpr_ndd_rm_0F38_regext", modifiers=[0x00, 0xF3, 1],
cpu=["BMI1"])
add_insn("blsmsk", "vex_gpr_ndd_rm_0F38_regext", modifiers=[0x00, 0xF3, 2],
cpu=["BMI1"])
add_insn("blsi", "vex_gpr_ndd_rm_0F38_regext", modifiers=[0x00, 0xF3, 3],
cpu=["BMI1"])
for sfx, sz in zip("wlq", [32, 64]):
add_group("vex_gpr_reg_rm_0F_imm8",
suffix=sfx,
modifiers=["PreAdd", "Op1Add", "Op2Add"],
opersize=sz,
prefix=0x00,
opcode=[0x0F, 0x00, 0x00],
vex=0, ## VEX.L=0
operands=[Operand(type="Reg", size=sz, dest="Spare"),
Operand(type="RM", size=sz, relaxed=True, dest="EA"),
Operand(type="Imm", size=8, relaxed=True, dest="Imm")])
add_insn("rorx", "vex_gpr_reg_rm_0F_imm8", modifiers=[0xF2, 0x3A, 0xF0],
cpu=["BMI2"])
for sfx, sz in zip("lq", [32, 64]): # no 16-bit forms
add_group("vex_gpr_reg_nds_rm_0F",
suffix=sfx,
modifiers=["PreAdd", "Op1Add", "Op2Add"],
opersize=sz,
prefix=0x00,
opcode=[0x0F, 0x00, 0x00],
vex=0,
operands=[Operand(type="Reg", size=sz, dest="Spare"),
Operand(type="Reg", size=sz, dest="VEX"),
Operand(type="RM", size=sz, relaxed=True, dest="EA")])
add_insn("andn", "vex_gpr_reg_nds_rm_0F", modifiers=[0x00, 0x38, 0xF2],
cpu=["BMI1"])
add_insn("pdep", "vex_gpr_reg_nds_rm_0F", modifiers=[0xF2, 0x38, 0xF5],
cpu=["BMI2"])
add_insn("pext", "vex_gpr_reg_nds_rm_0F", modifiers=[0xF3, 0x38, 0xF5],
cpu=["BMI2"])
for sfx, sz in zip("lq", [32, 64]): # no 16-bit forms
add_group("vex_gpr_reg_rm_nds_0F",
suffix=sfx,
modifiers=["PreAdd", "Op1Add", "Op2Add"],
opersize=sz,
prefix=0x00,
opcode=[0x0F, 0x00, 0x00],
vex=0,
operands=[Operand(type="Reg", size=sz, dest="Spare"),
Operand(type="RM", size=sz, relaxed=True, dest="EA"),
Operand(type="Reg", size=sz, dest="VEX")])
add_insn("bzhi", "vex_gpr_reg_rm_nds_0F", modifiers=[0x00, 0x38, 0xF5],
cpu=["BMI2"])
add_insn("bextr","vex_gpr_reg_rm_nds_0F", modifiers=[0x00, 0x38, 0xF7],
cpu=["BMI1"])
add_insn("shlx", "vex_gpr_reg_rm_nds_0F", modifiers=[0x66, 0x38, 0xF7],
cpu=["BMI2"])
add_insn("shrx", "vex_gpr_reg_rm_nds_0F", modifiers=[0xF2, 0x38, 0xF7],
cpu=["BMI2"])
add_insn("sarx", "vex_gpr_reg_rm_nds_0F", modifiers=[0xF3, 0x38, 0xF7],
cpu=["BMI2"])
add_insn("mulx", "vex_gpr_reg_nds_rm_0F", modifiers=[0xF2, 0x38, 0xF6],
cpu=["BMI2"])
#####################################################################
# Intel INVPCID instruction
#####################################################################
add_group("invpcid",
cpu=["INVPCID", "Priv"],
not64=True,
prefix=0x66,
opcode=[0x0F, 0x38, 0x82],
operands=[Operand(type="Reg", size=32, dest="Spare"),
Operand(type="Mem", size=128, relaxed=True, dest="EA")])
add_group("invpcid",
cpu=["INVPCID", "Priv"],
only64=True,
def_opersize_64=64,
prefix=0x66,
opcode=[0x0F, 0x38, 0x82],
operands=[Operand(type="Reg", size=64, dest="Spare"),
Operand(type="Mem", size=128, relaxed=True, dest="EA")])
add_insn("invpcid", "invpcid")
#####################################################################
# AMD 3DNow! instructions
#####################################################################
@ -7400,7 +7510,7 @@ add_insn("syscall", "twobyte", modifiers=[0x0F, 0x05], cpu=["686", "AMD"])
for sfx in [None, "l", "q"]:
add_insn("sysret"+(sfx or ""), "twobyte", suffix=sfx, modifiers=[0x0F, 0x07],
cpu=["686", "AMD", "Priv"])
add_insn("lzcnt", "cnt", modifiers=[0xBD], cpu=["686", "AMD"])
add_insn("lzcnt", "cnt", modifiers=[0xBD], cpu=["LZCNT"])
#####################################################################
# AMD x86-64 extensions

View file

@ -29,6 +29,10 @@ EXTRA_DIST += modules/arch/x86/tests/avxcc.asm
EXTRA_DIST += modules/arch/x86/tests/avxcc.hex
EXTRA_DIST += modules/arch/x86/tests/bittest.asm
EXTRA_DIST += modules/arch/x86/tests/bittest.hex
EXTRA_DIST += modules/arch/x86/tests/bmi1.asm
EXTRA_DIST += modules/arch/x86/tests/bmi1.hex
EXTRA_DIST += modules/arch/x86/tests/bmi2.asm
EXTRA_DIST += modules/arch/x86/tests/bmi2.hex
EXTRA_DIST += modules/arch/x86/tests/bswap64.asm
EXTRA_DIST += modules/arch/x86/tests/bswap64.hex
EXTRA_DIST += modules/arch/x86/tests/clmul.asm
@ -79,6 +83,8 @@ EXTRA_DIST += modules/arch/x86/tests/genopcode.hex
EXTRA_DIST += modules/arch/x86/tests/imm64.asm
EXTRA_DIST += modules/arch/x86/tests/imm64.errwarn
EXTRA_DIST += modules/arch/x86/tests/imm64.hex
EXTRA_DIST += modules/arch/x86/tests/invpcid.asm
EXTRA_DIST += modules/arch/x86/tests/invpcid.hex
EXTRA_DIST += modules/arch/x86/tests/iret.asm
EXTRA_DIST += modules/arch/x86/tests/iret.hex
EXTRA_DIST += modules/arch/x86/tests/jmp64-1.asm
@ -105,6 +111,8 @@ EXTRA_DIST += modules/arch/x86/tests/loopadsz.asm
EXTRA_DIST += modules/arch/x86/tests/loopadsz.hex
EXTRA_DIST += modules/arch/x86/tests/lsahf.asm
EXTRA_DIST += modules/arch/x86/tests/lsahf.hex
EXTRA_DIST += modules/arch/x86/tests/lzcnt.asm
EXTRA_DIST += modules/arch/x86/tests/lzcnt.hex
EXTRA_DIST += modules/arch/x86/tests/mem64-err.asm
EXTRA_DIST += modules/arch/x86/tests/mem64-err.errwarn
EXTRA_DIST += modules/arch/x86/tests/mem64.asm

View file

@ -0,0 +1,32 @@
[bits 64]
andn eax, ebx, ecx ; c4 e2 60 f2 c1
andn eax, ebx, [0] ; c4 e2 60 f2 04 25 00 00 00 00
andn rax, rbx, rcx ; c4 e2 e0 f2 c1
andn rax, rbx, [0] ; c4 e2 e0 f2 04 25 00 00 00 00
bextr eax, ebx, ecx ; c4 e2 70 f7 c3
bextr eax, [0], ecx ; c4 e2 70 f7 04 25 00 00 00 00
bextr rax, rbx, rcx ; c4 e2 f0 f7 c3
bextr rax, [0], rcx ; c4 e2 f0 f7 04 25 00 00 00 00
blsi eax, ecx ; c4 e2 78 f3 d9
blsi eax, [0] ; c4 e2 78 f3 1c 25 00 00 00 00
blsi rax, rcx ; c4 e2 f8 f3 d9
blsi rax, [0] ; c4 e2 f8 f3 1c 25 00 00 00 00
blsmsk eax, ecx ; c4 e2 78 f3 d1
blsmsk eax, [0] ; c4 e2 78 f3 14 25 00 00 00 00
blsmsk rax, rcx ; c4 e2 f8 f3 d1
blsmsk rax, [0] ; c4 e2 f8 f3 14 25 00 00 00 00
blsr eax, ecx ; c4 e2 78 f3 c9
blsr eax, [0] ; c4 e2 78 f3 0c 25 00 00 00 00
blsr rax, rcx ; c4 e2 f8 f3 c9
blsr rax, [0] ; c4 e2 f8 f3 0c 25 00 00 00 00
tzcnt ax, bx ; 66 f3 0f bc c3
tzcnt ax, [0] ; 66 f3 0f bc 04 25 00 00 00 00
tzcnt eax, ebx ; f3 0f bc c3
tzcnt eax, [0] ; f3 0f bc 04 25 00 00 00 00
tzcnt rax, rbx ; f3 48 0f bc c3
tzcnt rax, [0] ; f3 48 0f bc 04 25 00 00 00 00

View file

@ -0,0 +1,193 @@
c4
e2
60
f2
c1
c4
e2
60
f2
04
25
00
00
00
00
c4
e2
e0
f2
c1
c4
e2
e0
f2
04
25
00
00
00
00
c4
e2
70
f7
c3
c4
e2
70
f7
04
25
00
00
00
00
c4
e2
f0
f7
c3
c4
e2
f0
f7
04
25
00
00
00
00
c4
e2
78
f3
d9
c4
e2
78
f3
1c
25
00
00
00
00
c4
e2
f8
f3
d9
c4
e2
f8
f3
1c
25
00
00
00
00
c4
e2
78
f3
d1
c4
e2
78
f3
14
25
00
00
00
00
c4
e2
f8
f3
d1
c4
e2
f8
f3
14
25
00
00
00
00
c4
e2
78
f3
c9
c4
e2
78
f3
0c
25
00
00
00
00
c4
e2
f8
f3
c9
c4
e2
f8
f3
0c
25
00
00
00
00
66
f3
0f
bc
c3
66
f3
0f
bc
04
25
00
00
00
00
f3
0f
bc
c3
f3
0f
bc
04
25
00
00
00
00
f3
48
0f
bc
c3
f3
48
0f
bc
04
25
00
00
00
00

View file

@ -0,0 +1,40 @@
[bits 64]
bzhi eax, ebx, ecx ; c4 e2 70 f5 c3
bzhi eax, [0], ecx ; c4 e2 70 f5 04 25 00 00 00 00
bzhi rax, rbx, rcx ; c4 e2 f0 f5 c3
bzhi rax, [0], rcx ; c4 e2 f0 f5 04 25 00 00 00 00
mulx eax, ebx, ecx ; c4 e2 63 f6 c1
mulx eax, ebx, [0] ; c4 e2 63 f6 04 25 00 00 00 00
mulx rax, rbx, rcx ; c4 e2 e3 f6 c1
mulx rax, rbx, [0] ; c4 e2 e3 f6 04 25 00 00 00 00
pdep eax, ebx, ecx ; c4 e2 63 f5 c1
pdep eax, ebx, [0] ; c4 e2 63 f5 04 25 00 00 00 00
pdep rax, rbx, rcx ; c4 e2 e3 f5 c1
pdep rax, rbx, [0] ; c4 e2 e3 f5 04 25 00 00 00 00
pext eax, ebx, ecx ; c4 e2 62 f5 c1
pext eax, ebx, [0] ; c4 e2 62 f5 04 25 00 00 00 00
pext rax, rbx, rcx ; c4 e2 e2 f5 c1
pext rax, rbx, [0] ; c4 e2 e2 f5 04 25 00 00 00 00
rorx eax, ebx, 3 ; c4 e3 7b f0 c3 03
rorx eax, [0], 3 ; c4 e3 7b f0 04 25 00 00 00 00 03
rorx rax, rbx, 3 ; c4 e3 fb f0 c3 03
rorx rax, [0], 3 ; c4 e3 fb f0 04 25 00 00 00 00 03
sarx eax, ebx, ecx ; c4 e2 72 f7 c3
sarx eax, [0], ecx ; c4 e2 72 f7 04 25 00 00 00 00
sarx rax, rbx, rcx ; c4 e2 f2 f7 c3
sarx rax, [0], rcx ; c4 e2 f2 f7 04 25 00 00 00 00
shlx eax, ebx, ecx ; c4 e2 71 f7 c3
shlx eax, [0], ecx ; c4 e2 71 f7 04 25 00 00 00 00
shlx rax, rbx, rcx ; c4 e2 f1 f7 c3
shlx rax, [0], rcx ; c4 e2 f1 f7 04 25 00 00 00 00
shrx eax, ebx, ecx ; c4 e2 73 f7 c3
shrx eax, [0], ecx ; c4 e2 73 f7 04 25 00 00 00 00
shrx rax, rbx, rcx ; c4 e2 f3 f7 c3
shrx rax, [0], rcx ; c4 e2 f3 f7 04 25 00 00 00 00

View file

@ -0,0 +1,244 @@
c4
e2
70
f5
c3
c4
e2
70
f5
04
25
00
00
00
00
c4
e2
f0
f5
c3
c4
e2
f0
f5
04
25
00
00
00
00
c4
e2
63
f6
c1
c4
e2
63
f6
04
25
00
00
00
00
c4
e2
e3
f6
c1
c4
e2
e3
f6
04
25
00
00
00
00
c4
e2
63
f5
c1
c4
e2
63
f5
04
25
00
00
00
00
c4
e2
e3
f5
c1
c4
e2
e3
f5
04
25
00
00
00
00
c4
e2
62
f5
c1
c4
e2
62
f5
04
25
00
00
00
00
c4
e2
e2
f5
c1
c4
e2
e2
f5
04
25
00
00
00
00
c4
e3
7b
f0
c3
03
c4
e3
7b
f0
04
25
00
00
00
00
03
c4
e3
fb
f0
c3
03
c4
e3
fb
f0
04
25
00
00
00
00
03
c4
e2
72
f7
c3
c4
e2
72
f7
04
25
00
00
00
00
c4
e2
f2
f7
c3
c4
e2
f2
f7
04
25
00
00
00
00
c4
e2
71
f7
c3
c4
e2
71
f7
04
25
00
00
00
00
c4
e2
f1
f7
c3
c4
e2
f1
f7
04
25
00
00
00
00
c4
e2
73
f7
c3
c4
e2
73
f7
04
25
00
00
00
00
c4
e2
f3
f7
c3
c4
e2
f3
f7
04
25
00
00
00
00

View file

@ -0,0 +1,6 @@
[bits 32]
invpcid eax, oword [0] ; 66 0f 38 82 05 00 00 00 00
[bits 64]
invpcid rax, oword [0] ; 66 0f 38 82 04 25 00 00 00 00

View file

@ -0,0 +1,19 @@
66
0f
38
82
05
00
00
00
00
66
0f
38
82
04
25
00
00
00
00

View file

@ -0,0 +1,8 @@
[bits 64]
lzcnt ax, bx ; 66 f3 0f bd c3
lzcnt ax, [0] ; 66 f3 0f bd 04 25 00 00 00 00
lzcnt eax, ebx ; f3 0f bd c3
lzcnt eax, [0] ; f3 0f bd 04 25 00 00 00 00
lzcnt rax, rbx ; f3 48 0f bd c3
lzcnt rax, [0] ; f3 48 0f bd 04 25 00 00 00 00

View file

@ -0,0 +1,43 @@
66
f3
0f
bd
c3
66
f3
0f
bd
04
25
00
00
00
00
f3
0f
bd
c3
f3
0f
bd
04
25
00
00
00
00
f3
48
0f
bd
c3
f3
48
0f
bd
04
25
00
00
00
00

View file

@ -78,6 +78,11 @@
#define CPU_XSAVEOPT 44 /* Intel XSAVEOPT instruction */
#define CPU_EPTVPID 45 /* Intel INVEPT, INVVPID instructions */
#define CPU_SMX 46 /* Intel SMX instruction (GETSEC) */
#define CPU_AVX2 47 /* Intel AVX2 instructions */
#define CPU_BMI1 48 /* Intel BMI1 instructions */
#define CPU_BMI2 49 /* Intel BMI2 instructions */
#define CPU_INVPCID 50 /* Intel INVPCID instruction */
#define CPU_LZCNT 51 /* Intel LZCNT instruction */
enum x86_parser_type {
X86_PARSER_NASM = 0,

View file

@ -389,6 +389,16 @@ eptvpid, x86_cpu_set, CPU_EPTVPID
noeptvpid, x86_cpu_clear, CPU_EPTVPID
smx, x86_cpu_set, CPU_SMX
nosmx, x86_cpu_clear, CPU_SMX
avx2, x86_cpu_set, CPU_AVX2
noavx2, x86_cpu_clear, CPU_AVX2
bmi1, x86_cpu_set, CPU_BMI1
nobmi1, x86_cpu_clear, CPU_BMI1
bmi2, x86_cpu_set, CPU_BMI2
nobmi2, x86_cpu_clear, CPU_BMI2
invpcid, x86_cpu_set, CPU_INVPCID
noinvpcid, x86_cpu_clear, CPU_INVPCID
lzcnt, x86_cpu_set, CPU_LZCNT
nolzcnt, x86_cpu_clear, CPU_LZCNT
# Change NOP patterns
basicnop, x86_nop, X86_NOP_BASIC
intelnop, x86_nop, X86_NOP_INTEL