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