18c2ecf20Sopenharmony_ci#!/bin/awk -f 28c2ecf20Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 38c2ecf20Sopenharmony_ci# gen-insn-attr-x86.awk: Instruction attribute table generator 48c2ecf20Sopenharmony_ci# Written by Masami Hiramatsu <mhiramat@redhat.com> 58c2ecf20Sopenharmony_ci# 68c2ecf20Sopenharmony_ci# Usage: awk -f gen-insn-attr-x86.awk x86-opcode-map.txt > inat-tables.c 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci# Awk implementation sanity check 98c2ecf20Sopenharmony_cifunction check_awk_implement() { 108c2ecf20Sopenharmony_ci if (sprintf("%x", 0) != "0") 118c2ecf20Sopenharmony_ci return "Your awk has a printf-format problem." 128c2ecf20Sopenharmony_ci return "" 138c2ecf20Sopenharmony_ci} 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci# Clear working vars 168c2ecf20Sopenharmony_cifunction clear_vars() { 178c2ecf20Sopenharmony_ci delete table 188c2ecf20Sopenharmony_ci delete lptable2 198c2ecf20Sopenharmony_ci delete lptable1 208c2ecf20Sopenharmony_ci delete lptable3 218c2ecf20Sopenharmony_ci eid = -1 # escape id 228c2ecf20Sopenharmony_ci gid = -1 # group id 238c2ecf20Sopenharmony_ci aid = -1 # AVX id 248c2ecf20Sopenharmony_ci tname = "" 258c2ecf20Sopenharmony_ci} 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ciBEGIN { 288c2ecf20Sopenharmony_ci # Implementation error checking 298c2ecf20Sopenharmony_ci awkchecked = check_awk_implement() 308c2ecf20Sopenharmony_ci if (awkchecked != "") { 318c2ecf20Sopenharmony_ci print "Error: " awkchecked > "/dev/stderr" 328c2ecf20Sopenharmony_ci print "Please try to use gawk." > "/dev/stderr" 338c2ecf20Sopenharmony_ci exit 1 348c2ecf20Sopenharmony_ci } 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci # Setup generating tables 378c2ecf20Sopenharmony_ci print "/* x86 opcode map generated from x86-opcode-map.txt */" 388c2ecf20Sopenharmony_ci print "/* Do not change this code. */\n" 398c2ecf20Sopenharmony_ci ggid = 1 408c2ecf20Sopenharmony_ci geid = 1 418c2ecf20Sopenharmony_ci gaid = 0 428c2ecf20Sopenharmony_ci delete etable 438c2ecf20Sopenharmony_ci delete gtable 448c2ecf20Sopenharmony_ci delete atable 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci opnd_expr = "^[A-Za-z/]" 478c2ecf20Sopenharmony_ci ext_expr = "^\\(" 488c2ecf20Sopenharmony_ci sep_expr = "^\\|$" 498c2ecf20Sopenharmony_ci group_expr = "^Grp[0-9A-Za-z]+" 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci imm_expr = "^[IJAOL][a-z]" 528c2ecf20Sopenharmony_ci imm_flag["Ib"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" 538c2ecf20Sopenharmony_ci imm_flag["Jb"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" 548c2ecf20Sopenharmony_ci imm_flag["Iw"] = "INAT_MAKE_IMM(INAT_IMM_WORD)" 558c2ecf20Sopenharmony_ci imm_flag["Id"] = "INAT_MAKE_IMM(INAT_IMM_DWORD)" 568c2ecf20Sopenharmony_ci imm_flag["Iq"] = "INAT_MAKE_IMM(INAT_IMM_QWORD)" 578c2ecf20Sopenharmony_ci imm_flag["Ap"] = "INAT_MAKE_IMM(INAT_IMM_PTR)" 588c2ecf20Sopenharmony_ci imm_flag["Iz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)" 598c2ecf20Sopenharmony_ci imm_flag["Jz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)" 608c2ecf20Sopenharmony_ci imm_flag["Iv"] = "INAT_MAKE_IMM(INAT_IMM_VWORD)" 618c2ecf20Sopenharmony_ci imm_flag["Ob"] = "INAT_MOFFSET" 628c2ecf20Sopenharmony_ci imm_flag["Ov"] = "INAT_MOFFSET" 638c2ecf20Sopenharmony_ci imm_flag["Lx"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])" 668c2ecf20Sopenharmony_ci force64_expr = "\\([df]64\\)" 678c2ecf20Sopenharmony_ci rex_expr = "^REX(\\.[XRWB]+)*" 688c2ecf20Sopenharmony_ci fpu_expr = "^ESC" # TODO 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci lprefix1_expr = "\\((66|!F3)\\)" 718c2ecf20Sopenharmony_ci lprefix2_expr = "\\(F3\\)" 728c2ecf20Sopenharmony_ci lprefix3_expr = "\\((F2|!F3|66&F2)\\)" 738c2ecf20Sopenharmony_ci lprefix_expr = "\\((66|F2|F3)\\)" 748c2ecf20Sopenharmony_ci max_lprefix = 4 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci # All opcodes starting with lower-case 'v', 'k' or with (v1) superscript 778c2ecf20Sopenharmony_ci # accepts VEX prefix 788c2ecf20Sopenharmony_ci vexok_opcode_expr = "^[vk].*" 798c2ecf20Sopenharmony_ci vexok_expr = "\\(v1\\)" 808c2ecf20Sopenharmony_ci # All opcodes with (v) superscript supports *only* VEX prefix 818c2ecf20Sopenharmony_ci vexonly_expr = "\\(v\\)" 828c2ecf20Sopenharmony_ci # All opcodes with (ev) superscript supports *only* EVEX prefix 838c2ecf20Sopenharmony_ci evexonly_expr = "\\(ev\\)" 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci prefix_expr = "\\(Prefix\\)" 868c2ecf20Sopenharmony_ci prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ" 878c2ecf20Sopenharmony_ci prefix_num["REPNE"] = "INAT_PFX_REPNE" 888c2ecf20Sopenharmony_ci prefix_num["REP/REPE"] = "INAT_PFX_REPE" 898c2ecf20Sopenharmony_ci prefix_num["XACQUIRE"] = "INAT_PFX_REPNE" 908c2ecf20Sopenharmony_ci prefix_num["XRELEASE"] = "INAT_PFX_REPE" 918c2ecf20Sopenharmony_ci prefix_num["LOCK"] = "INAT_PFX_LOCK" 928c2ecf20Sopenharmony_ci prefix_num["SEG=CS"] = "INAT_PFX_CS" 938c2ecf20Sopenharmony_ci prefix_num["SEG=DS"] = "INAT_PFX_DS" 948c2ecf20Sopenharmony_ci prefix_num["SEG=ES"] = "INAT_PFX_ES" 958c2ecf20Sopenharmony_ci prefix_num["SEG=FS"] = "INAT_PFX_FS" 968c2ecf20Sopenharmony_ci prefix_num["SEG=GS"] = "INAT_PFX_GS" 978c2ecf20Sopenharmony_ci prefix_num["SEG=SS"] = "INAT_PFX_SS" 988c2ecf20Sopenharmony_ci prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ" 998c2ecf20Sopenharmony_ci prefix_num["VEX+1byte"] = "INAT_PFX_VEX2" 1008c2ecf20Sopenharmony_ci prefix_num["VEX+2byte"] = "INAT_PFX_VEX3" 1018c2ecf20Sopenharmony_ci prefix_num["EVEX"] = "INAT_PFX_EVEX" 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci clear_vars() 1048c2ecf20Sopenharmony_ci} 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_cifunction semantic_error(msg) { 1078c2ecf20Sopenharmony_ci print "Semantic error at " NR ": " msg > "/dev/stderr" 1088c2ecf20Sopenharmony_ci exit 1 1098c2ecf20Sopenharmony_ci} 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_cifunction debug(msg) { 1128c2ecf20Sopenharmony_ci print "DEBUG: " msg 1138c2ecf20Sopenharmony_ci} 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_cifunction array_size(arr, i,c) { 1168c2ecf20Sopenharmony_ci c = 0 1178c2ecf20Sopenharmony_ci for (i in arr) 1188c2ecf20Sopenharmony_ci c++ 1198c2ecf20Sopenharmony_ci return c 1208c2ecf20Sopenharmony_ci} 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci/^Table:/ { 1238c2ecf20Sopenharmony_ci print "/* " $0 " */" 1248c2ecf20Sopenharmony_ci if (tname != "") 1258c2ecf20Sopenharmony_ci semantic_error("Hit Table: before EndTable:."); 1268c2ecf20Sopenharmony_ci} 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci/^Referrer:/ { 1298c2ecf20Sopenharmony_ci if (NF != 1) { 1308c2ecf20Sopenharmony_ci # escape opcode table 1318c2ecf20Sopenharmony_ci ref = "" 1328c2ecf20Sopenharmony_ci for (i = 2; i <= NF; i++) 1338c2ecf20Sopenharmony_ci ref = ref $i 1348c2ecf20Sopenharmony_ci eid = escape[ref] 1358c2ecf20Sopenharmony_ci tname = sprintf("inat_escape_table_%d", eid) 1368c2ecf20Sopenharmony_ci } 1378c2ecf20Sopenharmony_ci} 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci/^AVXcode:/ { 1408c2ecf20Sopenharmony_ci if (NF != 1) { 1418c2ecf20Sopenharmony_ci # AVX/escape opcode table 1428c2ecf20Sopenharmony_ci aid = $2 1438c2ecf20Sopenharmony_ci if (gaid <= aid) 1448c2ecf20Sopenharmony_ci gaid = aid + 1 1458c2ecf20Sopenharmony_ci if (tname == "") # AVX only opcode table 1468c2ecf20Sopenharmony_ci tname = sprintf("inat_avx_table_%d", $2) 1478c2ecf20Sopenharmony_ci } 1488c2ecf20Sopenharmony_ci if (aid == -1 && eid == -1) # primary opcode table 1498c2ecf20Sopenharmony_ci tname = "inat_primary_table" 1508c2ecf20Sopenharmony_ci} 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci/^GrpTable:/ { 1538c2ecf20Sopenharmony_ci print "/* " $0 " */" 1548c2ecf20Sopenharmony_ci if (!($2 in group)) 1558c2ecf20Sopenharmony_ci semantic_error("No group: " $2 ) 1568c2ecf20Sopenharmony_ci gid = group[$2] 1578c2ecf20Sopenharmony_ci tname = "inat_group_table_" gid 1588c2ecf20Sopenharmony_ci} 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_cifunction print_table(tbl,name,fmt,n) 1618c2ecf20Sopenharmony_ci{ 1628c2ecf20Sopenharmony_ci print "const insn_attr_t " name " = {" 1638c2ecf20Sopenharmony_ci for (i = 0; i < n; i++) { 1648c2ecf20Sopenharmony_ci id = sprintf(fmt, i) 1658c2ecf20Sopenharmony_ci if (tbl[id]) 1668c2ecf20Sopenharmony_ci print " [" id "] = " tbl[id] "," 1678c2ecf20Sopenharmony_ci } 1688c2ecf20Sopenharmony_ci print "};" 1698c2ecf20Sopenharmony_ci} 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci/^EndTable/ { 1728c2ecf20Sopenharmony_ci if (gid != -1) { 1738c2ecf20Sopenharmony_ci # print group tables 1748c2ecf20Sopenharmony_ci if (array_size(table) != 0) { 1758c2ecf20Sopenharmony_ci print_table(table, tname "[INAT_GROUP_TABLE_SIZE]", 1768c2ecf20Sopenharmony_ci "0x%x", 8) 1778c2ecf20Sopenharmony_ci gtable[gid,0] = tname 1788c2ecf20Sopenharmony_ci } 1798c2ecf20Sopenharmony_ci if (array_size(lptable1) != 0) { 1808c2ecf20Sopenharmony_ci print_table(lptable1, tname "_1[INAT_GROUP_TABLE_SIZE]", 1818c2ecf20Sopenharmony_ci "0x%x", 8) 1828c2ecf20Sopenharmony_ci gtable[gid,1] = tname "_1" 1838c2ecf20Sopenharmony_ci } 1848c2ecf20Sopenharmony_ci if (array_size(lptable2) != 0) { 1858c2ecf20Sopenharmony_ci print_table(lptable2, tname "_2[INAT_GROUP_TABLE_SIZE]", 1868c2ecf20Sopenharmony_ci "0x%x", 8) 1878c2ecf20Sopenharmony_ci gtable[gid,2] = tname "_2" 1888c2ecf20Sopenharmony_ci } 1898c2ecf20Sopenharmony_ci if (array_size(lptable3) != 0) { 1908c2ecf20Sopenharmony_ci print_table(lptable3, tname "_3[INAT_GROUP_TABLE_SIZE]", 1918c2ecf20Sopenharmony_ci "0x%x", 8) 1928c2ecf20Sopenharmony_ci gtable[gid,3] = tname "_3" 1938c2ecf20Sopenharmony_ci } 1948c2ecf20Sopenharmony_ci } else { 1958c2ecf20Sopenharmony_ci # print primary/escaped tables 1968c2ecf20Sopenharmony_ci if (array_size(table) != 0) { 1978c2ecf20Sopenharmony_ci print_table(table, tname "[INAT_OPCODE_TABLE_SIZE]", 1988c2ecf20Sopenharmony_ci "0x%02x", 256) 1998c2ecf20Sopenharmony_ci etable[eid,0] = tname 2008c2ecf20Sopenharmony_ci if (aid >= 0) 2018c2ecf20Sopenharmony_ci atable[aid,0] = tname 2028c2ecf20Sopenharmony_ci } 2038c2ecf20Sopenharmony_ci if (array_size(lptable1) != 0) { 2048c2ecf20Sopenharmony_ci print_table(lptable1,tname "_1[INAT_OPCODE_TABLE_SIZE]", 2058c2ecf20Sopenharmony_ci "0x%02x", 256) 2068c2ecf20Sopenharmony_ci etable[eid,1] = tname "_1" 2078c2ecf20Sopenharmony_ci if (aid >= 0) 2088c2ecf20Sopenharmony_ci atable[aid,1] = tname "_1" 2098c2ecf20Sopenharmony_ci } 2108c2ecf20Sopenharmony_ci if (array_size(lptable2) != 0) { 2118c2ecf20Sopenharmony_ci print_table(lptable2,tname "_2[INAT_OPCODE_TABLE_SIZE]", 2128c2ecf20Sopenharmony_ci "0x%02x", 256) 2138c2ecf20Sopenharmony_ci etable[eid,2] = tname "_2" 2148c2ecf20Sopenharmony_ci if (aid >= 0) 2158c2ecf20Sopenharmony_ci atable[aid,2] = tname "_2" 2168c2ecf20Sopenharmony_ci } 2178c2ecf20Sopenharmony_ci if (array_size(lptable3) != 0) { 2188c2ecf20Sopenharmony_ci print_table(lptable3,tname "_3[INAT_OPCODE_TABLE_SIZE]", 2198c2ecf20Sopenharmony_ci "0x%02x", 256) 2208c2ecf20Sopenharmony_ci etable[eid,3] = tname "_3" 2218c2ecf20Sopenharmony_ci if (aid >= 0) 2228c2ecf20Sopenharmony_ci atable[aid,3] = tname "_3" 2238c2ecf20Sopenharmony_ci } 2248c2ecf20Sopenharmony_ci } 2258c2ecf20Sopenharmony_ci print "" 2268c2ecf20Sopenharmony_ci clear_vars() 2278c2ecf20Sopenharmony_ci} 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_cifunction add_flags(old,new) { 2308c2ecf20Sopenharmony_ci if (old && new) 2318c2ecf20Sopenharmony_ci return old " | " new 2328c2ecf20Sopenharmony_ci else if (old) 2338c2ecf20Sopenharmony_ci return old 2348c2ecf20Sopenharmony_ci else 2358c2ecf20Sopenharmony_ci return new 2368c2ecf20Sopenharmony_ci} 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci# convert operands to flags. 2398c2ecf20Sopenharmony_cifunction convert_operands(count,opnd, i,j,imm,mod) 2408c2ecf20Sopenharmony_ci{ 2418c2ecf20Sopenharmony_ci imm = null 2428c2ecf20Sopenharmony_ci mod = null 2438c2ecf20Sopenharmony_ci for (j = 1; j <= count; j++) { 2448c2ecf20Sopenharmony_ci i = opnd[j] 2458c2ecf20Sopenharmony_ci if (match(i, imm_expr) == 1) { 2468c2ecf20Sopenharmony_ci if (!imm_flag[i]) 2478c2ecf20Sopenharmony_ci semantic_error("Unknown imm opnd: " i) 2488c2ecf20Sopenharmony_ci if (imm) { 2498c2ecf20Sopenharmony_ci if (i != "Ib") 2508c2ecf20Sopenharmony_ci semantic_error("Second IMM error") 2518c2ecf20Sopenharmony_ci imm = add_flags(imm, "INAT_SCNDIMM") 2528c2ecf20Sopenharmony_ci } else 2538c2ecf20Sopenharmony_ci imm = imm_flag[i] 2548c2ecf20Sopenharmony_ci } else if (match(i, modrm_expr)) 2558c2ecf20Sopenharmony_ci mod = "INAT_MODRM" 2568c2ecf20Sopenharmony_ci } 2578c2ecf20Sopenharmony_ci return add_flags(imm, mod) 2588c2ecf20Sopenharmony_ci} 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci/^[0-9a-f]+:/ { 2618c2ecf20Sopenharmony_ci if (NR == 1) 2628c2ecf20Sopenharmony_ci next 2638c2ecf20Sopenharmony_ci # get index 2648c2ecf20Sopenharmony_ci idx = "0x" substr($1, 1, index($1,":") - 1) 2658c2ecf20Sopenharmony_ci if (idx in table) 2668c2ecf20Sopenharmony_ci semantic_error("Redefine " idx " in " tname) 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci # check if escaped opcode 2698c2ecf20Sopenharmony_ci if ("escape" == $2) { 2708c2ecf20Sopenharmony_ci if ($3 != "#") 2718c2ecf20Sopenharmony_ci semantic_error("No escaped name") 2728c2ecf20Sopenharmony_ci ref = "" 2738c2ecf20Sopenharmony_ci for (i = 4; i <= NF; i++) 2748c2ecf20Sopenharmony_ci ref = ref $i 2758c2ecf20Sopenharmony_ci if (ref in escape) 2768c2ecf20Sopenharmony_ci semantic_error("Redefine escape (" ref ")") 2778c2ecf20Sopenharmony_ci escape[ref] = geid 2788c2ecf20Sopenharmony_ci geid++ 2798c2ecf20Sopenharmony_ci table[idx] = "INAT_MAKE_ESCAPE(" escape[ref] ")" 2808c2ecf20Sopenharmony_ci next 2818c2ecf20Sopenharmony_ci } 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci variant = null 2848c2ecf20Sopenharmony_ci # converts 2858c2ecf20Sopenharmony_ci i = 2 2868c2ecf20Sopenharmony_ci while (i <= NF) { 2878c2ecf20Sopenharmony_ci opcode = $(i++) 2888c2ecf20Sopenharmony_ci delete opnds 2898c2ecf20Sopenharmony_ci ext = null 2908c2ecf20Sopenharmony_ci flags = null 2918c2ecf20Sopenharmony_ci opnd = null 2928c2ecf20Sopenharmony_ci # parse one opcode 2938c2ecf20Sopenharmony_ci if (match($i, opnd_expr)) { 2948c2ecf20Sopenharmony_ci opnd = $i 2958c2ecf20Sopenharmony_ci count = split($(i++), opnds, ",") 2968c2ecf20Sopenharmony_ci flags = convert_operands(count, opnds) 2978c2ecf20Sopenharmony_ci } 2988c2ecf20Sopenharmony_ci if (match($i, ext_expr)) 2998c2ecf20Sopenharmony_ci ext = $(i++) 3008c2ecf20Sopenharmony_ci if (match($i, sep_expr)) 3018c2ecf20Sopenharmony_ci i++ 3028c2ecf20Sopenharmony_ci else if (i < NF) 3038c2ecf20Sopenharmony_ci semantic_error($i " is not a separator") 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_ci # check if group opcode 3068c2ecf20Sopenharmony_ci if (match(opcode, group_expr)) { 3078c2ecf20Sopenharmony_ci if (!(opcode in group)) { 3088c2ecf20Sopenharmony_ci group[opcode] = ggid 3098c2ecf20Sopenharmony_ci ggid++ 3108c2ecf20Sopenharmony_ci } 3118c2ecf20Sopenharmony_ci flags = add_flags(flags, "INAT_MAKE_GROUP(" group[opcode] ")") 3128c2ecf20Sopenharmony_ci } 3138c2ecf20Sopenharmony_ci # check force(or default) 64bit 3148c2ecf20Sopenharmony_ci if (match(ext, force64_expr)) 3158c2ecf20Sopenharmony_ci flags = add_flags(flags, "INAT_FORCE64") 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci # check REX prefix 3188c2ecf20Sopenharmony_ci if (match(opcode, rex_expr)) 3198c2ecf20Sopenharmony_ci flags = add_flags(flags, "INAT_MAKE_PREFIX(INAT_PFX_REX)") 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci # check coprocessor escape : TODO 3228c2ecf20Sopenharmony_ci if (match(opcode, fpu_expr)) 3238c2ecf20Sopenharmony_ci flags = add_flags(flags, "INAT_MODRM") 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci # check VEX codes 3268c2ecf20Sopenharmony_ci if (match(ext, evexonly_expr)) 3278c2ecf20Sopenharmony_ci flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY") 3288c2ecf20Sopenharmony_ci else if (match(ext, vexonly_expr)) 3298c2ecf20Sopenharmony_ci flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY") 3308c2ecf20Sopenharmony_ci else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr)) 3318c2ecf20Sopenharmony_ci flags = add_flags(flags, "INAT_VEXOK") 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci # check prefixes 3348c2ecf20Sopenharmony_ci if (match(ext, prefix_expr)) { 3358c2ecf20Sopenharmony_ci if (!prefix_num[opcode]) 3368c2ecf20Sopenharmony_ci semantic_error("Unknown prefix: " opcode) 3378c2ecf20Sopenharmony_ci flags = add_flags(flags, "INAT_MAKE_PREFIX(" prefix_num[opcode] ")") 3388c2ecf20Sopenharmony_ci } 3398c2ecf20Sopenharmony_ci if (length(flags) == 0) 3408c2ecf20Sopenharmony_ci continue 3418c2ecf20Sopenharmony_ci # check if last prefix 3428c2ecf20Sopenharmony_ci if (match(ext, lprefix1_expr)) { 3438c2ecf20Sopenharmony_ci lptable1[idx] = add_flags(lptable1[idx],flags) 3448c2ecf20Sopenharmony_ci variant = "INAT_VARIANT" 3458c2ecf20Sopenharmony_ci } 3468c2ecf20Sopenharmony_ci if (match(ext, lprefix2_expr)) { 3478c2ecf20Sopenharmony_ci lptable2[idx] = add_flags(lptable2[idx],flags) 3488c2ecf20Sopenharmony_ci variant = "INAT_VARIANT" 3498c2ecf20Sopenharmony_ci } 3508c2ecf20Sopenharmony_ci if (match(ext, lprefix3_expr)) { 3518c2ecf20Sopenharmony_ci lptable3[idx] = add_flags(lptable3[idx],flags) 3528c2ecf20Sopenharmony_ci variant = "INAT_VARIANT" 3538c2ecf20Sopenharmony_ci } 3548c2ecf20Sopenharmony_ci if (!match(ext, lprefix_expr)){ 3558c2ecf20Sopenharmony_ci table[idx] = add_flags(table[idx],flags) 3568c2ecf20Sopenharmony_ci } 3578c2ecf20Sopenharmony_ci } 3588c2ecf20Sopenharmony_ci if (variant) 3598c2ecf20Sopenharmony_ci table[idx] = add_flags(table[idx],variant) 3608c2ecf20Sopenharmony_ci} 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ciEND { 3638c2ecf20Sopenharmony_ci if (awkchecked != "") 3648c2ecf20Sopenharmony_ci exit 1 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci print "#ifndef __BOOT_COMPRESSED\n" 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_ci # print escape opcode map's array 3698c2ecf20Sopenharmony_ci print "/* Escape opcode map array */" 3708c2ecf20Sopenharmony_ci print "const insn_attr_t * const inat_escape_tables[INAT_ESC_MAX + 1]" \ 3718c2ecf20Sopenharmony_ci "[INAT_LSTPFX_MAX + 1] = {" 3728c2ecf20Sopenharmony_ci for (i = 0; i < geid; i++) 3738c2ecf20Sopenharmony_ci for (j = 0; j < max_lprefix; j++) 3748c2ecf20Sopenharmony_ci if (etable[i,j]) 3758c2ecf20Sopenharmony_ci print " ["i"]["j"] = "etable[i,j]"," 3768c2ecf20Sopenharmony_ci print "};\n" 3778c2ecf20Sopenharmony_ci # print group opcode map's array 3788c2ecf20Sopenharmony_ci print "/* Group opcode map array */" 3798c2ecf20Sopenharmony_ci print "const insn_attr_t * const inat_group_tables[INAT_GRP_MAX + 1]"\ 3808c2ecf20Sopenharmony_ci "[INAT_LSTPFX_MAX + 1] = {" 3818c2ecf20Sopenharmony_ci for (i = 0; i < ggid; i++) 3828c2ecf20Sopenharmony_ci for (j = 0; j < max_lprefix; j++) 3838c2ecf20Sopenharmony_ci if (gtable[i,j]) 3848c2ecf20Sopenharmony_ci print " ["i"]["j"] = "gtable[i,j]"," 3858c2ecf20Sopenharmony_ci print "};\n" 3868c2ecf20Sopenharmony_ci # print AVX opcode map's array 3878c2ecf20Sopenharmony_ci print "/* AVX opcode map array */" 3888c2ecf20Sopenharmony_ci print "const insn_attr_t * const inat_avx_tables[X86_VEX_M_MAX + 1]"\ 3898c2ecf20Sopenharmony_ci "[INAT_LSTPFX_MAX + 1] = {" 3908c2ecf20Sopenharmony_ci for (i = 0; i < gaid; i++) 3918c2ecf20Sopenharmony_ci for (j = 0; j < max_lprefix; j++) 3928c2ecf20Sopenharmony_ci if (atable[i,j]) 3938c2ecf20Sopenharmony_ci print " ["i"]["j"] = "atable[i,j]"," 3948c2ecf20Sopenharmony_ci print "};\n" 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_ci print "#else /* !__BOOT_COMPRESSED */\n" 3978c2ecf20Sopenharmony_ci 3988c2ecf20Sopenharmony_ci print "/* Escape opcode map array */" 3998c2ecf20Sopenharmony_ci print "static const insn_attr_t *inat_escape_tables[INAT_ESC_MAX + 1]" \ 4008c2ecf20Sopenharmony_ci "[INAT_LSTPFX_MAX + 1];" 4018c2ecf20Sopenharmony_ci print "" 4028c2ecf20Sopenharmony_ci 4038c2ecf20Sopenharmony_ci print "/* Group opcode map array */" 4048c2ecf20Sopenharmony_ci print "static const insn_attr_t *inat_group_tables[INAT_GRP_MAX + 1]"\ 4058c2ecf20Sopenharmony_ci "[INAT_LSTPFX_MAX + 1];" 4068c2ecf20Sopenharmony_ci print "" 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_ci print "/* AVX opcode map array */" 4098c2ecf20Sopenharmony_ci print "static const insn_attr_t *inat_avx_tables[X86_VEX_M_MAX + 1]"\ 4108c2ecf20Sopenharmony_ci "[INAT_LSTPFX_MAX + 1];" 4118c2ecf20Sopenharmony_ci print "" 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_ci print "static void inat_init_tables(void)" 4148c2ecf20Sopenharmony_ci print "{" 4158c2ecf20Sopenharmony_ci 4168c2ecf20Sopenharmony_ci # print escape opcode map's array 4178c2ecf20Sopenharmony_ci print "\t/* Print Escape opcode map array */" 4188c2ecf20Sopenharmony_ci for (i = 0; i < geid; i++) 4198c2ecf20Sopenharmony_ci for (j = 0; j < max_lprefix; j++) 4208c2ecf20Sopenharmony_ci if (etable[i,j]) 4218c2ecf20Sopenharmony_ci print "\tinat_escape_tables["i"]["j"] = "etable[i,j]";" 4228c2ecf20Sopenharmony_ci print "" 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_ci # print group opcode map's array 4258c2ecf20Sopenharmony_ci print "\t/* Print Group opcode map array */" 4268c2ecf20Sopenharmony_ci for (i = 0; i < ggid; i++) 4278c2ecf20Sopenharmony_ci for (j = 0; j < max_lprefix; j++) 4288c2ecf20Sopenharmony_ci if (gtable[i,j]) 4298c2ecf20Sopenharmony_ci print "\tinat_group_tables["i"]["j"] = "gtable[i,j]";" 4308c2ecf20Sopenharmony_ci print "" 4318c2ecf20Sopenharmony_ci # print AVX opcode map's array 4328c2ecf20Sopenharmony_ci print "\t/* Print AVX opcode map array */" 4338c2ecf20Sopenharmony_ci for (i = 0; i < gaid; i++) 4348c2ecf20Sopenharmony_ci for (j = 0; j < max_lprefix; j++) 4358c2ecf20Sopenharmony_ci if (atable[i,j]) 4368c2ecf20Sopenharmony_ci print "\tinat_avx_tables["i"]["j"] = "atable[i,j]";" 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_ci print "}" 4398c2ecf20Sopenharmony_ci print "#endif" 4408c2ecf20Sopenharmony_ci} 4418c2ecf20Sopenharmony_ci 442