fp.isa revision 10474
1// -*- mode:c++ -*- 2 3// Copyright (c) 2003-2005 The Regents of The University of Michigan 4// All rights reserved. 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions are 8// met: redistributions of source code must retain the above copyright 9// notice, this list of conditions and the following disclaimer; 10// redistributions in binary form must reproduce the above copyright 11// notice, this list of conditions and the following disclaimer in the 12// documentation and/or other materials provided with the distribution; 13// neither the name of the copyright holders nor the names of its 14// contributors may be used to endorse or promote products derived from 15// this software without specific prior written permission. 16// 17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28// 29// Authors: Steve Reinhardt 30 31//////////////////////////////////////////////////////////////////// 32// 33// Floating-point instructions 34// 35// Note that many FP-type instructions which do not support all the 36// various rounding & trapping modes use the simpler format 37// BasicOperateWithNopCheck. 38// 39 40output exec {{ 41 /// Check "FP enabled" machine status bit. Called when executing any FP 42 /// instruction in full-system mode. 43 /// @retval Full-system mode: NoFault if FP is enabled, FenFault 44 /// if not. Non-full-system mode: always returns NoFault. 45 inline Fault checkFpEnableFault(CPU_EXEC_CONTEXT *xc) 46 { 47 Fault fault = NoFault; // dummy... this ipr access should not fault 48 if (FullSystem && !ICSR_FPE(xc->readMiscReg(IPR_ICSR))) { 49 fault = std::make_shared<FloatEnableFault>(); 50 } 51 return fault; 52 } 53}}; 54 55output header {{ 56 /** 57 * Base class for general floating-point instructions. Includes 58 * support for various Alpha rounding and trapping modes. Only FP 59 * instructions that require this support are derived from this 60 * class; the rest derive directly from AlphaStaticInst. 61 */ 62 class AlphaFP : public AlphaStaticInst 63 { 64 public: 65 /// Alpha FP rounding modes. 66 enum RoundingMode { 67 Chopped = 0, ///< round toward zero 68 Minus_Infinity = 1, ///< round toward minus infinity 69 Normal = 2, ///< round to nearest (default) 70 Dynamic = 3, ///< use FPCR setting (in instruction) 71 Plus_Infinity = 3 ///< round to plus inifinity (in FPCR) 72 }; 73 74 /// Alpha FP trapping modes. 75 /// For instructions that produce integer results, the 76 /// "Underflow Enable" modes really mean "Overflow Enable", and 77 /// the assembly modifier is V rather than U. 78 enum TrappingMode { 79 /// default: nothing enabled 80 Imprecise = 0, ///< no modifier 81 /// underflow/overflow traps enabled, inexact disabled 82 Underflow_Imprecise = 1, ///< /U or /V 83 Underflow_Precise = 5, ///< /SU or /SV 84 /// underflow/overflow and inexact traps enabled 85 Underflow_Inexact_Precise = 7 ///< /SUI or /SVI 86 }; 87 88 protected: 89 /// Map Alpha rounding mode to C99 constants from <fenv.h>. 90 static const int alphaToC99RoundingMode[]; 91 92 /// Map enum RoundingMode values to disassembly suffixes. 93 static const char *roundingModeSuffix[]; 94 /// Map enum TrappingMode values to FP disassembly suffixes. 95 static const char *fpTrappingModeSuffix[]; 96 /// Map enum TrappingMode values to integer disassembly suffixes. 97 static const char *intTrappingModeSuffix[]; 98 99 /// This instruction's rounding mode. 100 RoundingMode roundingMode; 101 /// This instruction's trapping mode. 102 TrappingMode trappingMode; 103 104 /// Have we warned about this instruction's unsupported 105 /// rounding mode (if applicable)? 106 mutable bool warnedOnRounding; 107 108 /// Have we warned about this instruction's unsupported 109 /// trapping mode (if applicable)? 110 mutable bool warnedOnTrapping; 111 112 /// Constructor 113 AlphaFP(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 114 : AlphaStaticInst(mnem, _machInst, __opClass), 115 roundingMode((enum RoundingMode)FP_ROUNDMODE), 116 trappingMode((enum TrappingMode)FP_TRAPMODE), 117 warnedOnRounding(false), 118 warnedOnTrapping(false) 119 { 120 } 121 122 int getC99RoundingMode(uint64_t fpcr_val) const; 123 124 // This differs from the AlphaStaticInst version only in 125 // printing suffixes for non-default rounding & trapping modes. 126 std::string 127 generateDisassembly(Addr pc, const SymbolTable *symtab) const; 128 }; 129 130}}; 131 132 133output decoder {{ 134 int 135 AlphaFP::getC99RoundingMode(uint64_t fpcr_val) const 136 { 137 if (roundingMode == Dynamic) { 138 return alphaToC99RoundingMode[bits(fpcr_val, 59, 58)]; 139 } 140 else { 141 return alphaToC99RoundingMode[roundingMode]; 142 } 143 } 144 145 std::string 146 AlphaFP::generateDisassembly(Addr pc, const SymbolTable *symtab) const 147 { 148 std::string mnem_str(mnemonic); 149 150#ifndef SS_COMPATIBLE_DISASSEMBLY 151 std::string suffix(""); 152 suffix += ((_destRegIdx[0] >= FP_Reg_Base) 153 ? fpTrappingModeSuffix[trappingMode] 154 : intTrappingModeSuffix[trappingMode]); 155 suffix += roundingModeSuffix[roundingMode]; 156 157 if (suffix != "") { 158 mnem_str = csprintf("%s/%s", mnemonic, suffix); 159 } 160#endif 161 162 std::stringstream ss; 163 ccprintf(ss, "%-10s ", mnem_str.c_str()); 164 165 // just print the first two source regs... if there's 166 // a third one, it's a read-modify-write dest (Rc), 167 // e.g. for CMOVxx 168 if (_numSrcRegs > 0) { 169 printReg(ss, _srcRegIdx[0]); 170 } 171 if (_numSrcRegs > 1) { 172 ss << ","; 173 printReg(ss, _srcRegIdx[1]); 174 } 175 176 // just print the first dest... if there's a second one, 177 // it's generally implicit 178 if (_numDestRegs > 0) { 179 if (_numSrcRegs > 0) 180 ss << ","; 181 printReg(ss, _destRegIdx[0]); 182 } 183 184 return ss.str(); 185 } 186 187 const int AlphaFP::alphaToC99RoundingMode[] = { 188 M5_FE_TOWARDZERO, // Chopped 189 M5_FE_DOWNWARD, // Minus_Infinity 190 M5_FE_TONEAREST, // Normal 191 M5_FE_UPWARD // Dynamic in inst, Plus_Infinity in FPCR 192 }; 193 194 const char *AlphaFP::roundingModeSuffix[] = { "c", "m", "", "d" }; 195 // mark invalid trapping modes, but don't fail on them, because 196 // you could decode anything on a misspeculated path 197 const char *AlphaFP::fpTrappingModeSuffix[] = 198 { "", "u", "INVTM2", "INVTM3", "INVTM4", "su", "INVTM6", "sui" }; 199 const char *AlphaFP::intTrappingModeSuffix[] = 200 { "", "v", "INVTM2", "INVTM3", "INVTM4", "sv", "INVTM6", "svi" }; 201}}; 202 203// FP instruction class execute method template. Handles non-standard 204// rounding modes. 205def template FloatingPointExecute {{ 206 Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc, 207 Trace::InstRecord *traceData) const 208 { 209 if (trappingMode != Imprecise && !warnedOnTrapping) { 210 warn("%s: non-standard trapping mode not supported", 211 generateDisassembly(0, NULL)); 212 warnedOnTrapping = true; 213 } 214 215 Fault fault = NoFault; 216 217 %(fp_enable_check)s; 218 %(op_decl)s; 219 %(op_rd)s; 220#if USE_FENV 221 if (roundingMode == Normal) { 222 %(code)s; 223 } else { 224 m5_fesetround(getC99RoundingMode( 225 xc->readMiscReg(MISCREG_FPCR))); 226 %(code)s; 227 m5_fesetround(M5_FE_TONEAREST); 228 } 229#else 230 if (roundingMode != Normal && !warnedOnRounding) { 231 warn("%s: non-standard rounding mode not supported", 232 generateDisassembly(0, NULL)); 233 warnedOnRounding = true; 234 } 235 %(code)s; 236#endif 237 238 if (fault == NoFault) { 239 %(op_wb)s; 240 } 241 242 return fault; 243 } 244}}; 245 246// FP instruction class execute method template where no dynamic 247// rounding mode control is needed. Like BasicExecute, but includes 248// check & warning for non-standard trapping mode. 249def template FPFixedRoundingExecute {{ 250 Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc, 251 Trace::InstRecord *traceData) const 252 { 253 if (trappingMode != Imprecise && !warnedOnTrapping) { 254 warn("%s: non-standard trapping mode not supported", 255 generateDisassembly(0, NULL)); 256 warnedOnTrapping = true; 257 } 258 259 Fault fault = NoFault; 260 261 %(fp_enable_check)s; 262 %(op_decl)s; 263 %(op_rd)s; 264 %(code)s; 265 266 if (fault == NoFault) { 267 %(op_wb)s; 268 } 269 270 return fault; 271 } 272}}; 273 274def template FloatingPointDecode {{ 275 { 276 AlphaStaticInst *i = new %(class_name)s(machInst); 277 if (FC == 31) { 278 i = makeNop(i); 279 } 280 return i; 281 } 282}}; 283 284// General format for floating-point operate instructions: 285// - Checks trapping and rounding mode flags. Trapping modes 286// currently unimplemented (will fail). 287// - Generates NOP if FC == 31. 288def format FloatingPointOperate(code, *opt_args) {{ 289 iop = InstObjParams(name, Name, 'AlphaFP', code, opt_args) 290 decode_block = FloatingPointDecode.subst(iop) 291 header_output = BasicDeclare.subst(iop) 292 decoder_output = BasicConstructor.subst(iop) 293 exec_output = FloatingPointExecute.subst(iop) 294}}; 295 296// Special format for cvttq where rounding mode is pre-decoded 297def format FPFixedRounding(code, class_suffix, *opt_args) {{ 298 Name += class_suffix 299 iop = InstObjParams(name, Name, 'AlphaFP', code, opt_args) 300 decode_block = FloatingPointDecode.subst(iop) 301 header_output = BasicDeclare.subst(iop) 302 decoder_output = BasicConstructor.subst(iop) 303 exec_output = FPFixedRoundingExecute.subst(iop) 304}}; 305 306