# Copyright (c) 2014, 2016, 2018-2019, 2022 ARM Limited
# All rights reserved
#
# The license below extends only to copyright in the software and shall
# not be construed as granting a license to any other intellectual
# property including but not limited to intellectual property relating
# to a hardware implementation of the functionality of the software
# licensed hereunder.  You may use the software subject to the license
# terms below provided that you ensure that this notice is replicated
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
# Copyright (c) 2003-2005 The Regents of The University of Michigan
# Copyright (c) 2013,2015 Advanced Micro Devices, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


def overrideInOperand(func):
    func.override_in_operand = True
    return func


overrideInOperand.overrides = dict()


class OperandDesc(object):
    def __init__(
        self, base_cls, dflt_ext, reg_spec, flags=None, sort_pri=None
    ):

        from .isa_parser import makeList

        # Canonical flag structure is a triple of lists, where each list
        # indicates the set of flags implied by this operand always, when
        # used as a source, and when used as a dest, respectively.
        # For simplicity this can be initialized using a variety of fairly
        # obvious shortcuts; we convert these to canonical form here.
        if not flags:
            # no flags specified (e.g., 'None')
            flags = ([], [], [])
        elif isinstance(flags, str):
            # a single flag: assumed to be unconditional
            flags = ([flags], [], [])
        elif isinstance(flags, list):
            # a list of flags: also assumed to be unconditional
            flags = (flags, [], [])
        elif isinstance(flags, tuple):
            # it's a tuple: it should be a triple,
            # but each item could be a single string or a list
            (uncond_flags, src_flags, dest_flags) = flags
            flags = (
                makeList(uncond_flags),
                makeList(src_flags),
                makeList(dest_flags),
            )

        attrs = {}
        # reg_spec is either just a string or a dictionary
        # (for elems of vector)
        if isinstance(reg_spec, tuple):
            (reg_spec, elem_spec) = reg_spec
            if isinstance(elem_spec, str):
                attrs["elem_spec"] = elem_spec
            else:
                assert isinstance(elem_spec, dict)
                attrs["elems"] = elem_spec

        for key in dir(self):
            val = getattr(self, key)
            # If this is a method, extract the function that implements it.
            if hasattr(val, "__func__"):
                val = val.__func__
            # If this should override something in the operand
            if getattr(val, "override_in_operand", False):
                attrs[key] = val

        attrs.update(
            {
                "base_cls": base_cls,
                "dflt_ext": dflt_ext,
                "reg_spec": reg_spec,
                "flags": flags,
                "sort_pri": sort_pri,
            }
        )
        self.attrs = attrs

    def setName(self, name):
        self.attrs["base_name"] = name


class Operand(object):
    """Base class for operand descriptors.  An instance of this class
    (or actually a class derived from this one) represents a specific
    operand for a code block (e.g, "Rc.sq" as a dest). Intermediate
    derived classes encapsulates the traits of a particular operand
    type (e.g., "32-bit integer register")."""

    src_reg_constructor = "\n\tsetSrcRegIdx(_numSrcRegs++, %s);"
    dst_reg_constructor = "\n\tsetDestRegIdx(_numDestRegs++, %s);"

    def regId(self):
        return f"{self.reg_class}[{self.reg_spec}]"

    def srcRegId(self):
        return self.regId()

    def destRegId(self):
        return self.regId()

    def __init__(self, parser, full_name, ext, is_src, is_dest):
        self.parser = parser
        self.full_name = full_name
        self.ext = ext
        self.is_src = is_src
        self.is_dest = is_dest
        # The 'effective extension' (eff_ext) is either the actual
        # extension, if one was explicitly provided, or the default.
        if ext:
            self.eff_ext = ext
        elif hasattr(self, "dflt_ext"):
            self.eff_ext = self.dflt_ext

        if hasattr(self, "eff_ext"):
            self.ctype = parser.operandTypeMap[self.eff_ext]

    # Finalize additional fields (primarily code fields).  This step
    # is done separately since some of these fields may depend on the
    # register index enumeration that hasn't been performed yet at the
    # time of __init__().
    def finalize(self):
        self.flags = self.getFlags()
        self.constructor = self.makeConstructor()
        self.op_decl = self.makeDecl()

        if self.is_src:
            self.op_rd = self.makeRead()
            self.op_src_decl = self.makeDecl()
        else:
            self.op_rd = ""
            self.op_src_decl = ""

        if self.is_dest:
            self.op_wb = self.makeWrite()
            self.op_dest_decl = self.makeDecl()
        else:
            self.op_wb = ""
            self.op_dest_decl = ""

    def isMem(self):
        return 0

    def isReg(self):
        return 0

    def isPCState(self):
        return 0

    def isPCPart(self):
        return self.isPCState() and self.reg_spec

    def getFlags(self):
        # note the empty slice '[:]' gives us a copy of self.flags[0]
        # instead of a reference to it
        my_flags = self.flags[0][:]
        if self.is_src:
            my_flags += self.flags[1]
        if self.is_dest:
            my_flags += self.flags[2]
        return my_flags

    def makeDecl(self):
        # Note that initializations in the declarations are solely
        # to avoid 'uninitialized variable' errors from the compiler.
        return self.ctype + " " + self.base_name + " = 0;\n"


class RegOperand(Operand):
    def isReg(self):
        return 1

    def makeConstructor(self):
        c_src = ""
        c_dest = ""

        if self.is_src:
            c_src = self.src_reg_constructor % self.srcRegId()

        if self.is_dest:
            c_dest = self.dst_reg_constructor % self.destRegId()
            c_dest += f"\n\t_numTypedDestRegs[{self.reg_class}.type()]++;"

        return c_src + c_dest


class RegValOperand(RegOperand):
    def makeRead(self):
        reg_val = f"xc->getRegOperand(this, {self.src_reg_idx})"

        if self.ctype == "float":
            reg_val = f"bitsToFloat32({reg_val})"
        elif self.ctype == "double":
            reg_val = f"bitsToFloat64({reg_val})"

        return f"{self.base_name} = {reg_val};\n"

    def makeWrite(self):
        reg_val = self.base_name

        if self.ctype == "float":
            reg_val = f"floatToBits32({reg_val})"
        elif self.ctype == "double":
            reg_val = f"floatToBits64({reg_val})"

        return f"""
        {{
            RegVal final_val = {reg_val};
            xc->setRegOperand(this, {self.dest_reg_idx}, final_val);
            if (traceData) {{
                traceData->setData({self.reg_class}, final_val);
            }}
        }}"""


class RegOperandDesc(OperandDesc):
    def __init__(self, reg_class, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.attrs["reg_class"] = reg_class


class IntRegOperandDesc(RegOperandDesc):
    def __init__(self, *args, **kwargs):
        super().__init__("intRegClass", RegValOperand, *args, **kwargs)


class FloatRegOperandDesc(RegOperandDesc):
    def __init__(self, *args, **kwargs):
        super().__init__("floatRegClass", RegValOperand, *args, **kwargs)


class CCRegOperandDesc(RegOperandDesc):
    def __init__(self, *args, **kwargs):
        super().__init__("ccRegClass", RegValOperand, *args, **kwargs)


class VecElemOperandDesc(RegOperandDesc):
    def __init__(self, *args, **kwargs):
        super().__init__("vecElemClass", RegValOperand, *args, **kwargs)


class VecRegOperand(RegOperand):
    reg_class = "vecRegClass"

    def __init__(self, parser, full_name, ext, is_src, is_dest):
        super().__init__(parser, full_name, ext, is_src, is_dest)
        self.elemExt = None

    def makeDeclElem(self, elem_op):
        (elem_name, elem_ext) = elem_op
        (elem_spec, dflt_elem_ext) = self.elems[elem_name]
        if elem_ext:
            ext = elem_ext
        else:
            ext = dflt_elem_ext
        ctype = self.parser.operandTypeMap[ext]
        return f"\n\t{ctype} {elem_name} = 0;"

    def makeDecl(self):
        if not self.is_dest and self.is_src:
            c_decl = f"\t/* Vars for {self.base_name}*/"
            if hasattr(self, "active_elems"):
                if self.active_elems:
                    for elem in self.active_elems:
                        c_decl += self.makeDeclElem(elem)
            return c_decl + f"\t/* End vars for {self.base_name} */\n"
        else:
            return ""

    # Read destination register to write
    def makeReadWElem(self, elem_op):
        (elem_name, elem_ext) = elem_op
        (elem_spec, dflt_elem_ext) = self.elems[elem_name]
        if elem_ext:
            ext = elem_ext
        else:
            ext = dflt_elem_ext
        ctype = self.parser.operandTypeMap[ext]
        c_read = f"\t\t{ctype}& {elem_name} = {self.base_name}[{elem_spec}];\n"
        return c_read

    def makeReadW(self):
        tmp_name = f"tmp_d{self.dest_reg_idx}"
        c_readw = (
            f"\t\tauto &{tmp_name} = \n"
            f"\t\t    *({self.parser.namespace}::VecRegContainer *)\n"
            f"\t\t    xc->getWritableRegOperand(\n"
            f"\t\t        this, {self.dest_reg_idx});\n"
        )
        if self.elemExt:
            ext = f"{self.parser.operandTypeMap[self.elemExt]}"
            c_readw += f"\t\tauto {self.base_name} = {tmp_name}.as<{ext}>();\n"
        if self.ext:
            ext = f"{self.parser.operandTypeMap[self.ext]}"
            c_readw += f"\t\tauto {self.base_name} = {tmp_name}.as<{ext}>();\n"
        if hasattr(self, "active_elems"):
            if self.active_elems:
                for elem in self.active_elems:
                    c_readw += self.makeReadWElem(elem)
        return c_readw

    # Normal source operand read
    def makeReadElem(self, elem_op, name):
        (elem_name, elem_ext) = elem_op
        (elem_spec, dflt_elem_ext) = self.elems[elem_name]

        if elem_ext:
            ext = elem_ext
        else:
            ext = dflt_elem_ext
        ctype = self.parser.operandTypeMap[ext]
        c_read = f"\t\t{elem_name} = {name}[{elem_spec}];\n"
        return c_read

    def makeRead(self):
        name = self.base_name
        if self.is_dest and self.is_src:
            name += "_merger"

        tmp_name = f"tmp_s{self.src_reg_idx}"
        c_read = (
            f"\t\t{self.parser.namespace}::VecRegContainer "
            f"{tmp_name};\n"
            f"\t\txc->getRegOperand(this, {self.src_reg_idx},\n"
            f"\t\t    &{tmp_name});\n"
        )
        # If the parser has detected that elements are being access, create
        # the appropriate view
        if self.elemExt:
            ext = f"{self.parser.operandTypeMap[self.elemExt]}"
            c_read += f"\t\tauto {name} = {tmp_name}.as<{ext}>();\n"
        if self.ext:
            ext = f"{self.parser.operandTypeMap[self.ext]}"
            c_read += f"\t\tauto {name} = {tmp_name}.as<{ext}>();\n"
        if hasattr(self, "active_elems"):
            if self.active_elems:
                for elem in self.active_elems:
                    c_read += self.makeReadElem(elem, name)
        return c_read

    def makeWrite(self):
        return f"""
        if (traceData) {{
            traceData->setData({self.reg_class}, &tmp_d{self.dest_reg_idx});
        }}
        """

    def finalize(self):
        super().finalize()
        if self.is_dest:
            self.op_rd = self.makeReadW() + self.op_rd


class VecRegOperandDesc(RegOperandDesc):
    def __init__(self, *args, **kwargs):
        super().__init__("vecRegClass", VecRegOperand, *args, **kwargs)


class VecPredRegOperand(RegOperand):
    reg_class = "vecPredRegClass"

    def makeDecl(self):
        return ""

    def makeRead(self):
        tmp_name = f"tmp_s{self.src_reg_idx}"
        c_read = (
            f"\t\t{self.parser.namespace}::VecPredRegContainer \n"
            f"\t\t        {tmp_name};\n"
            f"xc->getRegOperand(this, {self.src_reg_idx}, "
            f"&{tmp_name});\n"
        )
        if self.ext:
            c_read += (
                f"\t\tauto {self.base_name} = {tmp_name}.as<"
                f"{self.parser.operandTypeMap[self.ext]}>();\n"
            )
        return c_read

    def makeReadW(self):
        tmp_name = f"tmp_d{self.dest_reg_idx}"
        c_readw = (
            f"\t\tauto &{tmp_name} = \n"
            f"\t\t    *({self.parser.namespace}::"
            f"VecPredRegContainer *)xc->getWritableRegOperand("
            f"this, {self.dest_reg_idx});\n"
        )
        if self.ext:
            c_readw += (
                f"\t\tauto {self.base_name} = {tmp_name}.as<"
                f"{self.parser.operandTypeMap[self.ext]}>();\n"
            )
        return c_readw

    def makeWrite(self):
        return f"""
        if (traceData) {{
            traceData->setData({self.reg_class}, &tmp_d{self.dest_reg_idx});
        }}
        """

    def finalize(self):
        super().finalize()
        if self.is_dest:
            self.op_rd = self.makeReadW() + self.op_rd


class VecPredRegOperandDesc(RegOperandDesc):
    def __init__(self, *args, **kwargs):
        super().__init__("vecPredRegClass", VecPredRegOperand, *args, **kwargs)


class MatRegOperand(RegOperand):
    reg_class = "MatRegClass"

    def __init__(self, parser, full_name, ext, is_src, is_dest):
        super().__init__(parser, full_name, ext, is_src, is_dest)

    def makeDecl(self):
        return ""

    def makeReadW(self):
        c_readw = (
            f"\t\tauto &tmp_d{self.dest_reg_idx} = \n"
            f"\t\t    *({self.parser.namespace}::MatRegContainer *)\n"
            f"\t\t    xc->getWritableRegOperand(this, \n"
            f"\t\t        {self.dest_reg_idx});\n"
            f"\t\tauto &{self.base_name} = tmp_d{self.dest_reg_idx};\n"
        )

        return c_readw

    def makeRead(self):
        name = self.base_name
        if self.is_dest and self.is_src:
            name += "_merger"

        c_read = (
            f"\t\t{self.parser.namespace}::MatRegContainer "
            f"\t\t        tmp_s{self.src_reg_idx};\n"
            f"\t\txc->getRegOperand(this, {self.src_reg_idx},\n"
            f"\t\t        &tmp_s{self.src_reg_idx});\n"
            f"\t\tauto &{name} = tmp_s{self.src_reg_idx};\n"
        )

        # The following is required due to the way that the O3 CPU
        # works. The ZA register is seen as two physical registers; one
        # for reading from and one for writing to. We need to make sure
        # to copy the data from the read-only copy to the writable
        # reference (the destination). Failure to do this results in
        # data loss for the O3 CPU. Other CPU models don't appear to
        # require this.
        if self.is_dest and self.is_src:
            c_read += f"{self.base_name} = {name};"

        return c_read

    def makeWrite(self):
        return f"""
        if (traceData) {{
            traceData->setData({self.reg_class}, &tmp_d{self.dest_reg_idx});
        }}
        """

    def finalize(self):
        super().finalize()
        if self.is_dest:
            self.op_rd = self.makeReadW() + self.op_rd


class MatRegOperandDesc(RegOperandDesc):
    def __init__(self, *args, **kwargs):
        super().__init__("matRegClass", MatRegOperand, *args, **kwargs)


class ControlRegOperand(Operand):
    reg_class = "miscRegClass"

    def isReg(self):
        return 1

    def isControlReg(self):
        return 1

    def makeConstructor(self):
        c_src = ""
        c_dest = ""

        if self.is_src:
            c_src = self.src_reg_constructor % self.srcRegId()

        if self.is_dest:
            c_dest = self.dst_reg_constructor % self.destRegId()

        return c_src + c_dest

    def makeRead(self):
        bit_select = 0
        if self.ctype == "float" or self.ctype == "double":
            error("Attempt to read control register as FP")

        return (
            f"{self.base_name} = "
            f"xc->readMiscRegOperand(this, {self.src_reg_idx});\n"
        )

    def makeWrite(self):
        if self.ctype == "float" or self.ctype == "double":
            error("Attempt to write control register as FP")
        wb = (
            f"xc->setMiscRegOperand(this, "
            f"{self.dest_reg_idx}, {self.base_name});\n"
        )
        wb += f"""
        if (traceData) {{
            traceData->setData({self.reg_class}, {self.base_name});
        }}
        """

        return wb


class ControlRegOperandDesc(RegOperandDesc):
    def __init__(self, *args, **kwargs):
        super().__init__("miscRegClass", ControlRegOperand, *args, **kwargs)


class MemOperand(Operand):
    def isMem(self):
        return 1

    def makeConstructor(self):
        return ""

    def makeDecl(self):
        # Declare memory data variable.
        return f"{self.ctype} {self.base_name} = {{}};\n"

    def makeRead(self):
        return ""

    def makeWrite(self):
        return ""


class MemOperandDesc(OperandDesc):
    def __init__(self, *args, **kwargs):
        super().__init__(MemOperand, *args, **kwargs)


class PCStateOperand(Operand):
    def __init__(self, parser, *args, **kwargs):
        super().__init__(parser, *args, **kwargs)
        self.parser = parser

    def makeConstructor(self):
        return ""

    def makeRead(self):
        if self.reg_spec:
            # A component of the PC state.
            return (
                f"{self.base_name} = "
                f"__parserAutoPCState.{self.reg_spec}();\n"
            )
        else:
            # The whole PC state itself.
            return (
                f"{self.base_name} = "
                f"xc->pcState().as<{self.parser.namespace}::PCState>();\n"
            )

    def makeWrite(self):
        if self.reg_spec:
            # A component of the PC state.
            return f"__parserAutoPCState.{self.reg_spec}({self.base_name});\n"
        else:
            # The whole PC state itself.
            return f"xc->pcState({self.base_name});\n"

    def makeDecl(self):
        ctype = f"{self.parser.namespace}::PCState"
        if self.isPCPart():
            ctype = self.ctype
        # Note that initializations in the declarations are solely
        # to avoid 'uninitialized variable' errors from the compiler.
        return f"{ctype} {self.base_name} = 0;\n"

    def isPCState(self):
        return 1


class PCStateOperandDesc(OperandDesc):
    def __init__(self, *args, **kwargs):
        super().__init__(PCStateOperand, *args, **kwargs)
