fp.isa revision 12110
12SN/A// -*- mode:c++ -*-
21762SN/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
272665Ssaidi@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282665Ssaidi@eecs.umich.edu//
292SN/A// Authors: Steve Reinhardt
302SN/A
312SN/A////////////////////////////////////////////////////////////////////
322SN/A//
332SN/A// Floating-point instructions
3477SN/A//
3577SN/A//      Note that many FP-type instructions which do not support all the
362986Sgblack@eecs.umich.edu//      various rounding & trapping modes use the simpler format
3756SN/A//      BasicOperateWithNopCheck.
3856SN/A//
3956SN/A
402SN/Aoutput exec {{
412SN/A    /// Check "FP enabled" machine status bit.  Called when executing any FP
422680Sktlim@umich.edu    /// instruction in full-system mode.
432SN/A    /// @retval Full-system mode: NoFault if FP is enabled, FenFault
442SN/A    /// if not.  Non-full-system mode: always returns NoFault.
451910SN/A    inline Fault checkFpEnableFault(CPU_EXEC_CONTEXT *xc)
463536Sgblack@eecs.umich.edu    {
473536Sgblack@eecs.umich.edu        Fault fault = NoFault;  // dummy... this ipr access should not fault
482SN/A        if (FullSystem && !ICSR_FPE(xc->readMiscReg(IPR_ICSR))) {
493536Sgblack@eecs.umich.edu            fault = std::make_shared<FloatEnableFault>();
503536Sgblack@eecs.umich.edu        }
513536Sgblack@eecs.umich.edu        return fault;
523536Sgblack@eecs.umich.edu    }
533536Sgblack@eecs.umich.edu    inline Fault checkVectorEnableFault(CPU_EXEC_CONTEXT *xc) {
543536Sgblack@eecs.umich.edu        return std::make_shared<VectorEnableFault>();
553536Sgblack@eecs.umich.edu    }
563536Sgblack@eecs.umich.edu}};
573536Sgblack@eecs.umich.edu
583536Sgblack@eecs.umich.eduoutput header {{
593536Sgblack@eecs.umich.edu    /**
603536Sgblack@eecs.umich.edu     * Base class for general floating-point instructions.  Includes
613536Sgblack@eecs.umich.edu     * support for various Alpha rounding and trapping modes.  Only FP
623536Sgblack@eecs.umich.edu     * instructions that require this support are derived from this
633536Sgblack@eecs.umich.edu     * class; the rest derive directly from AlphaStaticInst.
643536Sgblack@eecs.umich.edu     */
653536Sgblack@eecs.umich.edu    class AlphaFP : public AlphaStaticInst
663536Sgblack@eecs.umich.edu    {
673536Sgblack@eecs.umich.edu      public:
683536Sgblack@eecs.umich.edu        /// Alpha FP rounding modes.
693536Sgblack@eecs.umich.edu        enum RoundingMode {
703536Sgblack@eecs.umich.edu            Chopped = 0,        ///< round toward zero
713536Sgblack@eecs.umich.edu            Minus_Infinity = 1, ///< round toward minus infinity
723536Sgblack@eecs.umich.edu            Normal = 2,         ///< round to nearest (default)
733536Sgblack@eecs.umich.edu            Dynamic = 3,        ///< use FPCR setting (in instruction)
743536Sgblack@eecs.umich.edu            Plus_Infinity = 3   ///< round to plus inifinity (in FPCR)
753536Sgblack@eecs.umich.edu        };
763536Sgblack@eecs.umich.edu
773536Sgblack@eecs.umich.edu        /// Alpha FP trapping modes.
783536Sgblack@eecs.umich.edu        /// For instructions that produce integer results, the
793536Sgblack@eecs.umich.edu        /// "Underflow Enable" modes really mean "Overflow Enable", and
803536Sgblack@eecs.umich.edu        /// the assembly modifier is V rather than U.
813536Sgblack@eecs.umich.edu        enum TrappingMode {
823536Sgblack@eecs.umich.edu            /// default: nothing enabled
833536Sgblack@eecs.umich.edu            Imprecise = 0,                 ///< no modifier
843536Sgblack@eecs.umich.edu            /// underflow/overflow traps enabled, inexact disabled
853536Sgblack@eecs.umich.edu            Underflow_Imprecise = 1,       ///< /U or /V
863536Sgblack@eecs.umich.edu            Underflow_Precise = 5,         ///< /SU or /SV
871910SN/A            /// underflow/overflow and inexact traps enabled
881910SN/A            Underflow_Inexact_Precise = 7  ///< /SUI or /SVI
891910SN/A        };
901910SN/A
913536Sgblack@eecs.umich.edu      protected:
923536Sgblack@eecs.umich.edu        /// Map Alpha rounding mode to C99 constants from <fenv.h>.
933536Sgblack@eecs.umich.edu        static const int alphaToC99RoundingMode[];
943536Sgblack@eecs.umich.edu
953536Sgblack@eecs.umich.edu        /// Map enum RoundingMode values to disassembly suffixes.
963536Sgblack@eecs.umich.edu        static const char *roundingModeSuffix[];
973536Sgblack@eecs.umich.edu        /// Map enum TrappingMode values to FP disassembly suffixes.
983536Sgblack@eecs.umich.edu        static const char *fpTrappingModeSuffix[];
993536Sgblack@eecs.umich.edu        /// Map enum TrappingMode values to integer disassembly suffixes.
1003536Sgblack@eecs.umich.edu        static const char *intTrappingModeSuffix[];
1013536Sgblack@eecs.umich.edu
1023536Sgblack@eecs.umich.edu        /// This instruction's rounding mode.
1033536Sgblack@eecs.umich.edu        RoundingMode roundingMode;
1042SN/A        /// This instruction's trapping mode.
1052SN/A        TrappingMode trappingMode;
1062SN/A
1072SN/A        /// Have we warned about this instruction's unsupported
1083536Sgblack@eecs.umich.edu        /// rounding mode (if applicable)?
1092SN/A        mutable bool warnedOnRounding;
1102SN/A
1113536Sgblack@eecs.umich.edu        /// Have we warned about this instruction's unsupported
1122SN/A        /// trapping mode (if applicable)?
1132SN/A        mutable bool warnedOnTrapping;
1142SN/A
1152SN/A        /// Constructor
1162SN/A        AlphaFP(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
1171910SN/A            : AlphaStaticInst(mnem, _machInst, __opClass),
1181910SN/A              roundingMode((enum RoundingMode)FP_ROUNDMODE),
1192SN/A              trappingMode((enum TrappingMode)FP_TRAPMODE),
1202SN/A              warnedOnRounding(false),
1213536Sgblack@eecs.umich.edu              warnedOnTrapping(false)
1222SN/A        {
1232SN/A        }
1242SN/A
1252SN/A        int getC99RoundingMode(uint64_t fpcr_val) const;
1262SN/A
1272SN/A        // This differs from the AlphaStaticInst version only in
1282SN/A        // printing suffixes for non-default rounding & trapping modes.
1292SN/A        std::string
1302SN/A        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
1312SN/A    };
1322SN/A
1332680Sktlim@umich.edu}};
1342SN/A
1352SN/A
1363536Sgblack@eecs.umich.eduoutput decoder {{
1373536Sgblack@eecs.umich.edu    int
1383536Sgblack@eecs.umich.edu    AlphaFP::getC99RoundingMode(uint64_t fpcr_val) const
1393536Sgblack@eecs.umich.edu    {
1403536Sgblack@eecs.umich.edu        if (roundingMode == Dynamic) {
1413536Sgblack@eecs.umich.edu            return alphaToC99RoundingMode[bits(fpcr_val, 59, 58)];
1423536Sgblack@eecs.umich.edu        }
1433536Sgblack@eecs.umich.edu        else {
1443536Sgblack@eecs.umich.edu            return alphaToC99RoundingMode[roundingMode];
1453536Sgblack@eecs.umich.edu        }
1463536Sgblack@eecs.umich.edu    }
1473536Sgblack@eecs.umich.edu
1483536Sgblack@eecs.umich.edu    std::string
1493536Sgblack@eecs.umich.edu    AlphaFP::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1503536Sgblack@eecs.umich.edu    {
1513536Sgblack@eecs.umich.edu        std::string mnem_str(mnemonic);
1523536Sgblack@eecs.umich.edu
1532SN/A#ifndef SS_COMPATIBLE_DISASSEMBLY
1542SN/A        std::string suffix("");
1552SN/A        suffix += ((_destRegIdx[0].isFloatReg())
1562SN/A                   ? fpTrappingModeSuffix[trappingMode]
1572SN/A                   : intTrappingModeSuffix[trappingMode]);
1582SN/A        suffix += roundingModeSuffix[roundingMode];
1592SN/A
1602SN/A        if (suffix != "") {
1613536Sgblack@eecs.umich.edu            mnem_str = csprintf("%s/%s", mnemonic, suffix);
1623536Sgblack@eecs.umich.edu        }
1632SN/A#endif
1642SN/A
1652SN/A        std::stringstream ss;
1662SN/A        ccprintf(ss, "%-10s ", mnem_str.c_str());
1672SN/A
1683536Sgblack@eecs.umich.edu        // just print the first two source regs... if there's
1693536Sgblack@eecs.umich.edu        // a third one, it's a read-modify-write dest (Rc),
1702SN/A        // e.g. for CMOVxx
1712680Sktlim@umich.edu        if (_numSrcRegs > 0) {
172180SN/A            printReg(ss, _srcRegIdx[0]);
1732SN/A        }
1742SN/A        if (_numSrcRegs > 1) {
1752SN/A            ss << ",";
1762SN/A            printReg(ss, _srcRegIdx[1]);
1773536Sgblack@eecs.umich.edu        }
1782SN/A
1792SN/A        // just print the first dest... if there's a second one,
1802SN/A        // it's generally implicit
1813536Sgblack@eecs.umich.edu        if (_numDestRegs > 0) {
1823536Sgblack@eecs.umich.edu            if (_numSrcRegs > 0)
1832SN/A                ss << ",";
1843536Sgblack@eecs.umich.edu            printReg(ss, _destRegIdx[0]);
1853536Sgblack@eecs.umich.edu        }
1862SN/A
1872SN/A        return ss.str();
1882SN/A    }
1892SN/A
1902SN/A    const int AlphaFP::alphaToC99RoundingMode[] = {
1912SN/A        M5_FE_TOWARDZERO,       // Chopped
1922SN/A        M5_FE_DOWNWARD, // Minus_Infinity
1933536Sgblack@eecs.umich.edu        M5_FE_TONEAREST,        // Normal
1942SN/A        M5_FE_UPWARD    // Dynamic in inst, Plus_Infinity in FPCR
1952SN/A    };
196507SN/A
197507SN/A    const char *AlphaFP::roundingModeSuffix[] = { "c", "m", "", "d" };
198507SN/A    // mark invalid trapping modes, but don't fail on them, because
1993536Sgblack@eecs.umich.edu    // you could decode anything on a misspeculated path
200507SN/A    const char *AlphaFP::fpTrappingModeSuffix[] =
2012SN/A        { "", "u", "INVTM2", "INVTM3", "INVTM4", "su", "INVTM6", "sui" };
2022680Sktlim@umich.edu    const char *AlphaFP::intTrappingModeSuffix[] =
2032SN/A        { "", "v", "INVTM2", "INVTM3", "INVTM4", "sv", "INVTM6", "svi" };
2042SN/A}};
2052SN/A
2062SN/A// FP instruction class execute method template.  Handles non-standard
2072SN/A// rounding modes.
2082SN/Adef template FloatingPointExecute {{
2092SN/A    Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
2102SN/A                                  Trace::InstRecord *traceData) const
2112SN/A    {
2122SN/A        if (trappingMode != Imprecise && !warnedOnTrapping) {
2132SN/A            warn("%s: non-standard trapping mode not supported",
2142SN/A                 generateDisassembly(0, NULL));
2153550Sgblack@eecs.umich.edu            warnedOnTrapping = true;
2163550Sgblack@eecs.umich.edu        }
2173550Sgblack@eecs.umich.edu
2183550Sgblack@eecs.umich.edu        Fault fault = NoFault;
219507SN/A
220507SN/A        %(fp_enable_check)s;
2212SN/A        %(op_decl)s;
2222SN/A        %(op_rd)s;
2232SN/A#if USE_FENV
2242SN/A        if (roundingMode == Normal) {
2253536Sgblack@eecs.umich.edu            %(code)s;
2262SN/A        } else {
2272SN/A            m5_fesetround(getC99RoundingMode(
2282SN/A                           xc->readMiscReg(MISCREG_FPCR)));
2292SN/A            %(code)s;
2302SN/A            m5_fesetround(M5_FE_TONEAREST);
2312SN/A        }
2322SN/A#else
2332SN/A        if (roundingMode != Normal && !warnedOnRounding) {
2343536Sgblack@eecs.umich.edu            warn("%s: non-standard rounding mode not supported",
2352SN/A                 generateDisassembly(0, NULL));
2362SN/A            warnedOnRounding = true;
2372SN/A        }
2382SN/A        %(code)s;
2392SN/A#endif
2402SN/A
2412SN/A        if (fault == NoFault) {
2422SN/A            %(op_wb)s;
2432SN/A        }
2442SN/A
2452SN/A        return fault;
2462SN/A    }
2472SN/A}};
2482SN/A
2492SN/A// FP instruction class execute method template where no dynamic
2502SN/A// rounding mode control is needed.  Like BasicExecute, but includes
2512SN/A// check & warning for non-standard trapping mode.
2522SN/Adef template FPFixedRoundingExecute {{
2532SN/A    Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
2542SN/A                                  Trace::InstRecord *traceData) const
2553536Sgblack@eecs.umich.edu    {
2562SN/A        if (trappingMode != Imprecise && !warnedOnTrapping) {
2572SN/A            warn("%s: non-standard trapping mode not supported",
2582SN/A                 generateDisassembly(0, NULL));
2593536Sgblack@eecs.umich.edu            warnedOnTrapping = true;
2602SN/A        }
2612SN/A
2622SN/A        Fault fault = NoFault;
2632SN/A
264507SN/A        %(fp_enable_check)s;
2652SN/A        %(op_decl)s;
2662SN/A        %(op_rd)s;
2672SN/A        %(code)s;
268
269        if (fault == NoFault) {
270            %(op_wb)s;
271        }
272
273        return fault;
274    }
275}};
276
277def template FloatingPointDecode {{
278 {
279     AlphaStaticInst *i = new %(class_name)s(machInst);
280     if (FC == 31) {
281         i = makeNop(i);
282     }
283     return i;
284 }
285}};
286
287// General format for floating-point operate instructions:
288// - Checks trapping and rounding mode flags.  Trapping modes
289//   currently unimplemented (will fail).
290// - Generates NOP if FC == 31.
291def format FloatingPointOperate(code, *opt_args) {{
292    iop = InstObjParams(name, Name, 'AlphaFP', code, opt_args)
293    decode_block = FloatingPointDecode.subst(iop)
294    header_output = BasicDeclare.subst(iop)
295    decoder_output = BasicConstructor.subst(iop)
296    exec_output = FloatingPointExecute.subst(iop)
297}};
298
299// Special format for cvttq where rounding mode is pre-decoded
300def format FPFixedRounding(code, class_suffix, *opt_args) {{
301    Name += class_suffix
302    iop = InstObjParams(name, Name, 'AlphaFP', code, opt_args)
303    decode_block = FloatingPointDecode.subst(iop)
304    header_output = BasicDeclare.subst(iop)
305    decoder_output = BasicConstructor.subst(iop)
306    exec_output = FPFixedRoundingExecute.subst(iop)
307}};
308
309