1#!/usr/bin/env python3
2
3##
4##  Copyright(c) 2019-2023 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##
29## Generate code to be fed to the idef_parser
30##
31## Consider A2_add:
32##
33##     Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
34##
35## We produce:
36##
37##     A2_add(RdV, in RsV, in RtV) {
38##       { RdV=RsV+RtV;}
39##     }
40##
41## A2_add represents the instruction tag. Then we have a list of TCGv
42## that the code generated by the parser can expect in input. Some of
43## them are inputs ("in" prefix), while some others are outputs.
44##
45def main():
46    hex_common.read_semantics_file(sys.argv[1])
47    hex_common.read_attribs_file(sys.argv[2])
48    hex_common.calculate_attribs()
49    hex_common.init_registers()
50    tagregs = hex_common.get_tagregs()
51    tagimms = hex_common.get_tagimms()
52
53    with open(sys.argv[3], "w") as f:
54        f.write('#include "macros.inc"\n\n')
55
56        for tag in hex_common.tags:
57            ## Skip the priv instructions
58            if "A_PRIV" in hex_common.attribdict[tag]:
59                continue
60            ## Skip the guest instructions
61            if "A_GUEST" in hex_common.attribdict[tag]:
62                continue
63            ## Skip instructions that saturate in a ternary expression
64            if tag in {"S2_asr_r_r_sat", "S2_asl_r_r_sat"}:
65                continue
66            ## Skip instructions using switch
67            if tag in {"S4_vrcrotate_acc", "S4_vrcrotate"}:
68                continue
69            ## Skip trap instructions
70            if tag in {"J2_trap0", "J2_trap1"}:
71                continue
72            ## Skip 128-bit instructions
73            if tag in {"A7_croundd_ri", "A7_croundd_rr"}:
74                continue
75            if tag in {
76                "M7_wcmpyrw",
77                "M7_wcmpyrwc",
78                "M7_wcmpyiw",
79                "M7_wcmpyiwc",
80                "M7_wcmpyrw_rnd",
81                "M7_wcmpyrwc_rnd",
82                "M7_wcmpyiw_rnd",
83                "M7_wcmpyiwc_rnd",
84            }:
85                continue
86            ## Skip interleave/deinterleave instructions
87            if tag in {"S2_interleave", "S2_deinterleave"}:
88                continue
89            ## Skip instructions using bit reverse
90            if tag in {
91                "S2_brev",
92                "S2_brevp",
93                "S2_ct0",
94                "S2_ct1",
95                "S2_ct0p",
96                "S2_ct1p",
97                "A4_tlbmatch",
98            }:
99                continue
100            ## Skip other unsupported instructions
101            if tag == "S2_cabacdecbin" or tag == "A5_ACS":
102                continue
103            if tag.startswith("Y"):
104                continue
105            if tag.startswith("V6_"):
106                continue
107            if ( tag.startswith("F") and
108                 tag not in {
109                     "F2_sfimm_p",
110                     "F2_sfimm_n",
111                     "F2_dfimm_p",
112                     "F2_dfimm_n",
113                     "F2_dfmpyll",
114                     "F2_dfmpylh"
115                 }):
116                continue
117            if tag.endswith("_locked"):
118                continue
119            if "A_COF" in hex_common.attribdict[tag]:
120                continue
121            if ( tag.startswith('R6_release_') ):
122                continue
123            ## Skip instructions that are incompatible with short-circuit
124            ## packet register writes
125            if ( tag == 'S2_insert' or
126                 tag == 'S2_insert_rp' or
127                 tag == 'S2_asr_r_svw_trun' or
128                 tag == 'A2_swiz' ):
129                continue
130
131            regs = tagregs[tag]
132            imms = tagimms[tag]
133
134            arguments = []
135            for regtype, regid in regs:
136                reg = hex_common.get_register(tag, regtype, regid)
137                prefix = "in " if reg.is_read() else ""
138                arguments.append(f"{prefix}{reg.reg_tcg()}")
139
140            for immlett, bits, immshift in imms:
141                arguments.append(hex_common.imm_name(immlett))
142
143            f.write(f"{tag}({', '.join(arguments)}) {{\n")
144            f.write("    ")
145            if hex_common.need_ea(tag):
146                f.write("size4u_t EA; ")
147            f.write(f"{hex_common.semdict[tag]}\n")
148            f.write("}\n\n")
149
150
151if __name__ == "__main__":
152    main()
153