fp.isa revision 12234
12068SN/A// -*- mode:c++ -*- 22068SN/A 32068SN/A// Copyright (c) 2003-2005 The Regents of The University of Michigan 42068SN/A// All rights reserved. 52068SN/A// 62068SN/A// Redistribution and use in source and binary forms, with or without 72068SN/A// modification, are permitted provided that the following conditions are 82068SN/A// met: redistributions of source code must retain the above copyright 92068SN/A// notice, this list of conditions and the following disclaimer; 102068SN/A// redistributions in binary form must reproduce the above copyright 112068SN/A// notice, this list of conditions and the following disclaimer in the 122068SN/A// documentation and/or other materials provided with the distribution; 132068SN/A// neither the name of the copyright holders nor the names of its 142068SN/A// contributors may be used to endorse or promote products derived from 152068SN/A// this software without specific prior written permission. 162068SN/A// 172068SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 182068SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 192068SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 202068SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 212068SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 222068SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 232068SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 242068SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 252068SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 262068SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 272068SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282665Ssaidi@eecs.umich.edu// 292665Ssaidi@eecs.umich.edu// Authors: Steve Reinhardt 302068SN/A 312649Ssaidi@eecs.umich.edu//////////////////////////////////////////////////////////////////// 322649Ssaidi@eecs.umich.edu// 332649Ssaidi@eecs.umich.edu// Floating-point instructions 342649Ssaidi@eecs.umich.edu// 357799Sgblack@eecs.umich.edu// Note that many FP-type instructions which do not support all the 367799Sgblack@eecs.umich.edu// various rounding & trapping modes use the simpler format 377799Sgblack@eecs.umich.edu// BasicOperateWithNopCheck. 382649Ssaidi@eecs.umich.edu// 392649Ssaidi@eecs.umich.edu 402068SN/Aoutput exec {{ 412068SN/A /// Check "FP enabled" machine status bit. Called when executing any FP 422068SN/A /// instruction in full-system mode. 432090SN/A /// @retval Full-system mode: NoFault if FP is enabled, FenFault 442090SN/A /// if not. Non-full-system mode: always returns NoFault. 4512234Sgabeblack@google.com inline Fault checkFpEnableFault(ExecContext *xc) 462068SN/A { 477799Sgblack@eecs.umich.edu Fault fault = NoFault; // dummy... this ipr access should not fault 488738Sgblack@eecs.umich.edu if (FullSystem && !ICSR_FPE(xc->readMiscReg(IPR_ICSR))) { 4910474Sandreas.hansson@arm.com fault = std::make_shared<FloatEnableFault>(); 502068SN/A } 512068SN/A return fault; 522068SN/A } 5312234Sgabeblack@google.com inline Fault checkVectorEnableFault(ExecContext *xc) { 5412110SRekai.GonzalezAlberquilla@arm.com return std::make_shared<VectorEnableFault>(); 5512110SRekai.GonzalezAlberquilla@arm.com } 562068SN/A}}; 572068SN/A 582068SN/Aoutput header {{ 592068SN/A /** 602068SN/A * Base class for general floating-point instructions. Includes 612068SN/A * support for various Alpha rounding and trapping modes. Only FP 622068SN/A * instructions that require this support are derived from this 632068SN/A * class; the rest derive directly from AlphaStaticInst. 642068SN/A */ 652068SN/A class AlphaFP : public AlphaStaticInst 662068SN/A { 672068SN/A public: 682068SN/A /// Alpha FP rounding modes. 692068SN/A enum RoundingMode { 707799Sgblack@eecs.umich.edu Chopped = 0, ///< round toward zero 712068SN/A Minus_Infinity = 1, ///< round toward minus infinity 727799Sgblack@eecs.umich.edu Normal = 2, ///< round to nearest (default) 737799Sgblack@eecs.umich.edu Dynamic = 3, ///< use FPCR setting (in instruction) 747799Sgblack@eecs.umich.edu Plus_Infinity = 3 ///< round to plus inifinity (in FPCR) 752068SN/A }; 762068SN/A 772068SN/A /// Alpha FP trapping modes. 782068SN/A /// For instructions that produce integer results, the 792068SN/A /// "Underflow Enable" modes really mean "Overflow Enable", and 802068SN/A /// the assembly modifier is V rather than U. 812068SN/A enum TrappingMode { 822068SN/A /// default: nothing enabled 837799Sgblack@eecs.umich.edu Imprecise = 0, ///< no modifier 842068SN/A /// underflow/overflow traps enabled, inexact disabled 857799Sgblack@eecs.umich.edu Underflow_Imprecise = 1, ///< /U or /V 867799Sgblack@eecs.umich.edu Underflow_Precise = 5, ///< /SU or /SV 872068SN/A /// underflow/overflow and inexact traps enabled 882068SN/A Underflow_Inexact_Precise = 7 ///< /SUI or /SVI 892068SN/A }; 902068SN/A 912068SN/A protected: 922068SN/A /// Map Alpha rounding mode to C99 constants from <fenv.h>. 932068SN/A static const int alphaToC99RoundingMode[]; 942068SN/A 952068SN/A /// Map enum RoundingMode values to disassembly suffixes. 962068SN/A static const char *roundingModeSuffix[]; 972068SN/A /// Map enum TrappingMode values to FP disassembly suffixes. 982068SN/A static const char *fpTrappingModeSuffix[]; 992068SN/A /// Map enum TrappingMode values to integer disassembly suffixes. 1002068SN/A static const char *intTrappingModeSuffix[]; 1012068SN/A 1022068SN/A /// This instruction's rounding mode. 1032068SN/A RoundingMode roundingMode; 1042068SN/A /// This instruction's trapping mode. 1052068SN/A TrappingMode trappingMode; 1062068SN/A 1072068SN/A /// Have we warned about this instruction's unsupported 1082068SN/A /// rounding mode (if applicable)? 1092068SN/A mutable bool warnedOnRounding; 1102068SN/A 1112068SN/A /// Have we warned about this instruction's unsupported 1122068SN/A /// trapping mode (if applicable)? 1132068SN/A mutable bool warnedOnTrapping; 1142068SN/A 1152068SN/A /// Constructor 1162227SN/A AlphaFP(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 1172068SN/A : AlphaStaticInst(mnem, _machInst, __opClass), 1182068SN/A roundingMode((enum RoundingMode)FP_ROUNDMODE), 1192068SN/A trappingMode((enum TrappingMode)FP_TRAPMODE), 1202068SN/A warnedOnRounding(false), 1212068SN/A warnedOnTrapping(false) 1222068SN/A { 1232068SN/A } 1242068SN/A 1252068SN/A int getC99RoundingMode(uint64_t fpcr_val) const; 1262068SN/A 1272068SN/A // This differs from the AlphaStaticInst version only in 1282068SN/A // printing suffixes for non-default rounding & trapping modes. 1292068SN/A std::string 1302068SN/A generateDisassembly(Addr pc, const SymbolTable *symtab) const; 1312068SN/A }; 1322068SN/A 1332068SN/A}}; 1342068SN/A 1352068SN/A 1362068SN/Aoutput decoder {{ 1372068SN/A int 1382068SN/A AlphaFP::getC99RoundingMode(uint64_t fpcr_val) const 1392068SN/A { 1402068SN/A if (roundingMode == Dynamic) { 1412068SN/A return alphaToC99RoundingMode[bits(fpcr_val, 59, 58)]; 1422068SN/A } 1432068SN/A else { 1442068SN/A return alphaToC99RoundingMode[roundingMode]; 1452068SN/A } 1462068SN/A } 1472068SN/A 1482068SN/A std::string 1492068SN/A AlphaFP::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1502068SN/A { 1512068SN/A std::string mnem_str(mnemonic); 1522068SN/A 1532068SN/A#ifndef SS_COMPATIBLE_DISASSEMBLY 1542068SN/A std::string suffix(""); 15512106SRekai.GonzalezAlberquilla@arm.com suffix += ((_destRegIdx[0].isFloatReg()) 1562068SN/A ? fpTrappingModeSuffix[trappingMode] 1572068SN/A : intTrappingModeSuffix[trappingMode]); 1582068SN/A suffix += roundingModeSuffix[roundingMode]; 1592068SN/A 1602068SN/A if (suffix != "") { 1612068SN/A mnem_str = csprintf("%s/%s", mnemonic, suffix); 1622068SN/A } 1632068SN/A#endif 1642068SN/A 1652068SN/A std::stringstream ss; 1662068SN/A ccprintf(ss, "%-10s ", mnem_str.c_str()); 1672068SN/A 1682068SN/A // just print the first two source regs... if there's 1692068SN/A // a third one, it's a read-modify-write dest (Rc), 1702068SN/A // e.g. for CMOVxx 1712068SN/A if (_numSrcRegs > 0) { 1722068SN/A printReg(ss, _srcRegIdx[0]); 1732068SN/A } 1742068SN/A if (_numSrcRegs > 1) { 1752068SN/A ss << ","; 1762068SN/A printReg(ss, _srcRegIdx[1]); 1772068SN/A } 1782068SN/A 1792068SN/A // just print the first dest... if there's a second one, 1802068SN/A // it's generally implicit 1812068SN/A if (_numDestRegs > 0) { 1822068SN/A if (_numSrcRegs > 0) 1832068SN/A ss << ","; 1842068SN/A printReg(ss, _destRegIdx[0]); 1852068SN/A } 1862068SN/A 1872068SN/A return ss.str(); 1882068SN/A } 1892068SN/A 1902068SN/A const int AlphaFP::alphaToC99RoundingMode[] = { 1917799Sgblack@eecs.umich.edu M5_FE_TOWARDZERO, // Chopped 1927799Sgblack@eecs.umich.edu M5_FE_DOWNWARD, // Minus_Infinity 1937799Sgblack@eecs.umich.edu M5_FE_TONEAREST, // Normal 1947799Sgblack@eecs.umich.edu M5_FE_UPWARD // Dynamic in inst, Plus_Infinity in FPCR 1952068SN/A }; 1962068SN/A 1972068SN/A const char *AlphaFP::roundingModeSuffix[] = { "c", "m", "", "d" }; 1982068SN/A // mark invalid trapping modes, but don't fail on them, because 1992068SN/A // you could decode anything on a misspeculated path 2002068SN/A const char *AlphaFP::fpTrappingModeSuffix[] = 2012068SN/A { "", "u", "INVTM2", "INVTM3", "INVTM4", "su", "INVTM6", "sui" }; 2022068SN/A const char *AlphaFP::intTrappingModeSuffix[] = 2032068SN/A { "", "v", "INVTM2", "INVTM3", "INVTM4", "sv", "INVTM6", "svi" }; 2042068SN/A}}; 2052068SN/A 2062068SN/A// FP instruction class execute method template. Handles non-standard 2072068SN/A// rounding modes. 2082068SN/Adef template FloatingPointExecute {{ 20912234Sgabeblack@google.com Fault %(class_name)s::execute(ExecContext *xc, 2102068SN/A Trace::InstRecord *traceData) const 2112068SN/A { 2122068SN/A if (trappingMode != Imprecise && !warnedOnTrapping) { 2132068SN/A warn("%s: non-standard trapping mode not supported", 2142068SN/A generateDisassembly(0, NULL)); 2152068SN/A warnedOnTrapping = true; 2162068SN/A } 2172068SN/A 2182132SN/A Fault fault = NoFault; 2192068SN/A 2202068SN/A %(fp_enable_check)s; 2212068SN/A %(op_decl)s; 2222068SN/A %(op_rd)s; 2232068SN/A#if USE_FENV 2242068SN/A if (roundingMode == Normal) { 2252068SN/A %(code)s; 2262068SN/A } else { 2274394Ssaidi@eecs.umich.edu m5_fesetround(getC99RoundingMode( 2287783SGiacomo.Gabrielli@arm.com xc->readMiscReg(MISCREG_FPCR))); 2292068SN/A %(code)s; 2304394Ssaidi@eecs.umich.edu m5_fesetround(M5_FE_TONEAREST); 2312068SN/A } 2322068SN/A#else 2332068SN/A if (roundingMode != Normal && !warnedOnRounding) { 2342068SN/A warn("%s: non-standard rounding mode not supported", 2352068SN/A generateDisassembly(0, NULL)); 2362068SN/A warnedOnRounding = true; 2372068SN/A } 2382068SN/A %(code)s; 2392068SN/A#endif 2402068SN/A 2412090SN/A if (fault == NoFault) { 2422068SN/A %(op_wb)s; 2432068SN/A } 2442068SN/A 2452068SN/A return fault; 2462068SN/A } 2472068SN/A}}; 2482068SN/A 2492068SN/A// FP instruction class execute method template where no dynamic 2502068SN/A// rounding mode control is needed. Like BasicExecute, but includes 2512068SN/A// check & warning for non-standard trapping mode. 2522068SN/Adef template FPFixedRoundingExecute {{ 25312234Sgabeblack@google.com Fault %(class_name)s::execute(ExecContext *xc, 2542068SN/A Trace::InstRecord *traceData) const 2552068SN/A { 2562068SN/A if (trappingMode != Imprecise && !warnedOnTrapping) { 2572068SN/A warn("%s: non-standard trapping mode not supported", 2582068SN/A generateDisassembly(0, NULL)); 2592068SN/A warnedOnTrapping = true; 2602068SN/A } 2612068SN/A 2622132SN/A Fault fault = NoFault; 2632068SN/A 2642068SN/A %(fp_enable_check)s; 2652068SN/A %(op_decl)s; 2662068SN/A %(op_rd)s; 2672068SN/A %(code)s; 2682068SN/A 2692090SN/A if (fault == NoFault) { 2702068SN/A %(op_wb)s; 2712068SN/A } 2722068SN/A 2732068SN/A return fault; 2742068SN/A } 2752068SN/A}}; 2762068SN/A 2772068SN/Adef template FloatingPointDecode {{ 2782068SN/A { 2792068SN/A AlphaStaticInst *i = new %(class_name)s(machInst); 2802068SN/A if (FC == 31) { 2812068SN/A i = makeNop(i); 2822068SN/A } 2832068SN/A return i; 2842068SN/A } 2852068SN/A}}; 2862068SN/A 2872068SN/A// General format for floating-point operate instructions: 2882068SN/A// - Checks trapping and rounding mode flags. Trapping modes 2892068SN/A// currently unimplemented (will fail). 2902068SN/A// - Generates NOP if FC == 31. 2912068SN/Adef format FloatingPointOperate(code, *opt_args) {{ 2923953Sstever@eecs.umich.edu iop = InstObjParams(name, Name, 'AlphaFP', code, opt_args) 2932068SN/A decode_block = FloatingPointDecode.subst(iop) 2942068SN/A header_output = BasicDeclare.subst(iop) 2952068SN/A decoder_output = BasicConstructor.subst(iop) 2962068SN/A exec_output = FloatingPointExecute.subst(iop) 2972068SN/A}}; 2982068SN/A 2992068SN/A// Special format for cvttq where rounding mode is pre-decoded 3002068SN/Adef format FPFixedRounding(code, class_suffix, *opt_args) {{ 3012068SN/A Name += class_suffix 3023953Sstever@eecs.umich.edu iop = InstObjParams(name, Name, 'AlphaFP', code, opt_args) 3032068SN/A decode_block = FloatingPointDecode.subst(iop) 3042068SN/A header_output = BasicDeclare.subst(iop) 3052068SN/A decoder_output = BasicConstructor.subst(iop) 3062068SN/A exec_output = FPFixedRoundingExecute.subst(iop) 3072068SN/A}}; 3082068SN/A 309