fp.isa revision 2090
17199Sgblack@eecs.umich.edu// -*- mode:c++ -*-
27199Sgblack@eecs.umich.edu
37199Sgblack@eecs.umich.edu// Copyright (c) 2003-2005 The Regents of The University of Michigan
47199Sgblack@eecs.umich.edu// All rights reserved.
57199Sgblack@eecs.umich.edu//
67199Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
77199Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
87199Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
97199Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
107199Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
117199Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
127199Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
137199Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
147199Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
157199Sgblack@eecs.umich.edu// this software without specific prior written permission.
167199Sgblack@eecs.umich.edu//
177199Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
187199Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
197199Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
207199Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
217199Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
227199Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
237199Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
247199Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
257199Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
267199Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
277199Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
287199Sgblack@eecs.umich.edu
297199Sgblack@eecs.umich.eduoutput exec {{
307199Sgblack@eecs.umich.edu    /// Check "FP enabled" machine status bit.  Called when executing any FP
317199Sgblack@eecs.umich.edu    /// instruction in full-system mode.
327199Sgblack@eecs.umich.edu    /// @retval Full-system mode: NoFault if FP is enabled, FenFault
337199Sgblack@eecs.umich.edu    /// if not.  Non-full-system mode: always returns NoFault.
347199Sgblack@eecs.umich.edu#if FULL_SYSTEM
357199Sgblack@eecs.umich.edu    inline Fault * checkFpEnableFault(%(CPU_exec_context)s *xc)
367199Sgblack@eecs.umich.edu    {
377199Sgblack@eecs.umich.edu        Fault * fault = NoFault;	// dummy... this ipr access should not fault
387199Sgblack@eecs.umich.edu        if (!EV5::ICSR_FPE(xc->readIpr(AlphaISA::IPR_ICSR, fault))) {
397199Sgblack@eecs.umich.edu            fault = FloatEnableFault;
407199Sgblack@eecs.umich.edu        }
417199Sgblack@eecs.umich.edu        return fault;
427199Sgblack@eecs.umich.edu    }
437199Sgblack@eecs.umich.edu#else
447199Sgblack@eecs.umich.edu    inline Fault * checkFpEnableFault(%(CPU_exec_context)s *xc)
457199Sgblack@eecs.umich.edu    {
467199Sgblack@eecs.umich.edu        return NoFault;
477199Sgblack@eecs.umich.edu    }
487199Sgblack@eecs.umich.edu#endif
497199Sgblack@eecs.umich.edu}};
507199Sgblack@eecs.umich.edu
517199Sgblack@eecs.umich.eduoutput header {{
527199Sgblack@eecs.umich.edu    /**
537199Sgblack@eecs.umich.edu     * Base class for general floating-point instructions.  Includes
547199Sgblack@eecs.umich.edu     * support for various Alpha rounding and trapping modes.  Only FP
557199Sgblack@eecs.umich.edu     * instructions that require this support are derived from this
567199Sgblack@eecs.umich.edu     * class; the rest derive directly from AlphaStaticInst.
577199Sgblack@eecs.umich.edu     */
587202Sgblack@eecs.umich.edu    class AlphaFP : public AlphaStaticInst
597202Sgblack@eecs.umich.edu    {
607202Sgblack@eecs.umich.edu      public:
617202Sgblack@eecs.umich.edu        /// Alpha FP rounding modes.
627202Sgblack@eecs.umich.edu        enum RoundingMode {
637202Sgblack@eecs.umich.edu            Chopped = 0,	///< round toward zero
647202Sgblack@eecs.umich.edu            Minus_Infinity = 1, ///< round toward minus infinity
657202Sgblack@eecs.umich.edu            Normal = 2,		///< round to nearest (default)
667202Sgblack@eecs.umich.edu            Dynamic = 3,	///< use FPCR setting (in instruction)
677202Sgblack@eecs.umich.edu            Plus_Infinity = 3	///< round to plus inifinity (in FPCR)
687202Sgblack@eecs.umich.edu        };
697202Sgblack@eecs.umich.edu
707202Sgblack@eecs.umich.edu        /// Alpha FP trapping modes.
717202Sgblack@eecs.umich.edu        /// For instructions that produce integer results, the
727202Sgblack@eecs.umich.edu        /// "Underflow Enable" modes really mean "Overflow Enable", and
737202Sgblack@eecs.umich.edu        /// the assembly modifier is V rather than U.
747202Sgblack@eecs.umich.edu        enum TrappingMode {
757202Sgblack@eecs.umich.edu            /// default: nothing enabled
767202Sgblack@eecs.umich.edu            Imprecise = 0,		   ///< no modifier
777202Sgblack@eecs.umich.edu            /// underflow/overflow traps enabled, inexact disabled
787202Sgblack@eecs.umich.edu            Underflow_Imprecise = 1,	   ///< /U or /V
797202Sgblack@eecs.umich.edu            Underflow_Precise = 5,	   ///< /SU or /SV
807202Sgblack@eecs.umich.edu            /// underflow/overflow and inexact traps enabled
817202Sgblack@eecs.umich.edu            Underflow_Inexact_Precise = 7  ///< /SUI or /SVI
827202Sgblack@eecs.umich.edu        };
837202Sgblack@eecs.umich.edu
847202Sgblack@eecs.umich.edu      protected:
857202Sgblack@eecs.umich.edu        /// Map Alpha rounding mode to C99 constants from <fenv.h>.
867202Sgblack@eecs.umich.edu        static const int alphaToC99RoundingMode[];
877202Sgblack@eecs.umich.edu
887202Sgblack@eecs.umich.edu        /// Map enum RoundingMode values to disassembly suffixes.
897202Sgblack@eecs.umich.edu        static const char *roundingModeSuffix[];
907202Sgblack@eecs.umich.edu        /// Map enum TrappingMode values to FP disassembly suffixes.
917202Sgblack@eecs.umich.edu        static const char *fpTrappingModeSuffix[];
927202Sgblack@eecs.umich.edu        /// Map enum TrappingMode values to integer disassembly suffixes.
937202Sgblack@eecs.umich.edu        static const char *intTrappingModeSuffix[];
947202Sgblack@eecs.umich.edu
957202Sgblack@eecs.umich.edu        /// This instruction's rounding mode.
967202Sgblack@eecs.umich.edu        RoundingMode roundingMode;
977202Sgblack@eecs.umich.edu        /// This instruction's trapping mode.
987202Sgblack@eecs.umich.edu        TrappingMode trappingMode;
997202Sgblack@eecs.umich.edu
1007202Sgblack@eecs.umich.edu        /// Have we warned about this instruction's unsupported
1017202Sgblack@eecs.umich.edu        /// rounding mode (if applicable)?
1027202Sgblack@eecs.umich.edu        mutable bool warnedOnRounding;
1037202Sgblack@eecs.umich.edu
1047202Sgblack@eecs.umich.edu        /// Have we warned about this instruction's unsupported
1057202Sgblack@eecs.umich.edu        /// trapping mode (if applicable)?
1067202Sgblack@eecs.umich.edu        mutable bool warnedOnTrapping;
1077202Sgblack@eecs.umich.edu
1087202Sgblack@eecs.umich.edu        /// Constructor
1097202Sgblack@eecs.umich.edu        AlphaFP(const char *mnem, MachInst _machInst, OpClass __opClass)
1107202Sgblack@eecs.umich.edu            : AlphaStaticInst(mnem, _machInst, __opClass),
1117202Sgblack@eecs.umich.edu              roundingMode((enum RoundingMode)FP_ROUNDMODE),
1127202Sgblack@eecs.umich.edu              trappingMode((enum TrappingMode)FP_TRAPMODE),
1137202Sgblack@eecs.umich.edu              warnedOnRounding(false),
1147202Sgblack@eecs.umich.edu              warnedOnTrapping(false)
1157202Sgblack@eecs.umich.edu        {
1167202Sgblack@eecs.umich.edu        }
1177202Sgblack@eecs.umich.edu
1187202Sgblack@eecs.umich.edu        int getC99RoundingMode(uint64_t fpcr_val) const;
1197202Sgblack@eecs.umich.edu
1207209Sgblack@eecs.umich.edu        // This differs from the AlphaStaticInst version only in
1217209Sgblack@eecs.umich.edu        // printing suffixes for non-default rounding & trapping modes.
1227209Sgblack@eecs.umich.edu        std::string
1237209Sgblack@eecs.umich.edu        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
1247209Sgblack@eecs.umich.edu    };
1257261Sgblack@eecs.umich.edu
1267209Sgblack@eecs.umich.edu}};
1277209Sgblack@eecs.umich.edu
1287261Sgblack@eecs.umich.edu
1297261Sgblack@eecs.umich.eduoutput decoder {{
1307209Sgblack@eecs.umich.edu    int
1317209Sgblack@eecs.umich.edu    AlphaFP::getC99RoundingMode(uint64_t fpcr_val) const
1327209Sgblack@eecs.umich.edu    {
1337209Sgblack@eecs.umich.edu        if (roundingMode == Dynamic) {
1347209Sgblack@eecs.umich.edu            return alphaToC99RoundingMode[bits(fpcr_val, 59, 58)];
1357209Sgblack@eecs.umich.edu        }
1367209Sgblack@eecs.umich.edu        else {
1377209Sgblack@eecs.umich.edu            return alphaToC99RoundingMode[roundingMode];
1387209Sgblack@eecs.umich.edu        }
1397261Sgblack@eecs.umich.edu    }
1407209Sgblack@eecs.umich.edu
1417209Sgblack@eecs.umich.edu    std::string
1427261Sgblack@eecs.umich.edu    AlphaFP::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1437261Sgblack@eecs.umich.edu    {
1447209Sgblack@eecs.umich.edu        std::string mnem_str(mnemonic);
1457209Sgblack@eecs.umich.edu
1467209Sgblack@eecs.umich.edu#ifndef SS_COMPATIBLE_DISASSEMBLY
1477209Sgblack@eecs.umich.edu        std::string suffix("");
1487209Sgblack@eecs.umich.edu        suffix += ((_destRegIdx[0] >= FP_Base_DepTag)
1497209Sgblack@eecs.umich.edu                   ? fpTrappingModeSuffix[trappingMode]
1507261Sgblack@eecs.umich.edu                   : intTrappingModeSuffix[trappingMode]);
1517209Sgblack@eecs.umich.edu        suffix += roundingModeSuffix[roundingMode];
1527209Sgblack@eecs.umich.edu
1537261Sgblack@eecs.umich.edu        if (suffix != "") {
1547261Sgblack@eecs.umich.edu            mnem_str = csprintf("%s/%s", mnemonic, suffix);
1557209Sgblack@eecs.umich.edu        }
1567226Sgblack@eecs.umich.edu#endif
1577249Sgblack@eecs.umich.edu
1587249Sgblack@eecs.umich.edu        std::stringstream ss;
1597249Sgblack@eecs.umich.edu        ccprintf(ss, "%-10s ", mnem_str.c_str());
1607249Sgblack@eecs.umich.edu
1617249Sgblack@eecs.umich.edu        // just print the first two source regs... if there's
1627249Sgblack@eecs.umich.edu        // a third one, it's a read-modify-write dest (Rc),
1637249Sgblack@eecs.umich.edu        // e.g. for CMOVxx
1647249Sgblack@eecs.umich.edu        if (_numSrcRegs > 0) {
1657249Sgblack@eecs.umich.edu            printReg(ss, _srcRegIdx[0]);
1667249Sgblack@eecs.umich.edu        }
1677249Sgblack@eecs.umich.edu        if (_numSrcRegs > 1) {
1687249Sgblack@eecs.umich.edu            ss << ",";
1697249Sgblack@eecs.umich.edu            printReg(ss, _srcRegIdx[1]);
1707261Sgblack@eecs.umich.edu        }
1717249Sgblack@eecs.umich.edu
1727249Sgblack@eecs.umich.edu        // just print the first dest... if there's a second one,
1737261Sgblack@eecs.umich.edu        // it's generally implicit
1747261Sgblack@eecs.umich.edu        if (_numDestRegs > 0) {
1757249Sgblack@eecs.umich.edu            if (_numSrcRegs > 0)
1767249Sgblack@eecs.umich.edu                ss << ",";
1777251Sgblack@eecs.umich.edu            printReg(ss, _destRegIdx[0]);
1787251Sgblack@eecs.umich.edu        }
1797251Sgblack@eecs.umich.edu
1807261Sgblack@eecs.umich.edu        return ss.str();
1817251Sgblack@eecs.umich.edu    }
1827251Sgblack@eecs.umich.edu
1837261Sgblack@eecs.umich.edu    const int AlphaFP::alphaToC99RoundingMode[] = {
1847261Sgblack@eecs.umich.edu        FE_TOWARDZERO,	// Chopped
1857251Sgblack@eecs.umich.edu        FE_DOWNWARD,	// Minus_Infinity
1867251Sgblack@eecs.umich.edu        FE_TONEAREST,	// Normal
1877226Sgblack@eecs.umich.edu        FE_UPWARD	// Dynamic in inst, Plus_Infinity in FPCR
1887226Sgblack@eecs.umich.edu    };
1897226Sgblack@eecs.umich.edu
1907232Sgblack@eecs.umich.edu    const char *AlphaFP::roundingModeSuffix[] = { "c", "m", "", "d" };
1917226Sgblack@eecs.umich.edu    // mark invalid trapping modes, but don't fail on them, because
1927226Sgblack@eecs.umich.edu    // you could decode anything on a misspeculated path
1937226Sgblack@eecs.umich.edu    const char *AlphaFP::fpTrappingModeSuffix[] =
1947226Sgblack@eecs.umich.edu        { "", "u", "INVTM2", "INVTM3", "INVTM4", "su", "INVTM6", "sui" };
1957226Sgblack@eecs.umich.edu    const char *AlphaFP::intTrappingModeSuffix[] =
1967232Sgblack@eecs.umich.edu        { "", "v", "INVTM2", "INVTM3", "INVTM4", "sv", "INVTM6", "svi" };
1977226Sgblack@eecs.umich.edu}};
1987226Sgblack@eecs.umich.edu
1997232Sgblack@eecs.umich.edu// FP instruction class execute method template.  Handles non-standard
2007232Sgblack@eecs.umich.edu// rounding modes.
2017226Sgblack@eecs.umich.edudef template FloatingPointExecute {{
2027226Sgblack@eecs.umich.edu    Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc,
2037226Sgblack@eecs.umich.edu                                  Trace::InstRecord *traceData) const
2047226Sgblack@eecs.umich.edu    {
2057226Sgblack@eecs.umich.edu        if (trappingMode != Imprecise && !warnedOnTrapping) {
2067232Sgblack@eecs.umich.edu            warn("%s: non-standard trapping mode not supported",
2077226Sgblack@eecs.umich.edu                 generateDisassembly(0, NULL));
2087226Sgblack@eecs.umich.edu            warnedOnTrapping = true;
2097226Sgblack@eecs.umich.edu        }
2107226Sgblack@eecs.umich.edu
2117226Sgblack@eecs.umich.edu        Fault * fault = NoFault;
2127232Sgblack@eecs.umich.edu
2137226Sgblack@eecs.umich.edu        %(fp_enable_check)s;
2147226Sgblack@eecs.umich.edu        %(op_decl)s;
2157232Sgblack@eecs.umich.edu        %(op_rd)s;
2167232Sgblack@eecs.umich.edu#if USE_FENV
2177226Sgblack@eecs.umich.edu        if (roundingMode == Normal) {
2187226Sgblack@eecs.umich.edu            %(code)s;
2197226Sgblack@eecs.umich.edu        } else {
2207226Sgblack@eecs.umich.edu            fesetround(getC99RoundingMode(xc->readFpcr()));
2217226Sgblack@eecs.umich.edu            %(code)s;
2227226Sgblack@eecs.umich.edu            fesetround(FE_TONEAREST);
2237226Sgblack@eecs.umich.edu        }
2247226Sgblack@eecs.umich.edu#else
2257232Sgblack@eecs.umich.edu        if (roundingMode != Normal && !warnedOnRounding) {
2267226Sgblack@eecs.umich.edu            warn("%s: non-standard rounding mode not supported",
2277226Sgblack@eecs.umich.edu                 generateDisassembly(0, NULL));
2287232Sgblack@eecs.umich.edu            warnedOnRounding = true;
2297226Sgblack@eecs.umich.edu        }
2307226Sgblack@eecs.umich.edu        %(code)s;
2317226Sgblack@eecs.umich.edu#endif
2327226Sgblack@eecs.umich.edu
2337232Sgblack@eecs.umich.edu        if (fault == NoFault) {
2347226Sgblack@eecs.umich.edu            %(op_wb)s;
2357226Sgblack@eecs.umich.edu        }
2367232Sgblack@eecs.umich.edu
2377232Sgblack@eecs.umich.edu        return fault;
2387226Sgblack@eecs.umich.edu    }
2397226Sgblack@eecs.umich.edu}};
2407226Sgblack@eecs.umich.edu
2417226Sgblack@eecs.umich.edu// FP instruction class execute method template where no dynamic
2427226Sgblack@eecs.umich.edu// rounding mode control is needed.  Like BasicExecute, but includes
2437226Sgblack@eecs.umich.edu// check & warning for non-standard trapping mode.
2447226Sgblack@eecs.umich.edudef template FPFixedRoundingExecute {{
2457226Sgblack@eecs.umich.edu    Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc,
2467232Sgblack@eecs.umich.edu                                  Trace::InstRecord *traceData) const
2477226Sgblack@eecs.umich.edu    {
2487226Sgblack@eecs.umich.edu        if (trappingMode != Imprecise && !warnedOnTrapping) {
2497232Sgblack@eecs.umich.edu            warn("%s: non-standard trapping mode not supported",
2507226Sgblack@eecs.umich.edu                 generateDisassembly(0, NULL));
2517226Sgblack@eecs.umich.edu            warnedOnTrapping = true;
2527226Sgblack@eecs.umich.edu        }
2537226Sgblack@eecs.umich.edu
2547232Sgblack@eecs.umich.edu        Fault * fault = NoFault;
2557226Sgblack@eecs.umich.edu
2567226Sgblack@eecs.umich.edu        %(fp_enable_check)s;
2577232Sgblack@eecs.umich.edu        %(op_decl)s;
2587232Sgblack@eecs.umich.edu        %(op_rd)s;
2597226Sgblack@eecs.umich.edu        %(code)s;
2607234Sgblack@eecs.umich.edu
2617234Sgblack@eecs.umich.edu        if (fault == NoFault) {
2627234Sgblack@eecs.umich.edu            %(op_wb)s;
2637234Sgblack@eecs.umich.edu        }
2647234Sgblack@eecs.umich.edu
2657234Sgblack@eecs.umich.edu        return fault;
2667234Sgblack@eecs.umich.edu    }
2677234Sgblack@eecs.umich.edu}};
2687234Sgblack@eecs.umich.edu
2697234Sgblack@eecs.umich.edudef template FloatingPointDecode {{
2707234Sgblack@eecs.umich.edu {
2717234Sgblack@eecs.umich.edu     AlphaStaticInst *i = new %(class_name)s(machInst);
2727234Sgblack@eecs.umich.edu     if (FC == 31) {
2737234Sgblack@eecs.umich.edu         i = makeNop(i);
2747234Sgblack@eecs.umich.edu     }
2757234Sgblack@eecs.umich.edu     return i;
2767234Sgblack@eecs.umich.edu }
2777234Sgblack@eecs.umich.edu}};
2787234Sgblack@eecs.umich.edu
2797234Sgblack@eecs.umich.edu// General format for floating-point operate instructions:
2807234Sgblack@eecs.umich.edu// - Checks trapping and rounding mode flags.  Trapping modes
2817234Sgblack@eecs.umich.edu//   currently unimplemented (will fail).
2827234Sgblack@eecs.umich.edu// - Generates NOP if FC == 31.
2837234Sgblack@eecs.umich.edudef format FloatingPointOperate(code, *opt_args) {{
2847234Sgblack@eecs.umich.edu    iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args)
2857234Sgblack@eecs.umich.edu    decode_block = FloatingPointDecode.subst(iop)
2867234Sgblack@eecs.umich.edu    header_output = BasicDeclare.subst(iop)
2877234Sgblack@eecs.umich.edu    decoder_output = BasicConstructor.subst(iop)
2887234Sgblack@eecs.umich.edu    exec_output = FloatingPointExecute.subst(iop)
2897234Sgblack@eecs.umich.edu}};
2907234Sgblack@eecs.umich.edu
2917234Sgblack@eecs.umich.edu// Special format for cvttq where rounding mode is pre-decoded
2927234Sgblack@eecs.umich.edudef format FPFixedRounding(code, class_suffix, *opt_args) {{
2937234Sgblack@eecs.umich.edu    Name += class_suffix
2947234Sgblack@eecs.umich.edu    iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args)
2957234Sgblack@eecs.umich.edu    decode_block = FloatingPointDecode.subst(iop)
2967234Sgblack@eecs.umich.edu    header_output = BasicDeclare.subst(iop)
2977234Sgblack@eecs.umich.edu    decoder_output = BasicConstructor.subst(iop)
2987234Sgblack@eecs.umich.edu    exec_output = FPFixedRoundingExecute.subst(iop)
2997234Sgblack@eecs.umich.edu}};
3007234Sgblack@eecs.umich.edu
3017234Sgblack@eecs.umich.edu