// Copyright (c) 2007 The Hewlett-Packard Development Company
// Copyright (c) 2012-2013 Mark D. Hill and David A. Wood
// Copyright (c) 2015 Advanced Micro Devices, Inc.
//
// 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.
//
// 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.

//////////////////////////////////////////////////////////////////////////
//
// FpOp Microop templates
//
//////////////////////////////////////////////////////////////////////////

def template MicroFpOpExecute {{
    Fault
    %(class_name)s::execute(ExecContext *xc,
            Trace::InstRecord *traceData) const
    {
        Fault fault = NoFault;

        DPRINTF(X86, "The data size is %d\n", dataSize);
        %(op_decl)s;
        %(op_rd)s;

        if (%(cond_check)s) {
            %(code)s;
            %(flag_code)s;
            %(tag_code)s;
            %(top_code)s;
        } else {
            %(else_code)s;
        }

        //Write the resulting state to the execution context
        if (fault == NoFault) {
            %(op_wb)s;
        }
        return fault;
    }
}};

def template MicroFpOpDeclare {{
    class %(class_name)s : public %(base_class)s
    {
      private:
        %(reg_idx_arr_decl)s;

      public:
        template <typename ...Args>
        %(class_name)s(ExtMachInst mach_inst, const char *inst_mnem,
                uint64_t set_flags, uint8_t data_size, int8_t _spm,
                Args... args);

        Fault execute(ExecContext *, Trace::InstRecord *) const override;
    };
}};

def template MicroFpOpConstructor {{
    template <typename ...Args>
    %(class_name)s::%(class_name)s(ExtMachInst mach_inst,
            const char *inst_mnem, uint64_t set_flags,
            uint8_t data_size, int8_t _spm, Args... args) :
        %(base_class)s(mach_inst, "%(mnemonic)s", inst_mnem, set_flags,
                %(op_class)s, { args... }, data_size, _spm)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
    }
}};

let {{

    # Make these empty strings so that concatenating onto
    # them will always work.
    header_output = ""
    decoder_output = ""
    exec_output = ""

    class FpOpMeta(type):
        def buildCppClasses(self, name, Name, suffix, code, flag_code,
                cond_check, else_code, op_class, operand_types):

            # Globals to stick the output in
            global header_output
            global decoder_output
            global exec_output

            # Stick all the code together so it can be searched at once
            allCode = "|".join((code, flag_code, cond_check, else_code))

            # If there's something optional to do with flags, generate
            # a version without it and fix up this version to use it.
            if flag_code != "" or cond_check != "true":
                self.buildCppClasses(name, Name, suffix,
                        code, "", "true", else_code, op_class, operand_types)
                suffix = "Flags" + suffix

            base = "X86ISA::InstOperands<" + \
                ", ".join(["X86ISA::FpOp"] +
                          [op.cxx_class() for op in operand_types]) + ">"

            # Get everything ready for the substitution
            iop_tag = InstObjParams(name, Name + suffix + "TopTag", base,
                    {"code" : code,
                     "flag_code" : flag_code,
                     "cond_check" : cond_check,
                     "else_code" : else_code,
                     "tag_code" : "FTW = genX87Tags(FTW, TOP, spm);",
                     "top_code" : "TOP = (TOP + spm + 8) % 8;",
                     "op_class" : op_class})
            iop_top = InstObjParams(name, Name + suffix + "Top", base,
                    {"code" : code,
                     "flag_code" : flag_code,
                     "cond_check" : cond_check,
                     "else_code" : else_code,
                     "tag_code" : ";",
                     "top_code" : "TOP = (TOP + spm + 8) % 8;",
                     "op_class" : op_class})
            iop = InstObjParams(name, Name + suffix, base,
                    {"code" : code,
                     "flag_code" : flag_code,
                     "cond_check" : cond_check,
                     "else_code" : else_code,
                     "tag_code" : ";",
                     "top_code" : ";",
                     "op_class" : op_class})

            # Generate the actual code (finally!)
            header_output += MicroFpOpDeclare.subst(iop_tag)
            decoder_output += MicroFpOpConstructor.subst(iop_tag)
            exec_output += MicroFpOpExecute.subst(iop_tag)
            header_output += MicroFpOpDeclare.subst(iop_top)
            decoder_output += MicroFpOpConstructor.subst(iop_top)
            exec_output += MicroFpOpExecute.subst(iop_top)
            header_output += MicroFpOpDeclare.subst(iop)
            decoder_output += MicroFpOpConstructor.subst(iop)
            exec_output += MicroFpOpExecute.subst(iop)


        def __new__(mcls, Name, bases, dict):
            abstract = False
            name = Name.lower()
            if "abstract" in dict:
                abstract = dict['abstract']
                del dict['abstract']

            cls = super(FpOpMeta, mcls).__new__(mcls, Name, bases, dict)
            if not abstract:
                cls.className = Name
                cls.mnemonic = name
                code = cls.code
                flag_code = cls.flag_code
                cond_check = cls.cond_check
                else_code = cls.else_code
                op_class = cls.op_class
                operand_types = cls.operand_types

                # Set up the C++ classes
                mcls.buildCppClasses(cls, name, Name, "",
                        code, flag_code, cond_check, else_code, op_class,
                        operand_types)

                # Hook into the microassembler dict
                global microopClasses
                microopClasses[name] = cls

            return cls

    class FpOp(X86Microop, metaclass=FpOpMeta):
        # This class itself doesn't act as a microop
        abstract = True

        # Default template parameter values
        flag_code = ""
        cond_check = "true"
        else_code = ";"
        op_class = "FloatAddOp"

        def __init__(self, *ops, spm=0,
                SetStatus=False, UpdateFTW=True, dataSize="env.dataSize"):
            self.ops = list(map(str, ops))
            self.spm = spm
            self.dataSize = dataSize
            if SetStatus:
                self.className += "Flags"
            if spm:
                self.className += "Top"
            if spm and UpdateFTW:
                self.className += "Tag"

        def getAllocator(self, microFlags):
            # Ensure there's at least one element to join with ","s.
            op_iter = iter(self.ops)
            ops = list([Type(op_iter).ctor_args() for
                    Type in self.operand_types])
            spm_ops = [str(self.spm)] + ops
            return '''new %(class_name)s(machInst, macrocodeBlock,
                    %(flags)s, %(dataSize)s, %(spm_ops)s)''' % {
                "class_name" : self.className,
                "flags" : self.microFlagsText(microFlags),
                "dataSize" : self.dataSize,
                "spm_ops" : ", ".join(spm_ops)}

    class Fp0Op(FpOp):
        abstract = True
        operand_types = ()
        def __init__(self, **kwargs):
            super(Fp0Op, self).__init__(**kwargs)

    class Fp1Op(FpOp):
        abstract = True
        operand_types = (FloatDestOp)
        def __init__(self, reg1, **kwargs):
            super(Fp1Op, self).__init__(reg1, **kwargs)

    class Fp2Op(FpOp):
        abstract = True
        operand_types = (FloatDestOp, FloatSrc1Op)
        def __init__(self, reg1, reg2, **kwargs):
            super(Fp2Op, self).__init__(reg1, reg2, **kwargs)

    class Fp3Op(FpOp):
        abstract = True
        operand_types = (FloatDestOp, FloatSrc1Op, FloatSrc2Op)
        def __init__(self, reg1, reg2, reg3, **kwargs):
            super(Fp3Op, self).__init__(reg1, reg2, reg3, **kwargs)

    class Movfp(Fp2Op):
        code = 'FpDestReg_uqw = FpSrcReg1_uqw;'
        else_code = 'FpDestReg_uqw = FpDestReg_uqw;'
        cond_check = "checkCondition(ccFlagBits | cfofBits | dfBit | \
                                     ecfBit | ezfBit, src1)"
        op_class = 'IntAluOp'

    class Xorfp(Fp3Op):
        code = 'FpDestReg_uqw = FpSrcReg1_uqw ^ FpSrcReg2_uqw;'

    class Sqrtfp(Fp2Op):
        code = 'FpDestReg = sqrt(FpSrcReg1);'
        op_class = 'FloatSqrtOp'

    class Cosfp(Fp2Op):
        code = 'FpDestReg = cos(FpSrcReg1);'
        op_class = 'FloatSqrtOp'

    class Sinfp(Fp2Op):
        code = 'FpDestReg = sin(FpSrcReg1);'
        op_class = 'FloatSqrtOp'

    class Tanfp(Fp2Op):
        code = 'FpDestReg = tan(FpSrcReg1);'
        op_class = 'FloatSqrtOp'


    # Conversion microops
    class ConvOp(Fp2Op):
        abstract = True
        op_class = 'FloatCvtOp'

    # These probably shouldn't look at the ExtMachInst directly to figure
    # out what size to use and should instead delegate that to the macroop's
    # constructor. That would be more efficient, and it would make the
    # microops a little more modular.
    class Cvtf_i2d(ConvOp):
        operand_types = (FloatDestOp, IntSrc1Op)
        code = '''
            X86IntReg intReg = SrcReg1;
            if (REX_W)
                FpDestReg = intReg.SR;
            else
                FpDestReg = intReg.SE;
            '''

    class Cvtf_i2d_hi(ConvOp):
        operand_types = (FloatDestOp, IntSrc1Op)
        code = 'FpDestReg = bits(SrcReg1, 63, 32);'

    class Cvtf_d2i(ConvOp):
        operand_types = (FoldedDestOp, FloatSrc1Op)
        code = '''
            int64_t intSrcReg1 = static_cast<int64_t>(FpSrcReg1);
            DestReg = merge(DestReg, dest, intSrcReg1, dataSize);
            '''

    # Convert two integers registers representing an 80-bit floating
    # point number to an x87 register.
    class Cvtint_fp80(Fp3Op):
        operand_types = (FloatDestOp, IntSrc1Op, IntSrc2Op)
        code = '''
            uint8_t bits[10];
            *(uint64_t *)(bits + 0) = SrcReg1;
            *(uint16_t *)(bits + 8) = (uint16_t)SrcReg2;
            FpDestReg = loadFloat80(bits);
            '''

    # Convert an x87 register (double) into extended precision and
    # extract the highest 64 bits.
    class Cvtfp80h_int(ConvOp):
        operand_types = (IntDestOp, FloatSrc1Op)
        code = '''
            char bits[10];
            storeFloat80(bits, FpSrcReg1);
            DestReg = *(uint64_t *)(bits + 0);
            '''

    # Convert an x87 register (double) into extended precision and
    # extract the lowest 16 bits.
    class Cvtfp80l_int(ConvOp):
        operand_types = (IntDestOp, FloatSrc1Op)
        code = '''
            char bits[10];
            storeFloat80(bits, FpSrcReg1);
            DestReg = *(uint16_t *)(bits + 8);
            '''

    # These need to consider size at some point. They'll always use doubles
    # for the moment.
    class Addfp(Fp3Op):
        code = 'FpDestReg = FpSrcReg1 + FpSrcReg2;'

    class Mulfp(Fp3Op):
        code = 'FpDestReg = FpSrcReg1 * FpSrcReg2;'
        op_class = 'FloatMultOp'

    class Divfp(Fp3Op):
        code = 'FpDestReg = FpSrcReg1 / FpSrcReg2;'
        op_class = 'FloatDivOp'

    class Subfp(Fp3Op):
        code = 'FpDestReg = FpSrcReg1 - FpSrcReg2;'

    class Yl2xFp(Fp3Op):
        code = '''
            FpDestReg = FpSrcReg2 * (log(FpSrcReg1) / log(2));
        '''
        op_class = 'FloatSqrtOp'

    class PremFp(Fp3Op):
        code = '''
            RegVal new_fsw = FSW;
            int src1_exp;
            int src2_exp;
            std::frexp(FpSrcReg1, &src1_exp);
            std::frexp(FpSrcReg2, &src2_exp);

            const int d = src2_exp - src1_exp;
            if (d < 64) {
                const int64_t q = std::trunc(FpSrcReg2 / FpSrcReg1);
                FpDestReg = FpSrcReg2 - FpSrcReg1 * q;
                new_fsw &= ~(CC0Bit | CC1Bit | CC2Bit | CC2Bit);
                new_fsw |= (q & 0x1) ? CC1Bit : 0;
                new_fsw |= (q & 0x2) ? CC3Bit : 0;
                new_fsw |= (q & 0x4) ? CC0Bit : 0;
            } else {
                const int n = 42;
                const int64_t qq = std::trunc(
                    FpSrcReg2 / std::ldexp(FpSrcReg1, d - n));
                FpDestReg = FpSrcReg2 - std::ldexp(FpSrcReg1 * qq, d - n);
                new_fsw |= CC2Bit;
            }
        '''
        op_class = 'FloatDivOp'

        flag_code = 'FSW = new_fsw;'

    class Compfp(Fp2Op):
        operand_types = (FloatSrc1Op, FloatSrc2Op)
        # This class sets the condition codes in rflags according to the
        # rules for comparing floating point.
        code = '''
            //               ZF PF CF
            // Unordered      1  1  1
            // Greater than   0  0  0
            // Less than      0  0  1
            // Equal          1  0  0
            //           OF = SF = AF = 0
            ccFlagBits = ccFlagBits & ~(SFBit | AFBit | ZFBit | PFBit);
            cfofBits = cfofBits & ~(OFBit | CFBit);

            if (std::isnan(FpSrcReg1) || std::isnan(FpSrcReg2)) {
                ccFlagBits = ccFlagBits | (ZFBit | PFBit);
                cfofBits = cfofBits | CFBit;
            }
            else if(FpSrcReg1 < FpSrcReg2)
                cfofBits = cfofBits | CFBit;
            else if(FpSrcReg1 == FpSrcReg2)
                ccFlagBits = ccFlagBits | ZFBit;
        '''
        op_class = 'FloatCmpOp'

    class absfp(Fp2Op):
        code = 'FpDestReg = fabs(FpSrcReg1);'
        flag_code = 'FSW = FSW & (~CC1Bit);'

    class chsfp(Fp2Op):
        code = 'FpDestReg = (-1) * (FpSrcReg1);'
        flag_code = 'FSW = FSW & (~CC1Bit);'

    class Pop87(Fp0Op):
        code = ''
        op_class = 'IntAluOp'
}};
