Skip to content
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

Add decode/encode support for additional Intel cache management instructions. #7109

Merged
merged 3 commits into from
Dec 10, 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
47 changes: 43 additions & 4 deletions core/ir/x86/decode_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ const instr_info_t * const op_instr[] =
/* OP_stmxcsr */ &e_vex_extensions[62][0],
khuey marked this conversation as resolved.
Show resolved Hide resolved
/* OP_lfence */ &mod_extensions[6][1],
/* OP_mfence */ &mod_extensions[7][1],
/* OP_clflush */ &mod_extensions[3][0],
/* OP_clflush */ &prefix_extensions[194][0],
/* OP_sfence */ &mod_extensions[3][1],
/* OP_prefetchnta */ &base_extensions[23][0],
/* OP_prefetcht0 */ &base_extensions[23][1],
Expand Down Expand Up @@ -1655,6 +1655,15 @@ const instr_info_t * const op_instr[] =

/* RDPID */
/* OP_rdpid */ &prefix_extensions[193][1],

/* Not really part of CLWB but never got added earlier. */
/* OP_clflushopt */ &prefix_extensions[194][2],

/* CLWB */
/* OP_clwb */ &mod_extensions[123][0],

/* CLDEMOTE */
/* OP_cldemote */ &second_byte[0x1c],
};


Expand Down Expand Up @@ -2517,7 +2526,7 @@ const instr_info_t second_byte[] = {
{OP_nop_modrm, 0x0f1910, catSIMD, "nop", xx, xx, Ed, xx, xx, mrm, x, END_LIST},
{PREFIX_EXT, 0x0f1a10, catUncategorized, "(prefix ext 186)", xx, xx, xx, xx, xx, mrm, x, 186},
{PREFIX_EXT, 0x0f1b10, catUncategorized, "(prefix ext 187)", xx, xx, xx, xx, xx, mrm, x, 187},
{OP_nop_modrm, 0x0f1c10, catSIMD, "nop", xx, xx, Ed, xx, xx, mrm, x, END_LIST},
{OP_cldemote, 0x0f1c30, catOther, "cldemote", xx, xx, Mb, xx, xx, mrm|reqp, x, END_LIST},
{OP_nop_modrm, 0x0f1d10, catSIMD, "nop", xx, xx, Ed, xx, xx, mrm, x, END_LIST},
{OP_nop_modrm, 0x0f1e10, catSIMD, "nop", xx, xx, Ed, xx, xx, mrm, x, END_LIST},
{OP_nop_modrm, 0x0f1f10, catSIMD, "nop", xx, xx, Ed, xx, xx, mrm, x, END_LIST},
Expand Down Expand Up @@ -5946,6 +5955,32 @@ const instr_info_t prefix_extensions[][12] = {
{INVALID, 0xf30fc737, catUncategorized, "(bad)" , xx, xx, xx, xx, xx, no, x, NA},
{INVALID, 0x660fc737, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
{INVALID, 0xf20fc737, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
},{ /* prefix extension 194 */
{OP_clflush, 0x0fae37, catSIMD, "clflush", xx, xx, Mb, xx, xx, mrm, x, END_LIST},
khuey marked this conversation as resolved.
Show resolved Hide resolved
{INVALID, 0xf30fae37, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
{OP_clflushopt, 0x660fae37, catOther, "clflushopt", xx, xx, Mb, xx, xx, mrm, x, END_LIST},
{INVALID, 0xf20fae37, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
{INVALID, 0x0fae37, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
{INVALID, 0xf30fae37, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
{INVALID, 0x660fae37, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
{INVALID, 0xf20fae37, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
{INVALID, 0x0fae37, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
{INVALID, 0xf30fae37, catUncategorized, "(bad)" , xx, xx, xx, xx, xx, no, x, NA},
{INVALID, 0x660fae37, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
{INVALID, 0xf20fae37, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
},{ /* prefix extension 195 */
{REX_W_EXT, 0x0fae36, catUncategorized, "(rex.w ext 4)", xx, xx, xx, xx, xx, mrm, x, 4},
{INVALID, 0xf30fae36, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
{MOD_EXT, 0x660fae36, catUncategorized, "(mod ext 123)", xx, xx, xx, xx, xx, mrm, x, 123},
{INVALID, 0xf20fae36, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
{INVALID, 0x0fae36, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
{INVALID, 0xf30fae36, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
{INVALID, 0x660fae36, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
{INVALID, 0xf20fae36, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
{INVALID, 0x0fae36, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
{INVALID, 0xf30fae36, catUncategorized, "(bad)" , xx, xx, xx, xx, xx, no, x, NA},
{INVALID, 0x660fae36, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
{INVALID, 0xf20fae36, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, NA},
}
};
/****************************************************************************
Expand Down Expand Up @@ -6596,7 +6631,7 @@ const instr_info_t mod_extensions[][2] = {
{RM_EXT, 0x0f0177, catUncategorized, "(group 7 mod + rm ext 2)", xx, xx, xx, xx, xx, mrm, x, 2},
},
{ /* mod extension 3 */
{OP_clflush, 0x0fae37, catSIMD, "clflush", xx, xx, Mb, xx, xx, mrm, x, END_LIST},
{PREFIX_EXT, 0x0fae37, catUncategorized, "(prefix ext 194)", xx, xx, xx, xx, xx, no, x, 194},
// If we add an "atomic" category we'd put this there.
// Without it, "state" might best be interpreted as a barrier, so we use it for
// all the OP_*fence opcodes.
Expand All @@ -6616,7 +6651,7 @@ const instr_info_t mod_extensions[][2] = {
{OP_lfence, 0xe80fae75, catState, "lfence", xx, xx, xx, xx, xx, mrm, x, END_LIST},
},
{ /* mod extension 7 */
{REX_W_EXT, 0x0fae36, catUncategorized, "(rex.w ext 4)", xx, xx, xx, xx, xx, mrm, x, 4},
{PREFIX_EXT, 0x0fae36, catUncategorized, "(prefix ext 195)", xx, xx, xx, xx, xx, no, x, 195},
{OP_mfence, 0xf00fae76, catState, "mfence", xx, xx, xx, xx, xx, mrm, x, END_LIST},
},
{ /* mod extension 8 */
Expand Down Expand Up @@ -7087,6 +7122,10 @@ const instr_info_t mod_extensions[][2] = {
{OP_enqcmd, 0xf238f808, catMove | catOther, "enqcmd", GesvS_oq, xx, Moq, xx, xx, mrm, fW6, END_LIST},
{INVALID, 0xf238f808, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, END_LIST},
},
{ /* mod extension 123 */
{OP_clwb, 0x660fae36, catOther, "clwb", xx, xx, Mb, xx, xx, mrm, no, END_LIST},
{INVALID, 0x660fae36, catUncategorized, "(bad)", xx, xx, xx, xx, xx, no, x, END_LIST},
},
};

/* Naturally all of these have modrm bytes even if they have no explicit operands */
Expand Down
24 changes: 24 additions & 0 deletions core/ir/x86/instr_create_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,30 @@
* created with OPND_CREATE_MEM_clflush() to get the appropriate operand size.
*/
#define INSTR_CREATE_clflush(dc, s) instr_create_0dst_1src((dc), OP_clflush, (s))
/**
* This INSTR_CREATE_xxx macro creates an instr_t with opcode OP_xxx and
* the given explicit operands, automatically supplying any implicit operands.
* \param dc The void * dcontext used to allocate memory for the instr_t.
* \param s The opnd_t explicit source operand for the instruction, which can be
* created with OPND_CREATE_MEM_clflush() to get the appropriate operand size.
khuey marked this conversation as resolved.
Show resolved Hide resolved
*/
#define INSTR_CREATE_clflushopt(dc, s) instr_create_0dst_1src((dc), OP_clflushopt, (s))
/**
* This INSTR_CREATE_xxx macro creates an instr_t with opcode OP_xxx and
* the given explicit operands, automatically supplying any implicit operands.
* \param dc The void * dcontext used to allocate memory for the instr_t.
* \param s The opnd_t explicit source operand for the instruction, which can be
* created with OPND_CREATE_MEM_clflush() to get the appropriate operand size.
*/
#define INSTR_CREATE_clwb(dc, s) instr_create_0dst_1src((dc), OP_clwb, (s))
/**
* This INSTR_CREATE_xxx macro creates an instr_t with opcode OP_xxx and
* the given explicit operands, automatically supplying any implicit operands.
* \param dc The void * dcontext used to allocate memory for the instr_t.
* \param s The opnd_t explicit source operand for the instruction, which can be
* created with OPND_CREATE_MEM_clflush() to get the appropriate operand size.
*/
#define INSTR_CREATE_cldemote(dc, s) instr_create_0dst_1src((dc), OP_cldemote, (s))
/**
* This INSTR_CREATE_xxx macro creates an instr_t with opcode OP_xxx and the
* given explicit operands, automatically supplying any implicit operands.
Expand Down
9 changes: 9 additions & 0 deletions core/ir/x86/opcode_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -1642,6 +1642,15 @@ enum {
/* RDPID */
/* 1448 */ OP_rdpid, /**< IA-32/AMD64 rdpid opcode. */

/* Not really part of CLWB but never got added earlier. */
/* 1449 */ OP_clflushopt, /**< IA-32/AMD64 clflushopt opcode. */

/* CLWB */
/* 1450 */ OP_clwb, /**< IA-32/AMD64 clwb opcode. */

/* CLDEMOTE */
/* 1451 */ OP_cldemote, /**< IA-32/AMD64 cldemote opcode. */

OP_AFTER_LAST,
OP_FIRST = OP_add, /**< First real opcode. */
OP_LAST = OP_AFTER_LAST - 1, /**< Last real opcode. */
Expand Down
2 changes: 1 addition & 1 deletion suite/tests/api/dis-x64.expect
Original file line number Diff line number Diff line change
Expand Up @@ -2897,7 +2897,7 @@
+0x1ca0 3a f5 cmp dh, ch
+0x1ca2 48 bf 79 0f c9 63 6d mov rdi, 0x77705d6d63c90f79
5d 70 77
+0x1cac 0f 1c 4f 65 nop dword ptr [rdi+0x65]
+0x1cac 0f 1c 4f 65 cldemote byte ptr [rdi+0x65]
+0x1cb0 74 2a jz 0x0000000010001cdc
+0x1cb2 12 cc adc cl, ah
+0x1cb4 37...?? <INVALID>
Expand Down
2 changes: 1 addition & 1 deletion suite/tests/api/dis-x86.expect
Original file line number Diff line number Diff line change
Expand Up @@ -2960,7 +2960,7 @@
+0x1ca8 6d insd
+0x1ca9 5d pop ebp
+0x1caa 70 77 jo 0x10001d23
+0x1cac 0f 1c 4f 65 nop dword ptr [edi+0x65]
+0x1cac 0f 1c 4f 65 cldemote byte ptr [edi+0x65]
+0x1cb0 74 2a jz 0x10001cdc
+0x1cb2 12 cc adc cl, ah
+0x1cb4 37 aaa
Expand Down
5 changes: 3 additions & 2 deletions suite/tests/api/ir_x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -1293,9 +1293,10 @@ test_hint_nops(void *dc)
/* other types of hintable nop [eax] */
buf[2] = 0x00;
for (buf[1] = 0x19; buf[1] <= 0x1f; buf[1]++) {
/* Intel is using these encodings now for the MPX instructions bndldx and bndstx.
/* Intel is using these encodings now for the MPX instructions bndldx and bndstx,
* and cldemote.
*/
if (buf[1] == 0x1a || buf[1] == 0x1b)
if (buf[1] == 0x1a || buf[1] == 0x1b || buf[1] == 0x1c)
continue;
pc = decode(dc, buf, instr);
ASSERT(instr_get_opcode(instr) == OP_nop_modrm);
Expand Down
3 changes: 3 additions & 0 deletions suite/tests/api/ir_x86_1args.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ OPCODE(xsaveopt32, xsaveopt32, xsaveopt32, 0, MEMARG(OPSZ_xsave))
OPCODE(xsaveopt64, xsaveopt64, xsaveopt64, X64_ONLY, MEMARG(OPSZ_xsave))
OPCODE(xsavec32, xsavec32, xsavec32, 0, MEMARG(OPSZ_xsave))
OPCODE(xsavec64, xsavec64, xsavec64, X64_ONLY, MEMARG(OPSZ_xsave))
OPCODE(clflushopt, clflushopt, clflushopt, 0, MEMARG(OPSZ_clflush))
OPCODE(clwb, clwb, clwb, 0, MEMARG(OPSZ_clflush))
OPCODE(cldemote, cldemote, cldemote, 0, MEMARG(OPSZ_clflush))

/****************************************************************************/
/* single immed argument */
Expand Down
Loading
Loading