fp.isa revision 2147
12SN/A// -*- mode:c++ -*-
22190SN/A
32SN/A// Copyright (c) 2003-2005 The Regents of The University of Michigan
42SN/A// All rights reserved.
52SN/A//
62SN/A// Redistribution and use in source and binary forms, with or without
72SN/A// modification, are permitted provided that the following conditions are
82SN/A// met: redistributions of source code must retain the above copyright
92SN/A// notice, this list of conditions and the following disclaimer;
102SN/A// redistributions in binary form must reproduce the above copyright
112SN/A// notice, this list of conditions and the following disclaimer in the
122SN/A// documentation and/or other materials provided with the distribution;
132SN/A// neither the name of the copyright holders nor the names of its
142SN/A// contributors may be used to endorse or promote products derived from
152SN/A// this software without specific prior written permission.
162SN/A//
172SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272665SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282665SN/A
292SN/Aoutput exec {{
302SN/A    /// Check "FP enabled" machine status bit.  Called when executing any FP
312680Sktlim@umich.edu    /// instruction in full-system mode.
322680Sktlim@umich.edu    /// @retval Full-system mode: NoFault if FP is enabled, FenFault
332SN/A    /// if not.  Non-full-system mode: always returns NoFault.
342972Sgblack@eecs.umich.edu#if FULL_SYSTEM
352972Sgblack@eecs.umich.edu    inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
362972Sgblack@eecs.umich.edu    {
371858SN/A        Fault fault = NoFault;	// dummy... this ipr access should not fault
382423SN/A        if (!EV5::ICSR_FPE(xc->readIpr(AlphaISA::IPR_ICSR, fault))) {
392190SN/A            fault = new FloatEnableFault;
4056SN/A        }
41217SN/A        return fault;
422036SN/A    }
432SN/A#else
442190SN/A    inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
452190SN/A    {
462190SN/A        return NoFault;
472190SN/A    }
482190SN/A#endif
492313SN/A}};
502235SN/A
512423SN/Aoutput header {{
522521SN/A    /**
532521SN/A     * Base class for general floating-point instructions.  Includes
542190SN/A     * support for various Alpha rounding and trapping modes.  Only FP
552190SN/A     * instructions that require this support are derived from this
562330SN/A     * class; the rest derive directly from AlphaStaticInst.
572330SN/A     */
582330SN/A    class AlphaFP : public AlphaStaticInst
592SN/A    {
602680Sktlim@umich.edu      public:
612680Sktlim@umich.edu        /// Alpha FP rounding modes.
622680Sktlim@umich.edu        enum RoundingMode {
632680Sktlim@umich.edu            Chopped = 0,	///< round toward zero
642680Sktlim@umich.edu            Minus_Infinity = 1, ///< round toward minus infinity
652680Sktlim@umich.edu            Normal = 2,		///< round to nearest (default)
662680Sktlim@umich.edu            Dynamic = 3,	///< use FPCR setting (in instruction)
672680Sktlim@umich.edu            Plus_Infinity = 3	///< round to plus inifinity (in FPCR)
682680Sktlim@umich.edu        };
692680Sktlim@umich.edu
702680Sktlim@umich.edu        /// Alpha FP trapping modes.
712682Sktlim@umich.edu        /// For instructions that produce integer results, the
722680Sktlim@umich.edu        /// "Underflow Enable" modes really mean "Overflow Enable", and
732680Sktlim@umich.edu        /// the assembly modifier is V rather than U.
742680Sktlim@umich.edu        enum TrappingMode {
752680Sktlim@umich.edu            /// default: nothing enabled
762680Sktlim@umich.edu            Imprecise = 0,		   ///< no modifier
772SN/A            /// underflow/overflow traps enabled, inexact disabled
782107SN/A            Underflow_Imprecise = 1,	   ///< /U or /V
792107SN/A            Underflow_Precise = 5,	   ///< /SU or /SV
802107SN/A            /// underflow/overflow and inexact traps enabled
812190SN/A            Underflow_Inexact_Precise = 7  ///< /SUI or /SVI
822455SN/A        };
832455SN/A
842107SN/A      protected:
852159SN/A        /// Map Alpha rounding mode to C99 constants from <fenv.h>.
862SN/A        static const int alphaToC99RoundingMode[];
87246SN/A
88246SN/A        /// Map enum RoundingMode values to disassembly suffixes.
89246SN/A        static const char *roundingModeSuffix[];
90246SN/A        /// Map enum TrappingMode values to FP disassembly suffixes.
91246SN/A        static const char *fpTrappingModeSuffix[];
92246SN/A        /// Map enum TrappingMode values to integer disassembly suffixes.
93246SN/A        static const char *intTrappingModeSuffix[];
94246SN/A
95246SN/A        /// This instruction's rounding mode.
96246SN/A        RoundingMode roundingMode;
97246SN/A        /// This instruction's trapping mode.
98246SN/A        TrappingMode trappingMode;
99246SN/A
1002190SN/A        /// Have we warned about this instruction's unsupported
101246SN/A        /// rounding mode (if applicable)?
102246SN/A        mutable bool warnedOnRounding;
103246SN/A
104246SN/A        /// Have we warned about this instruction's unsupported
105246SN/A        /// trapping mode (if applicable)?
106246SN/A        mutable bool warnedOnTrapping;
107246SN/A
1082SN/A        /// Constructor
1092680Sktlim@umich.edu        AlphaFP(const char *mnem, MachInst _machInst, OpClass __opClass)
1102423SN/A            : AlphaStaticInst(mnem, _machInst, __opClass),
1112190SN/A              roundingMode((enum RoundingMode)FP_ROUNDMODE),
112180SN/A              trappingMode((enum TrappingMode)FP_TRAPMODE),
1132190SN/A              warnedOnRounding(false),
1142190SN/A              warnedOnTrapping(false)
1152190SN/A        {
1162190SN/A        }
1172190SN/A
1182190SN/A        int getC99RoundingMode(uint64_t fpcr_val) const;
1192190SN/A
1202190SN/A        // This differs from the AlphaStaticInst version only in
1212190SN/A        // printing suffixes for non-default rounding & trapping modes.
1222190SN/A        std::string
1232521SN/A        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
1242330SN/A    };
1252654SN/A
1262521SN/A}};
1272521SN/A
1282680Sktlim@umich.edu
1292521SN/Aoutput decoder {{
1302521SN/A    int
1312190SN/A    AlphaFP::getC99RoundingMode(uint64_t fpcr_val) const
1322518SN/A    {
1332518SN/A        if (roundingMode == Dynamic) {
1342190SN/A            return alphaToC99RoundingMode[bits(fpcr_val, 59, 58)];
1352190SN/A        }
1362190SN/A        else {
1372190SN/A            return alphaToC99RoundingMode[roundingMode];
1382159SN/A        }
1392235SN/A    }
1402103SN/A
141393SN/A    std::string
142393SN/A    AlphaFP::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1432190SN/A    {
144393SN/A        std::string mnem_str(mnemonic);
145393SN/A
1462190SN/A#ifndef SS_COMPATIBLE_DISASSEMBLY
147393SN/A        std::string suffix("");
148393SN/A        suffix += ((_destRegIdx[0] >= FP_Base_DepTag)
1492875Sksewell@umich.edu                   ? fpTrappingModeSuffix[trappingMode]
150393SN/A                   : intTrappingModeSuffix[trappingMode]);
151393SN/A        suffix += roundingModeSuffix[roundingMode];
1522190SN/A
1532159SN/A        if (suffix != "") {
1542159SN/A            mnem_str = csprintf("%s/%s", mnemonic, suffix);
1552190SN/A        }
1562159SN/A#endif
1572159SN/A
1582680Sktlim@umich.edu        std::stringstream ss;
1592159SN/A        ccprintf(ss, "%-10s ", mnem_str.c_str());
1602190SN/A
1612159SN/A        // just print the first two source regs... if there's
1622190SN/A        // a third one, it's a read-modify-write dest (Rc),
1632190SN/A        // e.g. for CMOVxx
1642159SN/A        if (_numSrcRegs > 0) {
1652235SN/A            printReg(ss, _srcRegIdx[0]);
1662313SN/A        }
1672235SN/A        if (_numSrcRegs > 1) {
1682235SN/A            ss << ",";
1692235SN/A            printReg(ss, _srcRegIdx[1]);
1702235SN/A        }
1712235SN/A
1722254SN/A        // just print the first dest... if there's a second one,
1732254SN/A        // it's generally implicit
1742254SN/A        if (_numDestRegs > 0) {
1752235SN/A            if (_numSrcRegs > 0)
1762235SN/A                ss << ",";
1772190SN/A            printReg(ss, _destRegIdx[0]);
1782159SN/A        }
1792235SN/A
1802254SN/A        return ss.str();
1812190SN/A    }
1822159SN/A
1832680Sktlim@umich.edu    const int AlphaFP::alphaToC99RoundingMode[] = {
1842159SN/A        FE_TOWARDZERO,	// Chopped
1852190SN/A        FE_DOWNWARD,	// Minus_Infinity
1862159SN/A        FE_TONEAREST,	// Normal
1872159SN/A        FE_UPWARD	// Dynamic in inst, Plus_Infinity in FPCR
1882159SN/A    };
1892159SN/A
1902190SN/A    const char *AlphaFP::roundingModeSuffix[] = { "c", "m", "", "d" };
1912159SN/A    // mark invalid trapping modes, but don't fail on them, because
1922455SN/A    // you could decode anything on a misspeculated path
1932159SN/A    const char *AlphaFP::fpTrappingModeSuffix[] =
1942455SN/A        { "", "u", "INVTM2", "INVTM3", "INVTM4", "su", "INVTM6", "sui" };
1952159SN/A    const char *AlphaFP::intTrappingModeSuffix[] =
1962455SN/A        { "", "v", "INVTM2", "INVTM3", "INVTM4", "sv", "INVTM6", "svi" };
1972455SN/A}};
1982455SN/A
1992159SN/A// FP instruction class execute method template.  Handles non-standard
2002190SN/A// rounding modes.
2012159SN/Adef template FloatingPointExecute {{
2022455SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2032159SN/A                                  Trace::InstRecord *traceData) const
2042455SN/A    {
2052159SN/A        if (trappingMode != Imprecise && !warnedOnTrapping) {
2062455SN/A            warn("%s: non-standard trapping mode not supported",
2072455SN/A                 generateDisassembly(0, NULL));
2082455SN/A            warnedOnTrapping = true;
2092159SN/A        }
2102190SN/A
2112159SN/A        Fault fault = NoFault;
2122190SN/A
2132159SN/A        %(fp_enable_check)s;
2142190SN/A        %(op_decl)s;
2152159SN/A        %(op_rd)s;
2162190SN/A#if USE_FENV
2172159SN/A        if (roundingMode == Normal) {
2182447SN/A            %(code)s;
2192447SN/A        } else {
2202447SN/A            fesetround(getC99RoundingMode(xc->readFpcr()));
2212447SN/A            %(code)s;
2222190SN/A            fesetround(FE_TONEAREST);
2232159SN/A        }
2242190SN/A#else
2252190SN/A        if (roundingMode != Normal && !warnedOnRounding) {
2262190SN/A            warn("%s: non-standard rounding mode not supported",
2272190SN/A                 generateDisassembly(0, NULL));
2282190SN/A            warnedOnRounding = true;
2292190SN/A        }
2302235SN/A        %(code)s;
2312235SN/A#endif
2322190SN/A
2332190SN/A        if (fault == NoFault) {
2342190SN/A            %(op_wb)s;
2352159SN/A        }
2362159SN/A
2372190SN/A        return fault;
2382159SN/A    }
2392159SN/A}};
2402235SN/A
2412190SN/A// FP instruction class execute method template where no dynamic
2422190SN/A// rounding mode control is needed.  Like BasicExecute, but includes
2432159SN/A// check & warning for non-standard trapping mode.
2442190SN/Adef template FPFixedRoundingExecute {{
2452159SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2462159SN/A                                  Trace::InstRecord *traceData) const
2472190SN/A    {
2482159SN/A        if (trappingMode != Imprecise && !warnedOnTrapping) {
2492190SN/A            warn("%s: non-standard trapping mode not supported",
2502159SN/A                 generateDisassembly(0, NULL));
2512235SN/A            warnedOnTrapping = true;
2522190SN/A        }
2532834Sksewell@umich.edu
2542834Sksewell@umich.edu        Fault fault = NoFault;
2552834Sksewell@umich.edu
2562834Sksewell@umich.edu        %(fp_enable_check)s;
2572834Sksewell@umich.edu        %(op_decl)s;
2582159SN/A        %(op_rd)s;
2592525SN/A        %(code)s;
2602972Sgblack@eecs.umich.edu
2612972Sgblack@eecs.umich.edu        if (fault == NoFault) {
2622159SN/A            %(op_wb)s;
2632159SN/A        }
2642682Sktlim@umich.edu
2652682Sktlim@umich.edu        return fault;
2662682Sktlim@umich.edu    }
2672682Sktlim@umich.edu}};
2682682Sktlim@umich.edu
2692682Sktlim@umich.edudef template FloatingPointDecode {{
2702682Sktlim@umich.edu {
2712682Sktlim@umich.edu     AlphaStaticInst *i = new %(class_name)s(machInst);
2722682Sktlim@umich.edu     if (FC == 31) {
2732682Sktlim@umich.edu         i = makeNop(i);
2742680Sktlim@umich.edu     }
2752680Sktlim@umich.edu     return i;
2762190SN/A }
2772190SN/A}};
2782680Sktlim@umich.edu
2792680Sktlim@umich.edu// General format for floating-point operate instructions:
2802159SN/A// - Checks trapping and rounding mode flags.  Trapping modes
2812190SN/A//   currently unimplemented (will fail).
2822680Sktlim@umich.edu// - Generates NOP if FC == 31.
2832SN/Adef format FloatingPointOperate(code, *opt_args) {{
2842SN/A    iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args)
2852SN/A    decode_block = FloatingPointDecode.subst(iop)
2862680Sktlim@umich.edu    header_output = BasicDeclare.subst(iop)
2872SN/A    decoder_output = BasicConstructor.subst(iop)
2882680Sktlim@umich.edu    exec_output = FloatingPointExecute.subst(iop)
289716SN/A}};
2902680Sktlim@umich.edu
2912SN/A// Special format for cvttq where rounding mode is pre-decoded
2921858SN/Adef format FPFixedRounding(code, class_suffix, *opt_args) {{
2932680Sktlim@umich.edu    Name += class_suffix
2942SN/A    iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args)
2952680Sktlim@umich.edu    decode_block = FloatingPointDecode.subst(iop)
2961917SN/A    header_output = BasicDeclare.subst(iop)
2972680Sktlim@umich.edu    decoder_output = BasicConstructor.subst(iop)
2982521SN/A    exec_output = FPFixedRoundingExecute.subst(iop)
2992680Sktlim@umich.edu}};
3002654SN/A
3012680Sktlim@umich.edu