xref: /qemu/target/hexagon/gen_helper_protos.py (revision e71fdc4f)
1793958c9STaylor Simpson#!/usr/bin/env python3
2793958c9STaylor Simpson
3793958c9STaylor Simpson##
4fb67c2bfSTaylor Simpson##  Copyright(c) 2019-2022 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 = {
29793958c9STaylor Simpson    'N' : 's32',
30793958c9STaylor Simpson    'O' : 's32',
31793958c9STaylor Simpson    'P' : 's32',
32793958c9STaylor Simpson    'M' : 's32',
33793958c9STaylor Simpson    'C' : 's32',
34793958c9STaylor Simpson    'R' : 's32',
35793958c9STaylor Simpson    'V' : 'ptr',
36793958c9STaylor Simpson    'Q' : 'ptr'
37793958c9STaylor Simpson}
38793958c9STaylor Simpson
39793958c9STaylor Simpsondef_helper_types_pair = {
40793958c9STaylor Simpson    'R' : 's64',
41793958c9STaylor Simpson    'C' : 's64',
42793958c9STaylor Simpson    'S' : 's64',
43793958c9STaylor Simpson    'G' : 's64',
44793958c9STaylor Simpson    'V' : 'ptr',
45793958c9STaylor Simpson    'Q' : 'ptr'
46793958c9STaylor Simpson}
47793958c9STaylor Simpson
48793958c9STaylor Simpsondef gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i):
49793958c9STaylor Simpson    if (hex_common.is_pair(regid)):
50793958c9STaylor Simpson        f.write(", %s" % (def_helper_types_pair[regtype]))
51793958c9STaylor Simpson    elif (hex_common.is_single(regid)):
52793958c9STaylor Simpson        f.write(", %s" % (def_helper_types[regtype]))
53793958c9STaylor Simpson    else:
54793958c9STaylor Simpson        print("Bad register parse: ",regtype,regid,toss,numregs)
55793958c9STaylor Simpson
56793958c9STaylor Simpson##
57793958c9STaylor Simpson## Generate the DEF_HELPER prototype for an instruction
58793958c9STaylor Simpson##     For A2_add: Rd32=add(Rs32,Rt32)
59793958c9STaylor Simpson##     We produce:
60793958c9STaylor Simpson##         DEF_HELPER_3(A2_add, s32, env, s32, s32)
61793958c9STaylor Simpson##
62793958c9STaylor Simpsondef gen_helper_prototype(f, tag, tagregs, tagimms):
63793958c9STaylor Simpson    regs = tagregs[tag]
64793958c9STaylor Simpson    imms = tagimms[tag]
65793958c9STaylor Simpson
66793958c9STaylor Simpson    numresults = 0
67793958c9STaylor Simpson    numscalarresults = 0
68793958c9STaylor Simpson    numscalarreadwrite = 0
69793958c9STaylor Simpson    for regtype,regid,toss,numregs in regs:
70793958c9STaylor Simpson        if (hex_common.is_written(regid)):
71793958c9STaylor Simpson            numresults += 1
72793958c9STaylor Simpson            if (hex_common.is_scalar_reg(regtype)):
73793958c9STaylor Simpson                numscalarresults += 1
74793958c9STaylor Simpson        if (hex_common.is_readwrite(regid)):
75793958c9STaylor Simpson            if (hex_common.is_scalar_reg(regtype)):
76793958c9STaylor Simpson                numscalarreadwrite += 1
77793958c9STaylor Simpson
78793958c9STaylor Simpson    if (numscalarresults > 1):
79793958c9STaylor Simpson        ## The helper is bogus when there is more than one result
80793958c9STaylor Simpson        f.write('DEF_HELPER_1(%s, void, env)\n' % tag)
81793958c9STaylor Simpson    else:
82793958c9STaylor Simpson        ## Figure out how many arguments the helper will take
83793958c9STaylor Simpson        if (numscalarresults == 0):
84793958c9STaylor Simpson            def_helper_size = len(regs)+len(imms)+numscalarreadwrite+1
85fb67c2bfSTaylor Simpson            if hex_common.need_pkt_has_multi_cof(tag): def_helper_size += 1
86793958c9STaylor Simpson            if hex_common.need_part1(tag): def_helper_size += 1
87793958c9STaylor Simpson            if hex_common.need_slot(tag): def_helper_size += 1
8840085901STaylor Simpson            if hex_common.need_PC(tag): def_helper_size += 1
89613653e5STaylor Simpson            if hex_common.helper_needs_next_PC(tag): def_helper_size += 1
90793958c9STaylor Simpson            f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag))
91793958c9STaylor Simpson            ## The return type is void
92793958c9STaylor Simpson            f.write(', void' )
93793958c9STaylor Simpson        else:
94793958c9STaylor Simpson            def_helper_size = len(regs)+len(imms)+numscalarreadwrite
95fb67c2bfSTaylor Simpson            if hex_common.need_pkt_has_multi_cof(tag): def_helper_size += 1
96793958c9STaylor Simpson            if hex_common.need_part1(tag): def_helper_size += 1
97793958c9STaylor Simpson            if hex_common.need_slot(tag): def_helper_size += 1
9840085901STaylor Simpson            if hex_common.need_PC(tag): def_helper_size += 1
99613653e5STaylor Simpson            if hex_common.helper_needs_next_PC(tag): def_helper_size += 1
100793958c9STaylor Simpson            f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag))
101793958c9STaylor Simpson
102793958c9STaylor Simpson        ## Generate the qemu DEF_HELPER type for each result
103ccd9eec8STaylor Simpson        ## Iterate over this list twice
104ccd9eec8STaylor Simpson        ## - Emit the scalar result
105ccd9eec8STaylor Simpson        ## - Emit the vector result
106793958c9STaylor Simpson        i=0
107793958c9STaylor Simpson        for regtype,regid,toss,numregs in regs:
108793958c9STaylor Simpson            if (hex_common.is_written(regid)):
109ccd9eec8STaylor Simpson                if (not hex_common.is_hvx_reg(regtype)):
110793958c9STaylor Simpson                    gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i)
111793958c9STaylor Simpson                i += 1
112793958c9STaylor Simpson
113793958c9STaylor Simpson        ## Put the env between the outputs and inputs
114793958c9STaylor Simpson        f.write(', env' )
115793958c9STaylor Simpson        i += 1
116793958c9STaylor Simpson
117ccd9eec8STaylor Simpson        # Second pass
118ccd9eec8STaylor Simpson        for regtype,regid,toss,numregs in regs:
119ccd9eec8STaylor Simpson            if (hex_common.is_written(regid)):
120ccd9eec8STaylor Simpson                if (hex_common.is_hvx_reg(regtype)):
121ccd9eec8STaylor Simpson                    gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i)
122ccd9eec8STaylor Simpson                    i += 1
123ccd9eec8STaylor Simpson
124793958c9STaylor Simpson        ## Generate the qemu type for each input operand (regs and immediates)
125793958c9STaylor Simpson        for regtype,regid,toss,numregs in regs:
126793958c9STaylor Simpson            if (hex_common.is_read(regid)):
127ccd9eec8STaylor Simpson                if (hex_common.is_hvx_reg(regtype) and
128ccd9eec8STaylor Simpson                    hex_common.is_readwrite(regid)):
129ccd9eec8STaylor Simpson                    continue
130793958c9STaylor Simpson                gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i)
131793958c9STaylor Simpson                i += 1
132793958c9STaylor Simpson        for immlett,bits,immshift in imms:
133793958c9STaylor Simpson            f.write(", s32")
134793958c9STaylor Simpson
135fb67c2bfSTaylor Simpson        ## Add the arguments for the instruction pkt_has_multi_cof, slot and
136fb67c2bfSTaylor Simpson        ## part1 (if needed)
137fb67c2bfSTaylor Simpson        if hex_common.need_pkt_has_multi_cof(tag): f.write(', i32')
13840085901STaylor Simpson        if hex_common.need_PC(tag): f.write(', i32')
139613653e5STaylor Simpson        if hex_common.helper_needs_next_PC(tag): f.write(', i32')
140793958c9STaylor Simpson        if hex_common.need_slot(tag): f.write(', i32' )
141793958c9STaylor Simpson        if hex_common.need_part1(tag): f.write(' , i32' )
142793958c9STaylor Simpson        f.write(')\n')
143793958c9STaylor Simpson
144793958c9STaylor Simpsondef main():
145793958c9STaylor Simpson    hex_common.read_semantics_file(sys.argv[1])
146793958c9STaylor Simpson    hex_common.read_attribs_file(sys.argv[2])
147793958c9STaylor Simpson    hex_common.read_overrides_file(sys.argv[3])
148d51bcabeSTaylor Simpson    hex_common.read_overrides_file(sys.argv[4])
149e71fdc4fSAlessandro Di Federico    ## Whether or not idef-parser is enabled is
150e71fdc4fSAlessandro Di Federico    ## determined by the number of arguments to
151e71fdc4fSAlessandro Di Federico    ## this script:
152e71fdc4fSAlessandro Di Federico    ##
153e71fdc4fSAlessandro Di Federico    ##   5 args. -> not enabled,
154e71fdc4fSAlessandro Di Federico    ##   6 args. -> idef-parser enabled.
155e71fdc4fSAlessandro Di Federico    ##
156e71fdc4fSAlessandro Di Federico    ## The 6:th arg. then holds a list of the successfully
157e71fdc4fSAlessandro Di Federico    ## parsed instructions.
158e71fdc4fSAlessandro Di Federico    is_idef_parser_enabled = len(sys.argv) > 6
159e71fdc4fSAlessandro Di Federico    if is_idef_parser_enabled:
160e71fdc4fSAlessandro Di Federico        hex_common.read_idef_parser_enabled_file(sys.argv[5])
161793958c9STaylor Simpson    hex_common.calculate_attribs()
162793958c9STaylor Simpson    tagregs = hex_common.get_tagregs()
163793958c9STaylor Simpson    tagimms = hex_common.get_tagimms()
164793958c9STaylor Simpson
165e71fdc4fSAlessandro Di Federico    output_file = sys.argv[-1]
166e71fdc4fSAlessandro Di Federico    with open(output_file, 'w') as f:
167793958c9STaylor Simpson        for tag in hex_common.tags:
168793958c9STaylor Simpson            ## Skip the priv instructions
169793958c9STaylor Simpson            if ( "A_PRIV" in hex_common.attribdict[tag] ) :
170793958c9STaylor Simpson                continue
171793958c9STaylor Simpson            ## Skip the guest instructions
172793958c9STaylor Simpson            if ( "A_GUEST" in hex_common.attribdict[tag] ) :
173793958c9STaylor Simpson                continue
174793958c9STaylor Simpson            ## Skip the diag instructions
175793958c9STaylor Simpson            if ( tag == "Y6_diag" ) :
176793958c9STaylor Simpson                continue
177793958c9STaylor Simpson            if ( tag == "Y6_diag0" ) :
178793958c9STaylor Simpson                continue
179793958c9STaylor Simpson            if ( tag == "Y6_diag1" ) :
180793958c9STaylor Simpson                continue
181793958c9STaylor Simpson
182793958c9STaylor Simpson            if ( hex_common.skip_qemu_helper(tag) ):
183793958c9STaylor Simpson                continue
184e71fdc4fSAlessandro Di Federico            if ( hex_common.is_idef_parser_enabled(tag) ):
185e71fdc4fSAlessandro Di Federico                continue
186793958c9STaylor Simpson
187793958c9STaylor Simpson            gen_helper_prototype(f, tag, tagregs, tagimms)
188793958c9STaylor Simpson
189793958c9STaylor Simpsonif __name__ == "__main__":
190793958c9STaylor Simpson    main()
191