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
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##    static void generate_A2_add(DisasContext *ctx)
31##    {
32##        Insn *insn G_GNUC_UNUSED = ctx->insn;
33##        const int RdN = insn->regno[0];
34##        TCGv RdV = get_result_gpr(ctx, RdN);
35##        TCGv RsV = hex_gpr[insn->regno[1]];
36##        TCGv RtV = hex_gpr[insn->regno[2]];
37##        <GEN>
38##        gen_log_reg_write(ctx, RdN, RdV);
39##    }
40##
41##       where <GEN> depends on hex_common.skip_qemu_helper(tag)
42##       if hex_common.skip_qemu_helper(tag) is True
43##       <GEN>  is fGEN_TCG_A2_add({ RdV=RsV+RtV;});
44##       if hex_common.skip_qemu_helper(tag) is False
45##       <GEN>  is gen_helper_A2_add(RdV, tcg_env, RsV, RtV);
46##
47def gen_tcg_func(f, tag, regs, imms):
48    f.write(f"static void generate_{tag}(DisasContext *ctx)\n")
49    f.write("{\n")
50
51    f.write("    Insn *insn G_GNUC_UNUSED = ctx->insn;\n")
52
53    if hex_common.need_ea(tag):
54        f.write("    TCGv EA G_GNUC_UNUSED = tcg_temp_new();\n")
55
56    ## Declare all the operands (regs and immediates)
57    i = 0
58    for regtype, regid in regs:
59        reg = hex_common.get_register(tag, regtype, regid)
60        reg.decl_tcg(f, tag, i)
61        i += 1
62    for immlett, bits, immshift in imms:
63        i = 1 if immlett.isupper() else 0
64        f.write(f"    int {hex_common.imm_name(immlett)} = insn->immed[{i}];\n")
65
66    if hex_common.is_idef_parser_enabled(tag):
67        declared = []
68        ## Handle registers
69        for regtype, regid in regs:
70            reg = hex_common.get_register(tag, regtype, regid)
71            reg.idef_arg(declared)
72        ## Handle immediates
73        for immlett, bits, immshift in imms:
74            declared.append(hex_common.imm_name(immlett))
75
76        arguments = ", ".join(["ctx", "ctx->insn", "ctx->pkt"] + declared)
77        f.write(f"    emit_{tag}({arguments});\n")
78
79    elif hex_common.skip_qemu_helper(tag):
80        f.write(f"    fGEN_TCG_{tag}({hex_common.semdict[tag]});\n")
81    else:
82        ## Generate the call to the helper
83        declared = []
84        ret_type = hex_common.helper_ret_type(tag, regs).call_arg
85        if ret_type != "void":
86            declared.append(ret_type)
87
88        for arg in hex_common.helper_args(tag, regs, imms):
89            declared.append(arg.call_arg)
90
91        arguments = ", ".join(declared)
92        f.write(f"    gen_helper_{tag}({arguments});\n")
93
94    ## Write all the outputs
95    for regtype, regid in regs:
96        reg = hex_common.get_register(tag, regtype, regid)
97        if reg.is_written():
98            reg.log_write(f, tag)
99
100    f.write("}\n\n")
101
102
103def gen_def_tcg_func(f, tag, tagregs, tagimms):
104    regs = tagregs[tag]
105    imms = tagimms[tag]
106
107    gen_tcg_func(f, tag, regs, imms)
108
109
110def main():
111    is_idef_parser_enabled = hex_common.read_common_files()
112    tagregs = hex_common.get_tagregs()
113    tagimms = hex_common.get_tagimms()
114
115    output_file = sys.argv[-1]
116    with open(output_file, "w") as f:
117        f.write("#ifndef HEXAGON_TCG_FUNCS_H\n")
118        f.write("#define HEXAGON_TCG_FUNCS_H\n\n")
119        if is_idef_parser_enabled:
120            f.write('#include "idef-generated-emitter.h.inc"\n\n')
121
122        for tag in hex_common.tags:
123            ## Skip the priv instructions
124            if "A_PRIV" in hex_common.attribdict[tag]:
125                continue
126            ## Skip the guest instructions
127            if "A_GUEST" in hex_common.attribdict[tag]:
128                continue
129            ## Skip the diag instructions
130            if tag == "Y6_diag":
131                continue
132            if tag == "Y6_diag0":
133                continue
134            if tag == "Y6_diag1":
135                continue
136
137            gen_def_tcg_func(f, tag, tagregs, tagimms)
138
139        f.write("#endif    /* HEXAGON_TCG_FUNCS_H */\n")
140
141
142if __name__ == "__main__":
143    main()
144