// -*- 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(CPU_EXEC_CONTEXT *xc)
    {
        Fault fault = NoFault;  // dummy... this ipr access should not fault
        if (FullSystem && !ICSR_FPE(xc->readMiscReg(IPR_ICSR))) {
            fault = new FloatEnableFault;
        }
        return fault;
    }
}};

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

}};


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] >= FP_Reg_Base)
                   ? 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(CPU_EXEC_CONTEXT *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(CPU_EXEC_CONTEXT *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)
}};

