xref: /kernel/linux/linux-5.10/arch/x86/lib/inat.c (revision 8c2ecf20)
18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * x86 instruction attribute tables
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Written by Masami Hiramatsu <mhiramat@redhat.com>
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci#include <asm/insn.h> /* __ignore_sync_check__ */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci/* Attribute tables are generated from opcode map */
108c2ecf20Sopenharmony_ci#include "inat-tables.c"
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci/* Attribute search APIs */
138c2ecf20Sopenharmony_ciinsn_attr_t inat_get_opcode_attribute(insn_byte_t opcode)
148c2ecf20Sopenharmony_ci{
158c2ecf20Sopenharmony_ci	return inat_primary_table[opcode];
168c2ecf20Sopenharmony_ci}
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ciint inat_get_last_prefix_id(insn_byte_t last_pfx)
198c2ecf20Sopenharmony_ci{
208c2ecf20Sopenharmony_ci	insn_attr_t lpfx_attr;
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci	lpfx_attr = inat_get_opcode_attribute(last_pfx);
238c2ecf20Sopenharmony_ci	return inat_last_prefix_id(lpfx_attr);
248c2ecf20Sopenharmony_ci}
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ciinsn_attr_t inat_get_escape_attribute(insn_byte_t opcode, int lpfx_id,
278c2ecf20Sopenharmony_ci				      insn_attr_t esc_attr)
288c2ecf20Sopenharmony_ci{
298c2ecf20Sopenharmony_ci	const insn_attr_t *table;
308c2ecf20Sopenharmony_ci	int n;
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci	n = inat_escape_id(esc_attr);
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci	table = inat_escape_tables[n][0];
358c2ecf20Sopenharmony_ci	if (!table)
368c2ecf20Sopenharmony_ci		return 0;
378c2ecf20Sopenharmony_ci	if (inat_has_variant(table[opcode]) && lpfx_id) {
388c2ecf20Sopenharmony_ci		table = inat_escape_tables[n][lpfx_id];
398c2ecf20Sopenharmony_ci		if (!table)
408c2ecf20Sopenharmony_ci			return 0;
418c2ecf20Sopenharmony_ci	}
428c2ecf20Sopenharmony_ci	return table[opcode];
438c2ecf20Sopenharmony_ci}
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ciinsn_attr_t inat_get_group_attribute(insn_byte_t modrm, int lpfx_id,
468c2ecf20Sopenharmony_ci				     insn_attr_t grp_attr)
478c2ecf20Sopenharmony_ci{
488c2ecf20Sopenharmony_ci	const insn_attr_t *table;
498c2ecf20Sopenharmony_ci	int n;
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	n = inat_group_id(grp_attr);
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci	table = inat_group_tables[n][0];
548c2ecf20Sopenharmony_ci	if (!table)
558c2ecf20Sopenharmony_ci		return inat_group_common_attribute(grp_attr);
568c2ecf20Sopenharmony_ci	if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && lpfx_id) {
578c2ecf20Sopenharmony_ci		table = inat_group_tables[n][lpfx_id];
588c2ecf20Sopenharmony_ci		if (!table)
598c2ecf20Sopenharmony_ci			return inat_group_common_attribute(grp_attr);
608c2ecf20Sopenharmony_ci	}
618c2ecf20Sopenharmony_ci	return table[X86_MODRM_REG(modrm)] |
628c2ecf20Sopenharmony_ci	       inat_group_common_attribute(grp_attr);
638c2ecf20Sopenharmony_ci}
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ciinsn_attr_t inat_get_avx_attribute(insn_byte_t opcode, insn_byte_t vex_m,
668c2ecf20Sopenharmony_ci				   insn_byte_t vex_p)
678c2ecf20Sopenharmony_ci{
688c2ecf20Sopenharmony_ci	const insn_attr_t *table;
698c2ecf20Sopenharmony_ci	if (vex_m > X86_VEX_M_MAX || vex_p > INAT_LSTPFX_MAX)
708c2ecf20Sopenharmony_ci		return 0;
718c2ecf20Sopenharmony_ci	/* At first, this checks the master table */
728c2ecf20Sopenharmony_ci	table = inat_avx_tables[vex_m][0];
738c2ecf20Sopenharmony_ci	if (!table)
748c2ecf20Sopenharmony_ci		return 0;
758c2ecf20Sopenharmony_ci	if (!inat_is_group(table[opcode]) && vex_p) {
768c2ecf20Sopenharmony_ci		/* If this is not a group, get attribute directly */
778c2ecf20Sopenharmony_ci		table = inat_avx_tables[vex_m][vex_p];
788c2ecf20Sopenharmony_ci		if (!table)
798c2ecf20Sopenharmony_ci			return 0;
808c2ecf20Sopenharmony_ci	}
818c2ecf20Sopenharmony_ci	return table[opcode];
828c2ecf20Sopenharmony_ci}
838c2ecf20Sopenharmony_ci
84