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