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