From fe6fe0ffc132b4c28317bfc5261ba4cf08dade24 Mon Sep 17 00:00:00 2001 From: Alexis Engelke Date: Sun, 27 Nov 2022 13:15:13 +0100 Subject: [PATCH] instrs: Add CMPCCXADD --- decode-test.c | 33 +++++++++++++++++++++++++++++++++ encode-test.inc | 33 +++++++++++++++++++++++++++++++++ encode.c | 3 ++- instrs.txt | 18 ++++++++++++++++++ parseinstrs.py | 1 + 5 files changed, 87 insertions(+), 1 deletion(-) diff --git a/decode-test.c b/decode-test.c index dad9a5b..640acb9 100644 --- a/decode-test.c +++ b/decode-test.c @@ -438,6 +438,39 @@ main(int argc, char** argv) TEST64("\xf2\x0f\x38\xfc\x01", "aor dword ptr [rcx], eax"); TEST64("\xf2\x48\x0f\x38\xfc\x01", "aor qword ptr [rcx], rax"); + TEST64("\xc4\xe2\x61\xe0\x08", "cmpoxadd dword ptr [rax], ecx, ebx"); + TEST64("\xc4\xe2\xe1\xe0\x08", "cmpoxadd qword ptr [rax], rcx, rbx"); + TEST64("\xc4\xe2\x61\xe1\x08", "cmpnoxadd dword ptr [rax], ecx, ebx"); + TEST64("\xc4\xe2\xe1\xe1\x08", "cmpnoxadd qword ptr [rax], rcx, rbx"); + TEST64("\xc4\xe2\x61\xe2\x08", "cmpbxadd dword ptr [rax], ecx, ebx"); + TEST64("\xc4\xe2\xe1\xe2\x08", "cmpbxadd qword ptr [rax], rcx, rbx"); + TEST64("\xc4\xe2\x61\xe3\x08", "cmpnbxadd dword ptr [rax], ecx, ebx"); + TEST64("\xc4\xe2\xe1\xe3\x08", "cmpnbxadd qword ptr [rax], rcx, rbx"); + TEST64("\xc4\xe2\x61\xe4\x08", "cmpzxadd dword ptr [rax], ecx, ebx"); + TEST64("\xc4\xe2\xe1\xe4\x08", "cmpzxadd qword ptr [rax], rcx, rbx"); + TEST64("\xc4\xe2\x61\xe5\x08", "cmpnzxadd dword ptr [rax], ecx, ebx"); + TEST64("\xc4\xe2\xe1\xe5\x08", "cmpnzxadd qword ptr [rax], rcx, rbx"); + TEST64("\xc4\xe2\x61\xe6\x08", "cmpbexadd dword ptr [rax], ecx, ebx"); + TEST64("\xc4\xe2\xe1\xe6\x08", "cmpbexadd qword ptr [rax], rcx, rbx"); + TEST64("\xc4\xe2\x61\xe7\x08", "cmpnbexadd dword ptr [rax], ecx, ebx"); + TEST64("\xc4\xe2\xe1\xe7\x08", "cmpnbexadd qword ptr [rax], rcx, rbx"); + TEST64("\xc4\xe2\x61\xe8\x08", "cmpsxadd dword ptr [rax], ecx, ebx"); + TEST64("\xc4\xe2\xe1\xe8\x08", "cmpsxadd qword ptr [rax], rcx, rbx"); + TEST64("\xc4\xe2\x61\xe9\x08", "cmpnsxadd dword ptr [rax], ecx, ebx"); + TEST64("\xc4\xe2\xe1\xe9\x08", "cmpnsxadd qword ptr [rax], rcx, rbx"); + TEST64("\xc4\xe2\x61\xea\x08", "cmppxadd dword ptr [rax], ecx, ebx"); + TEST64("\xc4\xe2\xe1\xea\x08", "cmppxadd qword ptr [rax], rcx, rbx"); + TEST64("\xc4\xe2\x61\xeb\x08", "cmpnpxadd dword ptr [rax], ecx, ebx"); + TEST64("\xc4\xe2\xe1\xeb\x08", "cmpnpxadd qword ptr [rax], rcx, rbx"); + TEST64("\xc4\xe2\x61\xec\x08", "cmplxadd dword ptr [rax], ecx, ebx"); + TEST64("\xc4\xe2\xe1\xec\x08", "cmplxadd qword ptr [rax], rcx, rbx"); + TEST64("\xc4\xe2\x61\xed\x08", "cmpnlxadd dword ptr [rax], ecx, ebx"); + TEST64("\xc4\xe2\xe1\xed\x08", "cmpnlxadd qword ptr [rax], rcx, rbx"); + TEST64("\xc4\xe2\x61\xee\x08", "cmplexadd dword ptr [rax], ecx, ebx"); + TEST64("\xc4\xe2\xe1\xee\x08", "cmplexadd qword ptr [rax], rcx, rbx"); + TEST64("\xc4\xe2\x61\xef\x08", "cmpnlexadd dword ptr [rax], ecx, ebx"); + TEST64("\xc4\xe2\xe1\xef\x08", "cmpnlexadd qword ptr [rax], rcx, rbx"); + TEST("\x0f\xae\xe8", "lfence"); TEST("\x0f\xae\xe9", "lfence"); TEST("\x0f\xae\xef", "lfence"); diff --git a/encode-test.inc b/encode-test.inc index f1ac21b..257d8ed 100644 --- a/encode-test.inc +++ b/encode-test.inc @@ -190,6 +190,39 @@ TEST("\xf3\x48\x0f\x38\xfc\x01", AXOR64mr, 0, FE_MEM(FE_CX, 0, FE_NOREG, 0), FE_ TEST("\xf2\x0f\x38\xfc\x01", AOR32mr, 0, FE_MEM(FE_CX, 0, FE_NOREG, 0), FE_AX); TEST("\xf2\x48\x0f\x38\xfc\x01", AOR64mr, 0, FE_MEM(FE_CX, 0, FE_NOREG, 0), FE_AX); +TEST("\xc4\xe2\x61\xe0\x08", CMPOXADD32mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\xe1\xe0\x08", CMPOXADD64mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\x61\xe1\x08", CMPNOXADD32mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\xe1\xe1\x08", CMPNOXADD64mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\x61\xe2\x08", CMPBXADD32mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\xe1\xe2\x08", CMPBXADD64mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\x61\xe3\x08", CMPNBXADD32mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\xe1\xe3\x08", CMPNBXADD64mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\x61\xe4\x08", CMPZXADD32mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\xe1\xe4\x08", CMPZXADD64mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\x61\xe5\x08", CMPNZXADD32mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\xe1\xe5\x08", CMPNZXADD64mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\x61\xe6\x08", CMPBEXADD32mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\xe1\xe6\x08", CMPBEXADD64mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\x61\xe7\x08", CMPNBEXADD32mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\xe1\xe7\x08", CMPNBEXADD64mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\x61\xe8\x08", CMPSXADD32mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\xe1\xe8\x08", CMPSXADD64mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\x61\xe9\x08", CMPNSXADD32mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\xe1\xe9\x08", CMPNSXADD64mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\x61\xea\x08", CMPPXADD32mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\xe1\xea\x08", CMPPXADD64mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\x61\xeb\x08", CMPNPXADD32mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\xe1\xeb\x08", CMPNPXADD64mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\x61\xec\x08", CMPLXADD32mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\xe1\xec\x08", CMPLXADD64mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\x61\xed\x08", CMPNLXADD32mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\xe1\xed\x08", CMPNLXADD64mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\x61\xee\x08", CMPLEXADD32mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\xe1\xee\x08", CMPLEXADD64mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\x61\xef\x08", CMPNLEXADD32mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); +TEST("\xc4\xe2\xe1\xef\x08", CMPNLEXADD64mrr, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0), FE_CX, FE_BX); + // Test FPU instructions TEST("\xd8\x00", FADDm32, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0)); TEST("\xdc\x00", FADDm64, 0, FE_MEM(FE_AX, 0, FE_NOREG, 0)); diff --git a/encode.c b/encode.c index 81a5b0e..58ea016 100644 --- a/encode.c +++ b/encode.c @@ -259,7 +259,7 @@ typedef enum { ENC_M, ENC_M1, ENC_MI, ENC_MC, ENC_MR, ENC_RM, ENC_RMA, ENC_MRI, ENC_RMI, ENC_MRC, ENC_AM, ENC_MA, ENC_I, ENC_IA, ENC_O, ENC_OI, ENC_OA, ENC_S, ENC_A, ENC_D, ENC_FD, ENC_TD, - ENC_RVM, ENC_RVMI, ENC_RVMR, ENC_RMV, ENC_VM, ENC_VMI, ENC_MVR, + ENC_RVM, ENC_RVMI, ENC_RVMR, ENC_RMV, ENC_VM, ENC_VMI, ENC_MVR, ENC_MRV, ENC_MAX } Encoding; @@ -305,6 +305,7 @@ const struct EncodingInfo encoding_infos[ENC_MAX] = { [ENC_VM] = { .modrm = 1^3, .vexreg = 0^3 }, [ENC_VMI] = { .modrm = 1^3, .vexreg = 0^3, .immctl = 4, .immidx = 2 }, [ENC_MVR] = { .modrm = 0^3, .modreg = 2^3, .vexreg = 1^3 }, + [ENC_MRV] = { .modrm = 0^3, .modreg = 1^3, .vexreg = 2^3 }, }; struct EncodeDesc { diff --git a/instrs.txt b/instrs.txt index 3ca6860..dedf9ca 100644 --- a/instrs.txt +++ b/instrs.txt @@ -1626,6 +1626,24 @@ NP.0f38fc/m MR My Gy - - AADD F=RAO-INT F3.0f38fc/m MR My Gy - - AXOR F=RAO-INT F2.0f38fc/m MR My Gy - - AOR F=RAO-INT +# CMPCCXADD +VEX.66.L0.0f38e0/m MRV My Gy By - CMPOXADD O64 F=CMPCCXADD EFL=m--mmmmm +VEX.66.L0.0f38e1/m MRV My Gy By - CMPNOXADD O64 F=CMPCCXADD EFL=m--mmmmm +VEX.66.L0.0f38e2/m MRV My Gy By - CMPBXADD O64 F=CMPCCXADD EFL=m--mmmmm +VEX.66.L0.0f38e3/m MRV My Gy By - CMPNBXADD O64 F=CMPCCXADD EFL=m--mmmmm +VEX.66.L0.0f38e4/m MRV My Gy By - CMPZXADD O64 F=CMPCCXADD EFL=m--mmmmm +VEX.66.L0.0f38e5/m MRV My Gy By - CMPNZXADD O64 F=CMPCCXADD EFL=m--mmmmm +VEX.66.L0.0f38e6/m MRV My Gy By - CMPBEXADD O64 F=CMPCCXADD EFL=m--mmmmm +VEX.66.L0.0f38e7/m MRV My Gy By - CMPNBEXADD O64 F=CMPCCXADD EFL=m--mmmmm +VEX.66.L0.0f38e8/m MRV My Gy By - CMPSXADD O64 F=CMPCCXADD EFL=m--mmmmm +VEX.66.L0.0f38e9/m MRV My Gy By - CMPNSXADD O64 F=CMPCCXADD EFL=m--mmmmm +VEX.66.L0.0f38ea/m MRV My Gy By - CMPPXADD O64 F=CMPCCXADD EFL=m--mmmmm +VEX.66.L0.0f38eb/m MRV My Gy By - CMPNPXADD O64 F=CMPCCXADD EFL=m--mmmmm +VEX.66.L0.0f38ec/m MRV My Gy By - CMPLXADD O64 F=CMPCCXADD EFL=m--mmmmm +VEX.66.L0.0f38ed/m MRV My Gy By - CMPNLXADD O64 F=CMPCCXADD EFL=m--mmmmm +VEX.66.L0.0f38ee/m MRV My Gy By - CMPLEXADD O64 F=CMPCCXADD EFL=m--mmmmm +VEX.66.L0.0f38ef/m MRV My Gy By - CMPNLEXADD O64 F=CMPCCXADD EFL=m--mmmmm + # AESKLE/KL (Key Locker) F3.0f38d8/0m M M - - - AESENCWIDE128KL F=AESKLE F3.0f38d8/1m M M - - - AESDECWIDE128KL F=AESKLE diff --git a/parseinstrs.py b/parseinstrs.py index 5cf6e96..247a463 100644 --- a/parseinstrs.py +++ b/parseinstrs.py @@ -75,6 +75,7 @@ ENCODINGS = { "VM": InstrFlags(modrm=1, modrm_idx=1^3, vexreg_idx=0^3), "VMI": InstrFlags(modrm=1, modrm_idx=1^3, vexreg_idx=0^3, imm_idx=2^3, imm_control=4), "MVR": InstrFlags(modrm=1, modrm_idx=0^3, modreg_idx=2^3, vexreg_idx=1^3), + "MRV": InstrFlags(modrm=1, modrm_idx=0^3, modreg_idx=1^3, vexreg_idx=2^3), } ENCODING_OPTYS = ["modrm", "modreg", "vexreg", "imm"] ENCODING_OPORDER = { enc: sorted(ENCODING_OPTYS, key=lambda ty: getattr(ENCODINGS[enc], ty+"_idx")^3) for enc in ENCODINGS}