1#!/usr/bin/env python3
2
3##
4##  Copyright(c) 2019-2023 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_semantics_file(sys.argv[1])
106    hex_common.read_attribs_file(sys.argv[2])
107    hex_common.read_overrides_file(sys.argv[3])
108    hex_common.read_overrides_file(sys.argv[4])
109    ## Whether or not idef-parser is enabled is
110    ## determined by the number of arguments to
111    ## this script:
112    ##
113    ##   5 args. -> not enabled,
114    ##   6 args. -> idef-parser enabled.
115    ##
116    ## The 6:th arg. then holds a list of the successfully
117    ## parsed instructions.
118    is_idef_parser_enabled = len(sys.argv) > 6
119    if is_idef_parser_enabled:
120        hex_common.read_idef_parser_enabled_file(sys.argv[5])
121    hex_common.calculate_attribs()
122    hex_common.init_registers()
123    tagregs = hex_common.get_tagregs()
124    tagimms = hex_common.get_tagimms()
125
126    output_file = sys.argv[-1]
127    with open(output_file, "w") as f:
128        for tag in hex_common.tags:
129            ## Skip the priv instructions
130            if "A_PRIV" in hex_common.attribdict[tag]:
131                continue
132            ## Skip the guest instructions
133            if "A_GUEST" in hex_common.attribdict[tag]:
134                continue
135            ## Skip the diag instructions
136            if tag == "Y6_diag":
137                continue
138            if tag == "Y6_diag0":
139                continue
140            if tag == "Y6_diag1":
141                continue
142            if hex_common.skip_qemu_helper(tag):
143                continue
144            if hex_common.is_idef_parser_enabled(tag):
145                continue
146
147            gen_helper_function(f, tag, tagregs, tagimms)
148
149
150if __name__ == "__main__":
151    main()
152