1793958c9STaylor Simpson#!/usr/bin/env python3 2793958c9STaylor Simpson 3793958c9STaylor Simpson## 4e28b77a6STaylor Simpson## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved. 5793958c9STaylor Simpson## 6793958c9STaylor Simpson## This program is free software; you can redistribute it and/or modify 7793958c9STaylor Simpson## it under the terms of the GNU General Public License as published by 8793958c9STaylor Simpson## the Free Software Foundation; either version 2 of the License, or 9793958c9STaylor Simpson## (at your option) any later version. 10793958c9STaylor Simpson## 11793958c9STaylor Simpson## This program is distributed in the hope that it will be useful, 12793958c9STaylor Simpson## but WITHOUT ANY WARRANTY; without even the implied warranty of 13793958c9STaylor Simpson## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14793958c9STaylor Simpson## GNU General Public License for more details. 15793958c9STaylor Simpson## 16793958c9STaylor Simpson## You should have received a copy of the GNU General Public License 17793958c9STaylor Simpson## along with this program; if not, see <http://www.gnu.org/licenses/>. 18793958c9STaylor Simpson## 19793958c9STaylor Simpson 20793958c9STaylor Simpsonimport sys 21793958c9STaylor Simpsonimport re 22793958c9STaylor Simpsonimport string 23793958c9STaylor Simpsonimport hex_common 24793958c9STaylor Simpson 25793958c9STaylor Simpson## 26793958c9STaylor Simpson## Helpers for gen_helper_prototype 27793958c9STaylor Simpson## 28793958c9STaylor Simpsondef_helper_types = { 295bb322e2SMarco Liebel "N": "s32", 305bb322e2SMarco Liebel "O": "s32", 315bb322e2SMarco Liebel "P": "s32", 325bb322e2SMarco Liebel "M": "s32", 335bb322e2SMarco Liebel "C": "s32", 345bb322e2SMarco Liebel "R": "s32", 355bb322e2SMarco Liebel "V": "ptr", 365bb322e2SMarco Liebel "Q": "ptr", 37793958c9STaylor Simpson} 38793958c9STaylor Simpson 39793958c9STaylor Simpsondef_helper_types_pair = { 405bb322e2SMarco Liebel "R": "s64", 415bb322e2SMarco Liebel "C": "s64", 425bb322e2SMarco Liebel "S": "s64", 435bb322e2SMarco Liebel "G": "s64", 445bb322e2SMarco Liebel "V": "ptr", 455bb322e2SMarco Liebel "Q": "ptr", 46793958c9STaylor Simpson} 47793958c9STaylor Simpson 485bb322e2SMarco Liebel 49793958c9STaylor Simpsondef gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i): 505bb322e2SMarco Liebel if hex_common.is_pair(regid): 51cd6c4edfSMarco Liebel f.write(f", {def_helper_types_pair[regtype]}") 525bb322e2SMarco Liebel elif hex_common.is_single(regid): 53cd6c4edfSMarco Liebel f.write(f", {def_helper_types[regtype]}") 54793958c9STaylor Simpson else: 55793958c9STaylor Simpson print("Bad register parse: ", regtype, regid, toss, numregs) 56793958c9STaylor Simpson 575bb322e2SMarco Liebel 58793958c9STaylor Simpson## 59793958c9STaylor Simpson## Generate the DEF_HELPER prototype for an instruction 60793958c9STaylor Simpson## For A2_add: Rd32=add(Rs32,Rt32) 61793958c9STaylor Simpson## We produce: 62793958c9STaylor Simpson## DEF_HELPER_3(A2_add, s32, env, s32, s32) 63793958c9STaylor Simpson## 64793958c9STaylor Simpsondef gen_helper_prototype(f, tag, tagregs, tagimms): 65793958c9STaylor Simpson regs = tagregs[tag] 66793958c9STaylor Simpson imms = tagimms[tag] 67793958c9STaylor Simpson 68793958c9STaylor Simpson numresults = 0 69793958c9STaylor Simpson numscalarresults = 0 70793958c9STaylor Simpson numscalarreadwrite = 0 71793958c9STaylor Simpson for regtype, regid, toss, numregs in regs: 725bb322e2SMarco Liebel if hex_common.is_written(regid): 73793958c9STaylor Simpson numresults += 1 745bb322e2SMarco Liebel if hex_common.is_scalar_reg(regtype): 75793958c9STaylor Simpson numscalarresults += 1 765bb322e2SMarco Liebel if hex_common.is_readwrite(regid): 775bb322e2SMarco Liebel if hex_common.is_scalar_reg(regtype): 78793958c9STaylor Simpson numscalarreadwrite += 1 79793958c9STaylor Simpson 805bb322e2SMarco Liebel if numscalarresults > 1: 81793958c9STaylor Simpson ## The helper is bogus when there is more than one result 825bb322e2SMarco Liebel f.write(f"DEF_HELPER_1({tag}, void, env)\n") 83793958c9STaylor Simpson else: 84793958c9STaylor Simpson ## Figure out how many arguments the helper will take 855bb322e2SMarco Liebel if numscalarresults == 0: 86793958c9STaylor Simpson def_helper_size = len(regs) + len(imms) + numscalarreadwrite + 1 875bb322e2SMarco Liebel if hex_common.need_pkt_has_multi_cof(tag): 885bb322e2SMarco Liebel def_helper_size += 1 895bb322e2SMarco Liebel if hex_common.need_part1(tag): 905bb322e2SMarco Liebel def_helper_size += 1 915bb322e2SMarco Liebel if hex_common.need_slot(tag): 925bb322e2SMarco Liebel def_helper_size += 1 935bb322e2SMarco Liebel if hex_common.need_PC(tag): 945bb322e2SMarco Liebel def_helper_size += 1 955bb322e2SMarco Liebel if hex_common.helper_needs_next_PC(tag): 965bb322e2SMarco Liebel def_helper_size += 1 975bb322e2SMarco Liebel if hex_common.need_condexec_reg(tag, regs): 985bb322e2SMarco Liebel def_helper_size += 1 995bb322e2SMarco Liebel f.write(f"DEF_HELPER_{def_helper_size}({tag}") 100793958c9STaylor Simpson ## The return type is void 1015bb322e2SMarco Liebel f.write(", void") 102793958c9STaylor Simpson else: 103793958c9STaylor Simpson def_helper_size = len(regs) + len(imms) + numscalarreadwrite 1045bb322e2SMarco Liebel if hex_common.need_pkt_has_multi_cof(tag): 1055bb322e2SMarco Liebel def_helper_size += 1 1065bb322e2SMarco Liebel if hex_common.need_part1(tag): 1075bb322e2SMarco Liebel def_helper_size += 1 1085bb322e2SMarco Liebel if hex_common.need_slot(tag): 1095bb322e2SMarco Liebel def_helper_size += 1 1105bb322e2SMarco Liebel if hex_common.need_PC(tag): 1115bb322e2SMarco Liebel def_helper_size += 1 1125bb322e2SMarco Liebel if hex_common.need_condexec_reg(tag, regs): 1135bb322e2SMarco Liebel def_helper_size += 1 1145bb322e2SMarco Liebel if hex_common.helper_needs_next_PC(tag): 1155bb322e2SMarco Liebel def_helper_size += 1 1165bb322e2SMarco Liebel f.write(f"DEF_HELPER_{def_helper_size}({tag}") 117793958c9STaylor Simpson 118793958c9STaylor Simpson ## Generate the qemu DEF_HELPER type for each result 119ccd9eec8STaylor Simpson ## Iterate over this list twice 120ccd9eec8STaylor Simpson ## - Emit the scalar result 121ccd9eec8STaylor Simpson ## - Emit the vector result 122793958c9STaylor Simpson i = 0 123793958c9STaylor Simpson for regtype, regid, toss, numregs in regs: 1245bb322e2SMarco Liebel if hex_common.is_written(regid): 1255bb322e2SMarco Liebel if not hex_common.is_hvx_reg(regtype): 126793958c9STaylor Simpson gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i) 127793958c9STaylor Simpson i += 1 128793958c9STaylor Simpson 129793958c9STaylor Simpson ## Put the env between the outputs and inputs 1305bb322e2SMarco Liebel f.write(", env") 131793958c9STaylor Simpson i += 1 132793958c9STaylor Simpson 133ccd9eec8STaylor Simpson # Second pass 134ccd9eec8STaylor Simpson for regtype, regid, toss, numregs in regs: 1355bb322e2SMarco Liebel if hex_common.is_written(regid): 1365bb322e2SMarco Liebel if hex_common.is_hvx_reg(regtype): 137ccd9eec8STaylor Simpson gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i) 138ccd9eec8STaylor Simpson i += 1 139ccd9eec8STaylor Simpson 140e28b77a6STaylor Simpson ## For conditional instructions, we pass in the destination register 1415bb322e2SMarco Liebel if "A_CONDEXEC" in hex_common.attribdict[tag]: 142e28b77a6STaylor Simpson for regtype, regid, toss, numregs in regs: 1435bb322e2SMarco Liebel if hex_common.is_writeonly(regid) and not hex_common.is_hvx_reg( 1445bb322e2SMarco Liebel regtype 1455bb322e2SMarco Liebel ): 146e28b77a6STaylor Simpson gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i) 147e28b77a6STaylor Simpson i += 1 148e28b77a6STaylor Simpson 149793958c9STaylor Simpson ## Generate the qemu type for each input operand (regs and immediates) 150793958c9STaylor Simpson for regtype, regid, toss, numregs in regs: 1515bb322e2SMarco Liebel if hex_common.is_read(regid): 1525bb322e2SMarco Liebel if hex_common.is_hvx_reg(regtype) and hex_common.is_readwrite(regid): 153ccd9eec8STaylor Simpson continue 154793958c9STaylor Simpson gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i) 155793958c9STaylor Simpson i += 1 156793958c9STaylor Simpson for immlett, bits, immshift in imms: 157793958c9STaylor Simpson f.write(", s32") 158793958c9STaylor Simpson 159fb67c2bfSTaylor Simpson ## Add the arguments for the instruction pkt_has_multi_cof, slot and 160fb67c2bfSTaylor Simpson ## part1 (if needed) 1615bb322e2SMarco Liebel if hex_common.need_pkt_has_multi_cof(tag): 1625bb322e2SMarco Liebel f.write(", i32") 1635bb322e2SMarco Liebel if hex_common.need_PC(tag): 1645bb322e2SMarco Liebel f.write(", i32") 1655bb322e2SMarco Liebel if hex_common.helper_needs_next_PC(tag): 1665bb322e2SMarco Liebel f.write(", i32") 1675bb322e2SMarco Liebel if hex_common.need_slot(tag): 1685bb322e2SMarco Liebel f.write(", i32") 1695bb322e2SMarco Liebel if hex_common.need_part1(tag): 1705bb322e2SMarco Liebel f.write(" , i32") 1715bb322e2SMarco Liebel f.write(")\n") 1725bb322e2SMarco Liebel 173793958c9STaylor Simpson 174793958c9STaylor Simpsondef main(): 175793958c9STaylor Simpson hex_common.read_semantics_file(sys.argv[1]) 176793958c9STaylor Simpson hex_common.read_attribs_file(sys.argv[2]) 177793958c9STaylor Simpson hex_common.read_overrides_file(sys.argv[3]) 178d51bcabeSTaylor Simpson hex_common.read_overrides_file(sys.argv[4]) 179e71fdc4fSAlessandro Di Federico ## Whether or not idef-parser is enabled is 180e71fdc4fSAlessandro Di Federico ## determined by the number of arguments to 181e71fdc4fSAlessandro Di Federico ## this script: 182e71fdc4fSAlessandro Di Federico ## 183e71fdc4fSAlessandro Di Federico ## 5 args. -> not enabled, 184e71fdc4fSAlessandro Di Federico ## 6 args. -> idef-parser enabled. 185e71fdc4fSAlessandro Di Federico ## 186e71fdc4fSAlessandro Di Federico ## The 6:th arg. then holds a list of the successfully 187e71fdc4fSAlessandro Di Federico ## parsed instructions. 188e71fdc4fSAlessandro Di Federico is_idef_parser_enabled = len(sys.argv) > 6 189e71fdc4fSAlessandro Di Federico if is_idef_parser_enabled: 190e71fdc4fSAlessandro Di Federico hex_common.read_idef_parser_enabled_file(sys.argv[5]) 191793958c9STaylor Simpson hex_common.calculate_attribs() 192793958c9STaylor Simpson tagregs = hex_common.get_tagregs() 193793958c9STaylor Simpson tagimms = hex_common.get_tagimms() 194793958c9STaylor Simpson 195e71fdc4fSAlessandro Di Federico output_file = sys.argv[-1] 1965bb322e2SMarco Liebel with open(output_file, "w") as f: 197793958c9STaylor Simpson for tag in hex_common.tags: 198793958c9STaylor Simpson ## Skip the priv instructions 1995bb322e2SMarco Liebel if "A_PRIV" in hex_common.attribdict[tag]: 200793958c9STaylor Simpson continue 201793958c9STaylor Simpson ## Skip the guest instructions 2025bb322e2SMarco Liebel if "A_GUEST" in hex_common.attribdict[tag]: 203793958c9STaylor Simpson continue 204793958c9STaylor Simpson ## Skip the diag instructions 2055bb322e2SMarco Liebel if tag == "Y6_diag": 206793958c9STaylor Simpson continue 2075bb322e2SMarco Liebel if tag == "Y6_diag0": 208793958c9STaylor Simpson continue 2095bb322e2SMarco Liebel if tag == "Y6_diag1": 210793958c9STaylor Simpson continue 211793958c9STaylor Simpson 2125bb322e2SMarco Liebel if hex_common.skip_qemu_helper(tag): 213793958c9STaylor Simpson continue 2145bb322e2SMarco Liebel if hex_common.is_idef_parser_enabled(tag): 215e71fdc4fSAlessandro Di Federico continue 216793958c9STaylor Simpson 217793958c9STaylor Simpson gen_helper_prototype(f, tag, tagregs, tagimms) 218793958c9STaylor Simpson 2195bb322e2SMarco Liebel 220793958c9STaylor Simpsonif __name__ == "__main__": 221793958c9STaylor Simpson main() 222