1#!/usr/bin/env python3
2
3##
4##  Copyright(c) 2019-2022 rev.ng Labs Srl. 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
23from io import StringIO
24
25import hex_common
26
27##
28## Generate code to be fed to the idef_parser
29##
30## Consider A2_add:
31##
32##     Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
33##
34## We produce:
35##
36##     A2_add(RdV, in RsV, in RtV) {
37##       { RdV=RsV+RtV;}
38##     }
39##
40## A2_add represents the instruction tag. Then we have a list of TCGv
41## that the code generated by the parser can expect in input. Some of
42## them are inputs ("in" prefix), while some others are outputs.
43##
44def main():
45    hex_common.read_semantics_file(sys.argv[1])
46    hex_common.read_attribs_file(sys.argv[2])
47    hex_common.calculate_attribs()
48    tagregs = hex_common.get_tagregs()
49    tagimms = hex_common.get_tagimms()
50
51    with open(sys.argv[3], 'w') as f:
52        f.write('#include "macros.inc"\n\n')
53
54        for tag in hex_common.tags:
55            ## Skip the priv instructions
56            if ( "A_PRIV" in hex_common.attribdict[tag] ) :
57                continue
58            ## Skip the guest instructions
59            if ( "A_GUEST" in hex_common.attribdict[tag] ) :
60                continue
61            ## Skip instructions that saturate in a ternary expression
62            if ( tag in {'S2_asr_r_r_sat', 'S2_asl_r_r_sat'} ) :
63                continue
64            ## Skip instructions using switch
65            if ( tag in {'S4_vrcrotate_acc', 'S4_vrcrotate'} ) :
66                continue
67            ## Skip trap instructions
68            if ( tag in {'J2_trap0', 'J2_trap1'} ) :
69                continue
70            ## Skip 128-bit instructions
71            if ( tag in {'A7_croundd_ri', 'A7_croundd_rr'} ) :
72                continue
73            if ( tag in {'M7_wcmpyrw', 'M7_wcmpyrwc',
74                         'M7_wcmpyiw', 'M7_wcmpyiwc',
75                         'M7_wcmpyrw_rnd', 'M7_wcmpyrwc_rnd',
76                         'M7_wcmpyiw_rnd', 'M7_wcmpyiwc_rnd'} ) :
77                continue
78            ## Skip interleave/deinterleave instructions
79            if ( tag in {'S2_interleave', 'S2_deinterleave'} ) :
80                continue
81            ## Skip instructions using bit reverse
82            if ( tag in {'S2_brev', 'S2_brevp', 'S2_ct0', 'S2_ct1',
83                         'S2_ct0p', 'S2_ct1p', 'A4_tlbmatch'} ) :
84                continue
85            ## Skip other unsupported instructions
86            if ( tag == 'S2_cabacdecbin' or tag == 'A5_ACS' ) :
87                continue
88            if ( tag.startswith('Y') ) :
89                continue
90            if ( tag.startswith('V6_') ) :
91                continue
92            if ( tag.startswith('F') ) :
93                continue
94            if ( tag.endswith('_locked') ) :
95                continue
96            if ( "A_COF" in hex_common.attribdict[tag] ) :
97                continue
98
99            regs = tagregs[tag]
100            imms = tagimms[tag]
101
102            arguments = []
103            for regtype,regid,toss,numregs in regs:
104                prefix = "in " if hex_common.is_read(regid) else ""
105
106                is_pair = hex_common.is_pair(regid)
107                is_single_old = (hex_common.is_single(regid)
108                                 and hex_common.is_old_val(regtype, regid, tag))
109                is_single_new = (hex_common.is_single(regid)
110                                 and hex_common.is_new_val(regtype, regid, tag))
111
112                if is_pair or is_single_old:
113                    arguments.append("%s%s%sV" % (prefix, regtype, regid))
114                elif is_single_new:
115                    arguments.append("%s%s%sN" % (prefix, regtype, regid))
116                else:
117                    print("Bad register parse: ",regtype,regid,toss,numregs)
118
119            for immlett,bits,immshift in imms:
120                arguments.append(hex_common.imm_name(immlett))
121
122            f.write("%s(%s) {\n" % (tag, ", ".join(arguments)))
123            f.write("    ");
124            if hex_common.need_ea(tag):
125                f.write("size4u_t EA; ");
126            f.write("%s\n" % hex_common.semdict[tag])
127            f.write("}\n\n")
128
129if __name__ == "__main__":
130    main()
131