#!/usr/bin/env python3

##
##  Copyright(c) 2019-2023 rev.ng Labs Srl. All Rights Reserved.
##
##  This program is free software; you can redistribute it and/or modify
##  it under the terms of the GNU General Public License as published by
##  the Free Software Foundation; either version 2 of the License, or
##  (at your option) any later version.
##
##  This program is distributed in the hope that it will be useful,
##  but WITHOUT ANY WARRANTY; without even the implied warranty of
##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##  GNU General Public License for more details.
##
##  You should have received a copy of the GNU General Public License
##  along with this program; if not, see <http://www.gnu.org/licenses/>.
##

import sys
import re
import string
from io import StringIO

import hex_common


##
## Generate code to be fed to the idef_parser
##
## Consider A2_add:
##
##     Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
##
## We produce:
##
##     A2_add(RdV, in RsV, in RtV) {
##       { RdV=RsV+RtV;}
##     }
##
## A2_add represents the instruction tag. Then we have a list of TCGv
## that the code generated by the parser can expect in input. Some of
## them are inputs ("in" prefix), while some others are outputs.
##
def main():
    hex_common.read_semantics_file(sys.argv[1])
    hex_common.read_attribs_file(sys.argv[2])
    hex_common.calculate_attribs()
    tagregs = hex_common.get_tagregs()
    tagimms = hex_common.get_tagimms()

    with open(sys.argv[3], "w") as f:
        f.write('#include "macros.inc"\n\n')

        for tag in hex_common.tags:
            ## Skip the priv instructions
            if "A_PRIV" in hex_common.attribdict[tag]:
                continue
            ## Skip the guest instructions
            if "A_GUEST" in hex_common.attribdict[tag]:
                continue
            ## Skip instructions that saturate in a ternary expression
            if tag in {"S2_asr_r_r_sat", "S2_asl_r_r_sat"}:
                continue
            ## Skip instructions using switch
            if tag in {"S4_vrcrotate_acc", "S4_vrcrotate"}:
                continue
            ## Skip trap instructions
            if tag in {"J2_trap0", "J2_trap1"}:
                continue
            ## Skip 128-bit instructions
            if tag in {"A7_croundd_ri", "A7_croundd_rr"}:
                continue
            if tag in {
                "M7_wcmpyrw",
                "M7_wcmpyrwc",
                "M7_wcmpyiw",
                "M7_wcmpyiwc",
                "M7_wcmpyrw_rnd",
                "M7_wcmpyrwc_rnd",
                "M7_wcmpyiw_rnd",
                "M7_wcmpyiwc_rnd",
            }:
                continue
            ## Skip interleave/deinterleave instructions
            if tag in {"S2_interleave", "S2_deinterleave"}:
                continue
            ## Skip instructions using bit reverse
            if tag in {
                "S2_brev",
                "S2_brevp",
                "S2_ct0",
                "S2_ct1",
                "S2_ct0p",
                "S2_ct1p",
                "A4_tlbmatch",
            }:
                continue
            ## Skip other unsupported instructions
            if tag == "S2_cabacdecbin" or tag == "A5_ACS":
                continue
            if tag.startswith("Y"):
                continue
            if tag.startswith("V6_"):
                continue
            if tag.startswith("F"):
                continue
            if tag.endswith("_locked"):
                continue
            if "A_COF" in hex_common.attribdict[tag]:
                continue

            regs = tagregs[tag]
            imms = tagimms[tag]

            arguments = []
            for regtype, regid, toss, numregs in regs:
                prefix = "in " if hex_common.is_read(regid) else ""

                is_pair = hex_common.is_pair(regid)
                is_single_old = hex_common.is_single(regid) and hex_common.is_old_val(
                    regtype, regid, tag
                )
                is_single_new = hex_common.is_single(regid) and hex_common.is_new_val(
                    regtype, regid, tag
                )

                if is_pair or is_single_old:
                    arguments.append(f"{prefix}{regtype}{regid}V")
                elif is_single_new:
                    arguments.append(f"{prefix}{regtype}{regid}N")
                else:
                    print("Bad register parse: ", regtype, regid, toss, numregs)

            for immlett, bits, immshift in imms:
                arguments.append(hex_common.imm_name(immlett))

            f.write(f"{tag}({', '.join(arguments)}) {{\n")
            f.write("    ")
            if hex_common.need_ea(tag):
                f.write("size4u_t EA; ")
            f.write(f"{hex_common.semdict[tag]}\n")
            f.write("}\n\n")


if __name__ == "__main__":
    main()
