// -*- mode:c++ -*-

// Copyright (c) 2007 MIPS Technologies, 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.
//
// Authors: Korey Sewell

////////////////////////////////////////////////////////////////////
//
// Floating Point operate instructions
//

output header {{
        /**
         * Base class for FP operations.
         */
        class FPOp : public MipsStaticInst
        {
                protected:

                /// Constructor
                FPOp(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass)
                {
                }

                //needs function to check for fpEnable or not
        };

        class FPCompareOp : public FPOp
        {
          protected:
            FPCompareOp(const char *mnem, MachInst _machInst, OpClass __opClass) : FPOp(mnem, _machInst, __opClass)
                {
                }

            std::string generateDisassembly(
                    Addr pc, const SymbolTable *symtab) const override;
        };
}};

output decoder {{
        std::string FPCompareOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
        {
            std::stringstream ss;

            ccprintf(ss, "%-10s ", mnemonic);

            ccprintf(ss,"%d",CC);

            if(_numSrcRegs > 0) {
                ss << ", ";
                printReg(ss, _srcRegIdx[0]);
            }

            if(_numSrcRegs > 1) {
                ss << ", ";
                printReg(ss, _srcRegIdx[1]);
            }

            return ss.str();
        }
}};

output header {{
        void fpResetCauseBits(ExecContext *cpu);

}};

output exec {{
        inline Fault checkFpEnableFault(ExecContext *xc)
        {
            //@TODO: Implement correct CP0 checks to see if the CP1
            // unit is enable or not
          if (!isCoprocessorEnabled(xc, 1))
              return std::make_shared<CoprocessorUnusableFault>(1);

          return NoFault;
        }

        //If any operand is Nan return the appropriate QNaN
        template <class T>
        bool
        fpNanOperands(FPOp *inst, ExecContext *xc, const T &src_type,
                      Trace::InstRecord *traceData)
        {
            uint64_t mips_nan = 0;
            assert(sizeof(T) == 4);

            for (int i = 0; i < inst->numSrcRegs(); i++) {
                uint64_t src_bits = xc->readFloatRegOperandBits(inst, 0);

                if (isNan(&src_bits, 32) ) {
                    mips_nan = MIPS32_QNAN;
                    xc->setFloatRegOperandBits(inst, 0, mips_nan);
                    if (traceData) { traceData->setData(mips_nan); }
                    return true;
                }
            }
            return false;
        }

        template <class T>
        bool
        fpInvalidOp(FPOp *inst, ExecContext *cpu, const T dest_val,
                    Trace::InstRecord *traceData)
        {
            uint64_t mips_nan = 0;
            T src_op = dest_val;
            assert(sizeof(T) == 4);

            if (isNan(&src_op, 32)) {
                mips_nan = MIPS32_QNAN;

                //Set value to QNAN
                cpu->setFloatRegOperandBits(inst, 0, mips_nan);

                //Read FCSR from FloatRegFile
                uint32_t fcsr_bits =
                    cpu->tcBase()->readFloatRegBits(FLOATREG_FCSR);

                uint32_t new_fcsr = genInvalidVector(fcsr_bits);

                //Write FCSR from FloatRegFile
                cpu->tcBase()->setFloatRegBits(FLOATREG_FCSR, new_fcsr);

                if (traceData) { traceData->setData(mips_nan); }
                return true;
            }

            return false;
        }

        void
        fpResetCauseBits(ExecContext *cpu)
        {
            //Read FCSR from FloatRegFile
            uint32_t fcsr = cpu->tcBase()->readFloatRegBits(FLOATREG_FCSR);

            // TODO: Use utility function here
            fcsr = bits(fcsr, 31, 18) << 18 | bits(fcsr, 11, 0);

            //Write FCSR from FloatRegFile
            cpu->tcBase()->setFloatRegBits(FLOATREG_FCSR, fcsr);
        }
}};

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

                %(fp_enable_check)s;


                //When is the right time to reset cause bits?
                //start of every instruction or every cycle?
                if (FullSystem)
                    fpResetCauseBits(xc);
                %(op_decl)s;
                %(op_rd)s;

                //Check if any FP operand is a NaN value
                if (!fpNanOperands((FPOp*)this, xc, Fd, traceData)) {
                    %(code)s;

                    //Change this code for Full-System/Sycall Emulation
                    //separation
                    //----
                    //Should Full System-Mode throw a fault here?
                    //----
                    //Check for IEEE 754 FP Exceptions
                    //fault = fpNanOperands((FPOp*)this, xc, Fd, traceData);
                    bool invalid_op = false;
                    if (FullSystem) {
                        invalid_op =
                            fpInvalidOp((FPOp*)this, xc, Fd, traceData);
                    }
                    if (!invalid_op && fault == NoFault) {
                        %(op_wb)s;
                    }
                }

                return fault;
        }
}};

// Primary format for float point operate instructions:
def format FloatOp(code, *flags) {{
        iop = InstObjParams(name, Name, 'FPOp', code, flags)
        header_output = BasicDeclare.subst(iop)
        decoder_output = BasicConstructor.subst(iop)
        decode_block = BasicDecode.subst(iop)
        exec_output = FloatingPointExecute.subst(iop)
}};

def format FloatCompareOp(cond_code, *flags) {{
    import sys

    code = 'bool cond;\n'
    if '_sf' in cond_code or 'SinglePrecision' in flags:
        if 'QnanException' in flags:
            code += 'if (isQnan(&Fs_sf, 32) || isQnan(&Ft_sf, 32)) {\n'
            code += '\tFCSR = genInvalidVector(FCSR);\n'
            code += '\treturn NoFault;'
            code += '}\n else '
        code += 'if (isNan(&Fs_sf, 32) || isNan(&Ft_sf, 32)) {\n'
    elif '_df' in cond_code or 'DoublePrecision' in flags:
        if 'QnanException' in flags:
            code += 'if (isQnan(&Fs_df, 64) || isQnan(&Ft_df, 64)) {\n'
            code += '\tFCSR = genInvalidVector(FCSR);\n'
            code += '\treturn NoFault;'
            code += '}\n else '
        code += 'if (isNan(&Fs_df, 64) || isNan(&Ft_df, 64)) {\n'
    else:
       sys.exit('Decoder Failed: Can\'t Determine Operand Type\n')

    if 'UnorderedTrue' in flags:
       code += 'cond = 1;\n'
    elif 'UnorderedFalse' in flags:
       code += 'cond = 0;\n'
    else:
       sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n')

    code += '} else {\n'
    code +=  cond_code + '}'
    code += 'FCSR = genCCVector(FCSR, CC, cond);\n'

    iop = InstObjParams(name, Name, 'FPCompareOp', code)
    header_output = BasicDeclare.subst(iop)
    decoder_output = BasicConstructor.subst(iop)
    decode_block = BasicDecode.subst(iop)
    exec_output = BasicExecute.subst(iop)
}};

def format FloatConvertOp(code, *flags) {{
    import sys

    #Determine Source Type
    convert = 'fpConvert('
    if '_sf' in code:
        code = 'float ' + code + '\n'
        convert += 'SINGLE_TO_'
    elif '_df' in code:
        code = 'double ' + code + '\n'
        convert += 'DOUBLE_TO_'
    elif '_sw' in code:
        code = 'int32_t ' + code + '\n'
        convert += 'WORD_TO_'
    elif '_sd' in code:
        code = 'int64_t ' + code + '\n'
        convert += 'LONG_TO_'
    else:
        sys.exit("Error Determining Source Type for Conversion")

    #Determine Destination Type
    if 'ToSingle' in flags:
        code += 'Fd_uw = ' + convert + 'SINGLE, '
    elif 'ToDouble' in flags:
        code += 'Fd_ud = ' + convert + 'DOUBLE, '
    elif 'ToWord' in flags:
        code += 'Fd_uw = ' + convert + 'WORD, '
    elif 'ToLong' in flags:
        code += 'Fd_ud = ' + convert + 'LONG, '
    else:
        sys.exit("Error Determining Destination Type for Conversion")

    #Figure out how to round value
    if 'Ceil' in flags:
        code += 'ceil(val)); '
    elif 'Floor' in flags:
        code += 'floor(val)); '
    elif 'Round' in flags:
        code += 'roundFP(val, 0)); '
    elif 'Trunc' in flags:
        code += 'truncFP(val));'
    else:
        code += 'val); '

    iop = InstObjParams(name, Name, 'FPOp', code)
    header_output = BasicDeclare.subst(iop)
    decoder_output = BasicConstructor.subst(iop)
    decode_block = BasicDecode.subst(iop)
    exec_output = BasicExecute.subst(iop)
}};

def format FloatAccOp(code, *flags) {{
        iop = InstObjParams(name, Name, 'FPOp', code, flags)
        header_output = BasicDeclare.subst(iop)
        decoder_output = BasicConstructor.subst(iop)
        decode_block = BasicDecode.subst(iop)
        exec_output = BasicExecute.subst(iop)
}};

// Primary format for float64 operate instructions:
def format Float64Op(code, *flags) {{
        iop = InstObjParams(name, Name, 'MipsStaticInst', code, flags)
        header_output = BasicDeclare.subst(iop)
        decoder_output = BasicConstructor.subst(iop)
        decode_block = BasicDecode.subst(iop)
        exec_output = BasicExecute.subst(iop)
}};

def format FloatPSCompareOp(cond_code1, cond_code2, *flags) {{
    import sys

    code = 'bool cond1, cond2;\n'
    code += 'bool code_block1, code_block2;\n'
    code += 'code_block1 = code_block2 = true;\n'

    if 'QnanException' in flags:
        code += 'if (isQnan(&Fs1_sf, 32) || isQnan(&Ft1_sf, 32)) {\n'
        code += '\tFCSR = genInvalidVector(FCSR);\n'
        code += 'code_block1 = false;'
        code += '}\n'
        code += 'if (isQnan(&Fs2_sf, 32) || isQnan(&Ft2_sf, 32)) {\n'
        code += '\tFCSR = genInvalidVector(FCSR);\n'
        code += 'code_block2 = false;'
        code += '}\n'

    code += 'if (code_block1) {'
    code += '\tif (isNan(&Fs1_sf, 32) || isNan(&Ft1_sf, 32)) {\n'
    if 'UnorderedTrue' in flags:
       code += 'cond1 = 1;\n'
    elif 'UnorderedFalse' in flags:
       code += 'cond1 = 0;\n'
    else:
       sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n')
    code += '} else {\n'
    code +=  cond_code1
    code += 'FCSR = genCCVector(FCSR, CC, cond1);}\n}\n'

    code += 'if (code_block2) {'
    code += '\tif (isNan(&Fs2_sf, 32) || isNan(&Ft2_sf, 32)) {\n'
    if 'UnorderedTrue' in flags:
       code += 'cond2 = 1;\n'
    elif 'UnorderedFalse' in flags:
       code += 'cond2 = 0;\n'
    else:
       sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n')
    code += '} else {\n'
    code +=  cond_code2
    code += 'FCSR = genCCVector(FCSR, CC, cond2);}\n}'

    iop = InstObjParams(name, Name, 'FPCompareOp', code)
    header_output = BasicDeclare.subst(iop)
    decoder_output = BasicConstructor.subst(iop)
    decode_block = BasicDecode.subst(iop)
    exec_output = BasicExecute.subst(iop)
}};

