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