// -*- 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)
                {
                }

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

                //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;

        };
}};

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)
}};

