// -*- 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.
#if FULL_SYSTEM
    inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
    {
        Fault fault = NoFault;	// dummy... this ipr access should not fault
        if (!EV5::ICSR_FPE(xc->readMiscReg(AlphaISA::IPR_ICSR))) {
            fault = new FloatEnableFault;
        }
        return fault;
    }
#else
    inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
    {
        return NoFault;
    }
#endif
}};

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_Base_DepTag)
                   ? 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)s *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->readMiscRegNoEffect(AlphaISA::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)s *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)
}};

