#!/usr/bin/env python3

##
##  Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. 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
import hex_common

##
##     Generate data for printing each instruction (format string + operands)
##
def regprinter(m):
    str = m.group(1)
    str += ":".join(["%d"]*len(m.group(2)))
    str += m.group(3)
    if ('S' in m.group(1)) and (len(m.group(2)) == 1):
        str += "/%s"
    elif ('C' in m.group(1)) and (len(m.group(2)) == 1):
        str += "/%s"
    return str

def spacify(s):
    # Regular expression that matches any operator that contains '=' character:
    opswithequal_re = '[-+^&|!<>=]?='
    # Regular expression that matches any assignment operator.
    assignment_re = '[-+^&|]?='

    # Out of the operators that contain the = sign, if the operator is also an
    # assignment, spaces will be added around it, unless it's enclosed within
    # parentheses, or spaces are already present.

    equals = re.compile(opswithequal_re)
    assign = re.compile(assignment_re)

    slen = len(s)
    paren_count = {}
    i = 0
    pc = 0
    while i < slen:
        c = s[i]
        if c == '(':
            pc += 1
        elif c == ')':
            pc -= 1
        paren_count[i] = pc
        i += 1

    # Iterate over all operators that contain the equal sign. If any
    # match is also an assignment operator, add spaces around it if
    # the parenthesis count is 0.
    pos = 0
    out = []
    for m in equals.finditer(s):
        ms = m.start()
        me = m.end()
        # t is the string that matched opswithequal_re.
        t = m.string[ms:me]
        out += s[pos:ms]
        pos = me
        if paren_count[ms] == 0:
            # Check if the entire string t is an assignment.
            am = assign.match(t)
            if am and len(am.group(0)) == me-ms:
                # Don't add spaces if they are already there.
                if ms > 0 and s[ms-1] != ' ':
                    out.append(' ')
                out += t
                if me < slen and s[me] != ' ':
                    out.append(' ')
                continue
        # If this is not an assignment, just append it to the output
        # string.
        out += t

    # Append the remaining part of the string.
    out += s[pos:len(s)]
    return ''.join(out)

def main():
    hex_common.read_semantics_file(sys.argv[1])
    hex_common.read_attribs_file(sys.argv[2])

    immext_casere = re.compile(r'IMMEXT\(([A-Za-z])')

    with open(sys.argv[3], 'w') as f:
        for tag in hex_common.tags:
            if not hex_common.behdict[tag]: continue
            extendable_upper_imm = False
            extendable_lower_imm = False
            m = immext_casere.search(hex_common.semdict[tag])
            if m:
                if m.group(1).isupper():
                    extendable_upper_imm = True
                else:
                    extendable_lower_imm = True
            beh = hex_common.behdict[tag]
            beh = hex_common.regre.sub(regprinter,beh)
            beh = hex_common.absimmre.sub(r"#%s0x%x",beh)
            beh = hex_common.relimmre.sub(r"PC+%s%d",beh)
            beh = spacify(beh)
            # Print out a literal "%s" at the end, used to match empty string
            # so C won't complain at us
            if ("A_VECX" in hex_common.attribdict[tag]):
                macname = "DEF_VECX_PRINTINFO"
            else: macname = "DEF_PRINTINFO"
            f.write('%s(%s,"%s%%s"' % (macname,tag,beh))
            regs_or_imms = \
                hex_common.reg_or_immre.findall(hex_common.behdict[tag])
            ri = 0
            seenregs = {}
            for allregs,a,b,c,d,allimm,immlett,bits,immshift in regs_or_imms:
                if a:
                    #register
                    if b in seenregs:
                        regno = seenregs[b]
                    else:
                        regno = ri
                    if len(b) == 1:
                        f.write(', insn->regno[%d]' % regno)
                        if 'S' in a:
                            f.write(', sreg2str(insn->regno[%d])' % regno)
                        elif 'C' in a:
                            f.write(', creg2str(insn->regno[%d])' % regno)
                    elif len(b) == 2:
                        f.write(', insn->regno[%d] + 1, insn->regno[%d]' % \
                            (regno,regno))
                    else:
                        print("Put some stuff to handle quads here")
                    if b not in seenregs:
                        seenregs[b] = ri
                        ri += 1
                else:
                    #immediate
                    if (immlett.isupper()):
                        if extendable_upper_imm:
                            if immlett in 'rR':
                                f.write(',insn->extension_valid?"##":""')
                            else:
                                f.write(',insn->extension_valid?"#":""')
                        else:
                            f.write(',""')
                        ii = 1
                    else:
                        if extendable_lower_imm:
                            if immlett in 'rR':
                                f.write(',insn->extension_valid?"##":""')
                            else:
                                f.write(',insn->extension_valid?"#":""')
                        else:
                            f.write(',""')
                        ii = 0
                    f.write(', insn->immed[%d]' % ii)
            # append empty string so there is at least one more arg
            f.write(',"")\n')

if __name__ == "__main__":
    main()
