fp.isa

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· ISA 代码 · 共 312 行

ISA
312
字号
// -*- mode:c++ -*-//Copyright (c) 2003, 2004, 2005//The Regents of The University of Michigan//All Rights Reserved//This code is part of the M5 simulator.//Permission is granted to use, copy, create derivative works and//redistribute this software and such derivative works for any purpose,//so long as the copyright notice above, this grant of permission, and//the disclaimer below appear in all copies made; and so long as the//name of The University of Michigan is not used in any advertising or//publicity pertaining to the use or distribution of this software//without specific, written prior authorization.//THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE//UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND WITHOUT//WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER EXPRESS OR//IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF//MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF//THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE FOR ANY DAMAGES,//INCLUDING DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL//DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OF OR IN CONNECTION//WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS HEREAFTER//ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.//Authors: Steven K. 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-decodeddef 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)}};

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?