1#!/usr/bin/env python3
2
3##
4##  Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
5##
6##  This program is free software; you can redistribute it and/or modify
7##  it under the terms of the GNU General Public License as published by
8##  the Free Software Foundation; either version 2 of the License, or
9##  (at your option) any later version.
10##
11##  This program is distributed in the hope that it will be useful,
12##  but WITHOUT ANY WARRANTY; without even the implied warranty of
13##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14##  GNU General Public License for more details.
15##
16##  You should have received a copy of the GNU General Public License
17##  along with this program; if not, see <http://www.gnu.org/licenses/>.
18##
19
20import sys
21import re
22import string
23import hex_common
24
25
26##
27## Generate the TCG code to call the helper
28##     For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
29##     We produce:
30##       int32_t HELPER(A2_add)(CPUHexagonState *env, int32_t RsV, int32_t RtV)
31##       {
32##           int32_t RdV = 0;
33##           { RdV=RsV+RtV;}
34##           return RdV;
35##       }
36##
37def gen_helper_function(f, tag, tagregs, tagimms):
38    regs = tagregs[tag]
39    imms = tagimms[tag]
40
41    ret_type = hex_common.helper_ret_type(tag, regs).func_arg
42
43    declared = []
44    for arg in hex_common.helper_args(tag, regs, imms):
45        declared.append(arg.func_arg)
46
47    arguments = ", ".join(declared)
48    f.write(f"{ret_type} HELPER({tag})({arguments})\n")
49    f.write("{\n")
50    if hex_common.need_ea(tag):
51        f.write(hex_common.code_fmt(f"""\
52            uint32_t EA;
53        """))
54    ## Declare the return variable
55    if not hex_common.is_predicated(tag):
56        for regtype, regid in regs:
57            reg = hex_common.get_register(tag, regtype, regid)
58            if reg.is_writeonly() and not reg.is_hvx_reg():
59                f.write(hex_common.code_fmt(f"""\
60                    {reg.helper_arg_type()} {reg.helper_arg_name()} = 0;
61                """))
62
63    ## Print useful information about HVX registers
64    for regtype, regid in regs:
65        reg = hex_common.get_register(tag, regtype, regid)
66        if reg.is_hvx_reg():
67            reg.helper_hvx_desc(f)
68
69    if hex_common.need_slot(tag):
70        if "A_LOAD" in hex_common.attribdict[tag]:
71            f.write(hex_common.code_fmt(f"""\
72                bool pkt_has_store_s1 = slotval & 0x1;
73            """))
74        f.write(hex_common.code_fmt(f"""\
75            uint32_t slot = slotval >> 1;
76        """))
77
78    if "A_FPOP" in hex_common.attribdict[tag]:
79        f.write(hex_common.code_fmt(f"""\
80            arch_fpop_start(env);
81        """))
82
83    f.write(hex_common.code_fmt(f"""\
84        {hex_common.semdict[tag]}
85    """))
86
87    if "A_FPOP" in hex_common.attribdict[tag]:
88        f.write(hex_common.code_fmt(f"""\
89            arch_fpop_end(env);
90        """))
91
92    ## Return the scalar result
93    for regtype, regid in regs:
94        reg = hex_common.get_register(tag, regtype, regid)
95        if reg.is_written() and not reg.is_hvx_reg():
96            f.write(hex_common.code_fmt(f"""\
97                return {reg.helper_arg_name()};
98            """))
99
100    f.write("}\n\n")
101    ## End of the helper definition
102
103
104def main():
105    hex_common.read_common_files()
106    tagregs = hex_common.get_tagregs()
107    tagimms = hex_common.get_tagimms()
108
109    output_file = sys.argv[-1]
110    with open(output_file, "w") as f:
111        for tag in hex_common.tags:
112            ## Skip the priv instructions
113            if "A_PRIV" in hex_common.attribdict[tag]:
114                continue
115            ## Skip the guest instructions
116            if "A_GUEST" in hex_common.attribdict[tag]:
117                continue
118            ## Skip the diag instructions
119            if tag == "Y6_diag":
120                continue
121            if tag == "Y6_diag0":
122                continue
123            if tag == "Y6_diag1":
124                continue
125            if hex_common.skip_qemu_helper(tag):
126                continue
127            if hex_common.is_idef_parser_enabled(tag):
128                continue
129
130            gen_helper_function(f, tag, tagregs, tagimms)
131
132
133if __name__ == "__main__":
134    main()
135