xref: /kernel/linux/linux-6.6/arch/x86/lib/inat.c (revision 62306a36)
162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * x86 instruction attribute tables
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Written by Masami Hiramatsu <mhiramat@redhat.com>
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci#include <asm/insn.h> /* __ignore_sync_check__ */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci/* Attribute tables are generated from opcode map */
1062306a36Sopenharmony_ci#include "inat-tables.c"
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci/* Attribute search APIs */
1362306a36Sopenharmony_ciinsn_attr_t inat_get_opcode_attribute(insn_byte_t opcode)
1462306a36Sopenharmony_ci{
1562306a36Sopenharmony_ci	return inat_primary_table[opcode];
1662306a36Sopenharmony_ci}
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ciint inat_get_last_prefix_id(insn_byte_t last_pfx)
1962306a36Sopenharmony_ci{
2062306a36Sopenharmony_ci	insn_attr_t lpfx_attr;
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci	lpfx_attr = inat_get_opcode_attribute(last_pfx);
2362306a36Sopenharmony_ci	return inat_last_prefix_id(lpfx_attr);
2462306a36Sopenharmony_ci}
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ciinsn_attr_t inat_get_escape_attribute(insn_byte_t opcode, int lpfx_id,
2762306a36Sopenharmony_ci				      insn_attr_t esc_attr)
2862306a36Sopenharmony_ci{
2962306a36Sopenharmony_ci	const insn_attr_t *table;
3062306a36Sopenharmony_ci	int n;
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	n = inat_escape_id(esc_attr);
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci	table = inat_escape_tables[n][0];
3562306a36Sopenharmony_ci	if (!table)
3662306a36Sopenharmony_ci		return 0;
3762306a36Sopenharmony_ci	if (inat_has_variant(table[opcode]) && lpfx_id) {
3862306a36Sopenharmony_ci		table = inat_escape_tables[n][lpfx_id];
3962306a36Sopenharmony_ci		if (!table)
4062306a36Sopenharmony_ci			return 0;
4162306a36Sopenharmony_ci	}
4262306a36Sopenharmony_ci	return table[opcode];
4362306a36Sopenharmony_ci}
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ciinsn_attr_t inat_get_group_attribute(insn_byte_t modrm, int lpfx_id,
4662306a36Sopenharmony_ci				     insn_attr_t grp_attr)
4762306a36Sopenharmony_ci{
4862306a36Sopenharmony_ci	const insn_attr_t *table;
4962306a36Sopenharmony_ci	int n;
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	n = inat_group_id(grp_attr);
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci	table = inat_group_tables[n][0];
5462306a36Sopenharmony_ci	if (!table)
5562306a36Sopenharmony_ci		return inat_group_common_attribute(grp_attr);
5662306a36Sopenharmony_ci	if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && lpfx_id) {
5762306a36Sopenharmony_ci		table = inat_group_tables[n][lpfx_id];
5862306a36Sopenharmony_ci		if (!table)
5962306a36Sopenharmony_ci			return inat_group_common_attribute(grp_attr);
6062306a36Sopenharmony_ci	}
6162306a36Sopenharmony_ci	return table[X86_MODRM_REG(modrm)] |
6262306a36Sopenharmony_ci	       inat_group_common_attribute(grp_attr);
6362306a36Sopenharmony_ci}
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ciinsn_attr_t inat_get_avx_attribute(insn_byte_t opcode, insn_byte_t vex_m,
6662306a36Sopenharmony_ci				   insn_byte_t vex_p)
6762306a36Sopenharmony_ci{
6862306a36Sopenharmony_ci	const insn_attr_t *table;
6962306a36Sopenharmony_ci	if (vex_m > X86_VEX_M_MAX || vex_p > INAT_LSTPFX_MAX)
7062306a36Sopenharmony_ci		return 0;
7162306a36Sopenharmony_ci	/* At first, this checks the master table */
7262306a36Sopenharmony_ci	table = inat_avx_tables[vex_m][0];
7362306a36Sopenharmony_ci	if (!table)
7462306a36Sopenharmony_ci		return 0;
7562306a36Sopenharmony_ci	if (!inat_is_group(table[opcode]) && vex_p) {
7662306a36Sopenharmony_ci		/* If this is not a group, get attribute directly */
7762306a36Sopenharmony_ci		table = inat_avx_tables[vex_m][vex_p];
7862306a36Sopenharmony_ci		if (!table)
7962306a36Sopenharmony_ci			return 0;
8062306a36Sopenharmony_ci	}
8162306a36Sopenharmony_ci	return table[opcode];
8262306a36Sopenharmony_ci}
8362306a36Sopenharmony_ci
84