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

// Copyright (c) 2003-2005 The Regents of The University of Michigan
// 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: Steve Reinhardt

////////////////////////////////////////////////////////////////////
//
// Floating-point instructions
//
//      Note that many FP-type instructions which do not support all the
//      various rounding & trapping modes use the simpler format
//      BasicOperateWithNopCheck.
//

output exec {{
    /// Check "FP enabled" machine status bit.  Called when executing any FP
    /// instruction in full-system mode.
    /// @retval Full-system mode: NoFault if FP is enabled, FenFault
    /// if not.  Non-full-system mode: always returns NoFault.
    inline Fault checkFpEnableFault(ExecContext *xc)
    {
        Fault fault = NoFault;  // dummy... this ipr access should not fault
        if (FullSystem && !ICSR_FPE(xc->readMiscReg(IPR_ICSR))) {
            fault = std::make_shared<FloatEnableFault>();
        }
        return fault;
    }
    inline Fault checkVectorEnableFault(ExecContext *xc) {
        return std::make_shared<VectorEnableFault>();
    }
}};

output header {{
    /**
     * Base class for general floating-point instructions.  Includes
     * support for various Alpha rounding and trapping modes.  Only FP
     * instructions that require this support are derived from this
     * class; the rest derive directly from AlphaStaticInst.
     */
    class AlphaFP : public AlphaStaticInst
    {
      public:
        /// Alpha FP rounding modes.
        enum RoundingMode {
            Chopped = 0,        ///< round toward zero
            Minus_Infinity = 1, ///< round toward minus infinity
            Normal = 2,         ///< round to nearest (default)
            Dynamic = 3,        ///< use FPCR setting (in instruction)
            Plus_Infinity = 3   ///< round to plus inifinity (in FPCR)
        };

        /// Alpha FP trapping modes.
        /// For instructions that produce integer results, the
        /// "Underflow Enable" modes really mean "Overflow Enable", and
        /// the assembly modifier is V rather than U.
        enum TrappingMode {
            /// default: nothing enabled
            Imprecise = 0,                 ///< no modifier
            /// underflow/overflow traps enabled, inexact disabled
            Underflow_Imprecise = 1,       ///< /U or /V
            Underflow_Precise = 5,         ///< /SU or /SV
            /// underflow/overflow and inexact traps enabled
            Underflow_Inexact_Precise = 7  ///< /SUI or /SVI
        };

      protected:
        /// Map Alpha rounding mode to C99 constants from <fenv.h>.
        static const int alphaToC99RoundingMode[];

        /// Map enum RoundingMode values to disassembly suffixes.
        static const char *roundingModeSuffix[];
        /// Map enum TrappingMode values to FP disassembly suffixes.
        static const char *fpTrappingModeSuffix[];
        /// Map enum TrappingMode values to integer disassembly suffixes.
        static const char *intTrappingModeSuffix[];

        /// This instruction's rounding mode.
        RoundingMode roundingMode;
        /// This instruction's trapping mode.
        TrappingMode trappingMode;

        /// Have we warned about this instruction's unsupported
        /// rounding mode (if applicable)?
        mutable bool warnedOnRounding;

        /// Have we warned about this instruction's unsupported
        /// trapping mode (if applicable)?
        mutable bool warnedOnTrapping;

        /// Constructor
        AlphaFP(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
            : AlphaStaticInst(mnem, _machInst, __opClass),
              roundingMode((enum RoundingMode)FP_ROUNDMODE),
              trappingMode((enum TrappingMode)FP_TRAPMODE),
              warnedOnRounding(false),
              warnedOnTrapping(false)
        {
        }

        int getC99RoundingMode(uint64_t fpcr_val) const;

        // This differs from the AlphaStaticInst version only in
        // printing suffixes for non-default rounding & trapping modes.
        std::string generateDisassembly(
                Addr pc, const SymbolTable *symtab) const override;
    };

}};


output decoder {{
    int
    AlphaFP::getC99RoundingMode(uint64_t fpcr_val) const
    {
        if (roundingMode == Dynamic) {
            return alphaToC99RoundingMode[bits(fpcr_val, 59, 58)];
        }
        else {
            return alphaToC99RoundingMode[roundingMode];
        }
    }

    std::string
    AlphaFP::generateDisassembly(Addr pc, const SymbolTable *symtab) const
    {
        std::string mnem_str(mnemonic);

#ifndef SS_COMPATIBLE_DISASSEMBLY
        std::string suffix("");
        suffix += ((_destRegIdx[0].isFloatReg())
                   ? fpTrappingModeSuffix[trappingMode]
                   : intTrappingModeSuffix[trappingMode]);
        suffix += roundingModeSuffix[roundingMode];

        if (suffix != "") {
            mnem_str = csprintf("%s/%s", mnemonic, suffix);
        }
#endif

        std::stringstream ss;
        ccprintf(ss, "%-10s ", mnem_str.c_str());

        // just print the first two source regs... if there's
        // a third one, it's a read-modify-write dest (Rc),
        // e.g. for CMOVxx
        if (_numSrcRegs > 0) {
            printReg(ss, _srcRegIdx[0]);
        }
        if (_numSrcRegs > 1) {
            ss << ",";
            printReg(ss, _srcRegIdx[1]);
        }

        // just print the first dest... if there's a second one,
        // it's generally implicit
        if (_numDestRegs > 0) {
            if (_numSrcRegs > 0)
                ss << ",";
            printReg(ss, _destRegIdx[0]);
        }

        return ss.str();
    }

    const int AlphaFP::alphaToC99RoundingMode[] = {
        M5_FE_TOWARDZERO,       // Chopped
        M5_FE_DOWNWARD, // Minus_Infinity
        M5_FE_TONEAREST,        // Normal
        M5_FE_UPWARD    // Dynamic in inst, Plus_Infinity in FPCR
    };

    const char *AlphaFP::roundingModeSuffix[] = { "c", "m", "", "d" };
    // mark invalid trapping modes, but don't fail on them, because
    // you could decode anything on a misspeculated path
    const char *AlphaFP::fpTrappingModeSuffix[] =
        { "", "u", "INVTM2", "INVTM3", "INVTM4", "su", "INVTM6", "sui" };
    const char *AlphaFP::intTrappingModeSuffix[] =
        { "", "v", "INVTM2", "INVTM3", "INVTM4", "sv", "INVTM6", "svi" };
}};

// FP instruction class execute method template.  Handles non-standard
// rounding modes.
def template FloatingPointExecute {{
    Fault %(class_name)s::execute(ExecContext *xc,
                                  Trace::InstRecord *traceData) const
    {
        if (trappingMode != Imprecise && !warnedOnTrapping) {
            warn("%s: non-standard trapping mode not supported",
                 generateDisassembly(0, NULL));
            warnedOnTrapping = true;
        }

        Fault fault = NoFault;

        %(fp_enable_check)s;
        %(op_decl)s;
        %(op_rd)s;
#if USE_FENV
        if (roundingMode == Normal) {
            %(code)s;
        } else {
            m5_fesetround(getC99RoundingMode(
                           xc->readMiscReg(MISCREG_FPCR)));
            %(code)s;
            m5_fesetround(M5_FE_TONEAREST);
        }
#else
        if (roundingMode != Normal && !warnedOnRounding) {
            warn("%s: non-standard rounding mode not supported",
                 generateDisassembly(0, NULL));
            warnedOnRounding = true;
        }
        %(code)s;
#endif

        if (fault == NoFault) {
            %(op_wb)s;
        }

        return fault;
    }
}};

// FP instruction class execute method template where no dynamic
// rounding mode control is needed.  Like BasicExecute, but includes
// check & warning for non-standard trapping mode.
def template FPFixedRoundingExecute {{
    Fault %(class_name)s::execute(ExecContext *xc,
                                  Trace::InstRecord *traceData) const
    {
        if (trappingMode != Imprecise && !warnedOnTrapping) {
            warn("%s: non-standard trapping mode not supported",
                 generateDisassembly(0, NULL));
            warnedOnTrapping = true;
        }

        Fault fault = NoFault;

        %(fp_enable_check)s;
        %(op_decl)s;
        %(op_rd)s;
        %(code)s;

        if (fault == NoFault) {
            %(op_wb)s;
        }

        return fault;
    }
}};

def template FloatingPointDecode {{
 {
     AlphaStaticInst *i = new %(class_name)s(machInst);
     if (FC == 31) {
         i = makeNop(i);
     }
     return i;
 }
}};

// General format for floating-point operate instructions:
// - Checks trapping and rounding mode flags.  Trapping modes
//   currently unimplemented (will fail).
// - Generates NOP if FC == 31.
def format FloatingPointOperate(code, *opt_args) {{
    iop = InstObjParams(name, Name, 'AlphaFP', code, opt_args)
    decode_block = FloatingPointDecode.subst(iop)
    header_output = BasicDeclare.subst(iop)
    decoder_output = BasicConstructor.subst(iop)
    exec_output = FloatingPointExecute.subst(iop)
}};

// Special format for cvttq where rounding mode is pre-decoded
def format FPFixedRounding(code, class_suffix, *opt_args) {{
    Name += class_suffix
    iop = InstObjParams(name, Name, 'AlphaFP', code, opt_args)
    decode_block = FloatingPointDecode.subst(iop)
    header_output = BasicDeclare.subst(iop)
    decoder_output = BasicConstructor.subst(iop)
    exec_output = FPFixedRoundingExecute.subst(iop)
}};

