xref: /qemu/target/hexagon/gen_helper_funcs.py (revision e8f62689acd5930a712655d0c6838ec5eccc6b1c)
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 
20 import sys
21 import re
22 import string
23 import 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 ##
37 def 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 
104 def 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 
133 if __name__ == "__main__":
134     main()
135