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