vfp.hh revision 7396
17375Sgblack@eecs.umich.edu/* 27375Sgblack@eecs.umich.edu * Copyright (c) 2010 ARM Limited 37375Sgblack@eecs.umich.edu * All rights reserved 47375Sgblack@eecs.umich.edu * 57375Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 67375Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 77375Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 87375Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 97375Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 107375Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 117375Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 127375Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 137375Sgblack@eecs.umich.edu * 147375Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 157375Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 167375Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 177375Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 187375Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 197375Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 207375Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 217375Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 227375Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 237375Sgblack@eecs.umich.edu * this software without specific prior written permission. 247375Sgblack@eecs.umich.edu * 257375Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 267375Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 277375Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 287375Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 297375Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 307375Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 317375Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 327375Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 337375Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 347375Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 357375Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 367375Sgblack@eecs.umich.edu * 377375Sgblack@eecs.umich.edu * Authors: Gabe Black 387375Sgblack@eecs.umich.edu */ 397375Sgblack@eecs.umich.edu 407375Sgblack@eecs.umich.edu#ifndef __ARCH_ARM_INSTS_VFP_HH__ 417375Sgblack@eecs.umich.edu#define __ARCH_ARM_INSTS_VFP_HH__ 427375Sgblack@eecs.umich.edu 437375Sgblack@eecs.umich.edu#include "arch/arm/insts/misc.hh" 447378Sgblack@eecs.umich.edu#include "arch/arm/miscregs.hh" 457378Sgblack@eecs.umich.edu#include <fenv.h> 467382Sgblack@eecs.umich.edu#include <cmath> 477375Sgblack@eecs.umich.edu 487384Sgblack@eecs.umich.edunamespace ArmISA 497384Sgblack@eecs.umich.edu{ 507384Sgblack@eecs.umich.edu 517375Sgblack@eecs.umich.eduenum VfpMicroMode { 527375Sgblack@eecs.umich.edu VfpNotAMicroop, 537375Sgblack@eecs.umich.edu VfpMicroop, 547375Sgblack@eecs.umich.edu VfpFirstMicroop, 557375Sgblack@eecs.umich.edu VfpLastMicroop 567375Sgblack@eecs.umich.edu}; 577375Sgblack@eecs.umich.edu 587375Sgblack@eecs.umich.edutemplate<class T> 597375Sgblack@eecs.umich.edustatic inline void 607375Sgblack@eecs.umich.edusetVfpMicroFlags(VfpMicroMode mode, T &flags) 617375Sgblack@eecs.umich.edu{ 627375Sgblack@eecs.umich.edu switch (mode) { 637375Sgblack@eecs.umich.edu case VfpMicroop: 647375Sgblack@eecs.umich.edu flags[StaticInst::IsMicroop] = true; 657375Sgblack@eecs.umich.edu break; 667375Sgblack@eecs.umich.edu case VfpFirstMicroop: 677375Sgblack@eecs.umich.edu flags[StaticInst::IsMicroop] = 687375Sgblack@eecs.umich.edu flags[StaticInst::IsFirstMicroop] = true; 697375Sgblack@eecs.umich.edu break; 707375Sgblack@eecs.umich.edu case VfpLastMicroop: 717375Sgblack@eecs.umich.edu flags[StaticInst::IsMicroop] = 727375Sgblack@eecs.umich.edu flags[StaticInst::IsLastMicroop] = true; 737375Sgblack@eecs.umich.edu break; 747375Sgblack@eecs.umich.edu case VfpNotAMicroop: 757375Sgblack@eecs.umich.edu break; 767375Sgblack@eecs.umich.edu } 777376Sgblack@eecs.umich.edu if (mode == VfpMicroop || mode == VfpFirstMicroop) { 787376Sgblack@eecs.umich.edu flags[StaticInst::IsDelayedCommit] = true; 797376Sgblack@eecs.umich.edu } 807375Sgblack@eecs.umich.edu} 817375Sgblack@eecs.umich.edu 827378Sgblack@eecs.umich.eduenum FeExceptionBit 837378Sgblack@eecs.umich.edu{ 847378Sgblack@eecs.umich.edu FeDivByZero = FE_DIVBYZERO, 857378Sgblack@eecs.umich.edu FeInexact = FE_INEXACT, 867378Sgblack@eecs.umich.edu FeInvalid = FE_INVALID, 877378Sgblack@eecs.umich.edu FeOverflow = FE_OVERFLOW, 887378Sgblack@eecs.umich.edu FeUnderflow = FE_UNDERFLOW, 897378Sgblack@eecs.umich.edu FeAllExceptions = FE_ALL_EXCEPT 907378Sgblack@eecs.umich.edu}; 917378Sgblack@eecs.umich.edu 927378Sgblack@eecs.umich.eduenum FeRoundingMode 937378Sgblack@eecs.umich.edu{ 947378Sgblack@eecs.umich.edu FeRoundDown = FE_DOWNWARD, 957378Sgblack@eecs.umich.edu FeRoundNearest = FE_TONEAREST, 967378Sgblack@eecs.umich.edu FeRoundZero = FE_TOWARDZERO, 977378Sgblack@eecs.umich.edu FeRoundUpward = FE_UPWARD 987378Sgblack@eecs.umich.edu}; 997378Sgblack@eecs.umich.edu 1007378Sgblack@eecs.umich.eduenum VfpRoundingMode 1017378Sgblack@eecs.umich.edu{ 1027378Sgblack@eecs.umich.edu VfpRoundNearest = 0, 1037378Sgblack@eecs.umich.edu VfpRoundUpward = 1, 1047378Sgblack@eecs.umich.edu VfpRoundDown = 2, 1057378Sgblack@eecs.umich.edu VfpRoundZero = 3 1067378Sgblack@eecs.umich.edu}; 1077378Sgblack@eecs.umich.edu 1087382Sgblack@eecs.umich.edutemplate <class fpType> 1097382Sgblack@eecs.umich.edustatic inline void 1107382Sgblack@eecs.umich.eduvfpFlushToZero(uint32_t &_fpscr, fpType &op) 1117382Sgblack@eecs.umich.edu{ 1127382Sgblack@eecs.umich.edu FPSCR fpscr = _fpscr; 1137396Sgblack@eecs.umich.edu fpType junk = 0.0; 1147382Sgblack@eecs.umich.edu if (fpscr.fz == 1 && (std::fpclassify(op) == FP_SUBNORMAL)) { 1157382Sgblack@eecs.umich.edu fpscr.idc = 1; 1167396Sgblack@eecs.umich.edu uint64_t bitMask = ULL(0x1) << (sizeof(fpType) * 8 - 1); 1177396Sgblack@eecs.umich.edu op = bitsToFp(fpToBits(op) & bitMask, junk); 1187382Sgblack@eecs.umich.edu } 1197382Sgblack@eecs.umich.edu _fpscr = fpscr; 1207382Sgblack@eecs.umich.edu} 1217382Sgblack@eecs.umich.edu 1227382Sgblack@eecs.umich.edutemplate <class fpType> 1237382Sgblack@eecs.umich.edustatic inline void 1247382Sgblack@eecs.umich.eduvfpFlushToZero(uint32_t &fpscr, fpType &op1, fpType &op2) 1257382Sgblack@eecs.umich.edu{ 1267382Sgblack@eecs.umich.edu vfpFlushToZero(fpscr, op1); 1277382Sgblack@eecs.umich.edu vfpFlushToZero(fpscr, op2); 1287382Sgblack@eecs.umich.edu} 1297382Sgblack@eecs.umich.edu 1307396Sgblack@eecs.umich.edutemplate <class fpType> 1317396Sgblack@eecs.umich.edustatic inline bool 1327396Sgblack@eecs.umich.eduflushToZero(fpType &op) 1337396Sgblack@eecs.umich.edu{ 1347396Sgblack@eecs.umich.edu fpType junk = 0.0; 1357396Sgblack@eecs.umich.edu if (std::fpclassify(op) == FP_SUBNORMAL) { 1367396Sgblack@eecs.umich.edu uint64_t bitMask = ULL(0x1) << (sizeof(fpType) * 8 - 1); 1377396Sgblack@eecs.umich.edu op = bitsToFp(fpToBits(op) & bitMask, junk); 1387396Sgblack@eecs.umich.edu return true; 1397396Sgblack@eecs.umich.edu } 1407396Sgblack@eecs.umich.edu return false; 1417396Sgblack@eecs.umich.edu} 1427396Sgblack@eecs.umich.edu 1437396Sgblack@eecs.umich.edutemplate <class fpType> 1447396Sgblack@eecs.umich.edustatic inline bool 1457396Sgblack@eecs.umich.eduflushToZero(fpType &op1, fpType &op2) 1467396Sgblack@eecs.umich.edu{ 1477396Sgblack@eecs.umich.edu bool flush1 = flushToZero(op1); 1487396Sgblack@eecs.umich.edu bool flush2 = flushToZero(op2); 1497396Sgblack@eecs.umich.edu return flush1 || flush2; 1507396Sgblack@eecs.umich.edu} 1517396Sgblack@eecs.umich.edu 1527384Sgblack@eecs.umich.edustatic inline uint32_t 1537384Sgblack@eecs.umich.edufpToBits(float fp) 1547384Sgblack@eecs.umich.edu{ 1557384Sgblack@eecs.umich.edu union 1567384Sgblack@eecs.umich.edu { 1577384Sgblack@eecs.umich.edu float fp; 1587384Sgblack@eecs.umich.edu uint32_t bits; 1597384Sgblack@eecs.umich.edu } val; 1607384Sgblack@eecs.umich.edu val.fp = fp; 1617384Sgblack@eecs.umich.edu return val.bits; 1627384Sgblack@eecs.umich.edu} 1637384Sgblack@eecs.umich.edu 1647384Sgblack@eecs.umich.edustatic inline uint64_t 1657384Sgblack@eecs.umich.edufpToBits(double fp) 1667384Sgblack@eecs.umich.edu{ 1677384Sgblack@eecs.umich.edu union 1687384Sgblack@eecs.umich.edu { 1697384Sgblack@eecs.umich.edu double fp; 1707384Sgblack@eecs.umich.edu uint64_t bits; 1717384Sgblack@eecs.umich.edu } val; 1727384Sgblack@eecs.umich.edu val.fp = fp; 1737384Sgblack@eecs.umich.edu return val.bits; 1747384Sgblack@eecs.umich.edu} 1757384Sgblack@eecs.umich.edu 1767384Sgblack@eecs.umich.edustatic inline float 1777384Sgblack@eecs.umich.edubitsToFp(uint64_t bits, float junk) 1787384Sgblack@eecs.umich.edu{ 1797384Sgblack@eecs.umich.edu union 1807384Sgblack@eecs.umich.edu { 1817384Sgblack@eecs.umich.edu float fp; 1827384Sgblack@eecs.umich.edu uint32_t bits; 1837384Sgblack@eecs.umich.edu } val; 1847384Sgblack@eecs.umich.edu val.bits = bits; 1857384Sgblack@eecs.umich.edu return val.fp; 1867384Sgblack@eecs.umich.edu} 1877384Sgblack@eecs.umich.edu 1887384Sgblack@eecs.umich.edustatic inline double 1897384Sgblack@eecs.umich.edubitsToFp(uint64_t bits, double junk) 1907384Sgblack@eecs.umich.edu{ 1917384Sgblack@eecs.umich.edu union 1927384Sgblack@eecs.umich.edu { 1937384Sgblack@eecs.umich.edu double fp; 1947384Sgblack@eecs.umich.edu uint64_t bits; 1957384Sgblack@eecs.umich.edu } val; 1967384Sgblack@eecs.umich.edu val.bits = bits; 1977384Sgblack@eecs.umich.edu return val.fp; 1987384Sgblack@eecs.umich.edu} 1997384Sgblack@eecs.umich.edu 2007396Sgblack@eecs.umich.edutypedef int VfpSavedState; 2017396Sgblack@eecs.umich.edu 2027396Sgblack@eecs.umich.edustatic inline VfpSavedState 2037396Sgblack@eecs.umich.eduprepVfpFpscr(FPSCR fpscr) 2047396Sgblack@eecs.umich.edu{ 2057396Sgblack@eecs.umich.edu int roundingMode = fegetround(); 2067396Sgblack@eecs.umich.edu feclearexcept(FeAllExceptions); 2077396Sgblack@eecs.umich.edu switch (fpscr.rMode) { 2087396Sgblack@eecs.umich.edu case VfpRoundNearest: 2097396Sgblack@eecs.umich.edu fesetround(FeRoundNearest); 2107396Sgblack@eecs.umich.edu break; 2117396Sgblack@eecs.umich.edu case VfpRoundUpward: 2127396Sgblack@eecs.umich.edu fesetround(FeRoundUpward); 2137396Sgblack@eecs.umich.edu break; 2147396Sgblack@eecs.umich.edu case VfpRoundDown: 2157396Sgblack@eecs.umich.edu fesetround(FeRoundDown); 2167396Sgblack@eecs.umich.edu break; 2177396Sgblack@eecs.umich.edu case VfpRoundZero: 2187396Sgblack@eecs.umich.edu fesetround(FeRoundZero); 2197396Sgblack@eecs.umich.edu break; 2207396Sgblack@eecs.umich.edu } 2217396Sgblack@eecs.umich.edu return roundingMode; 2227396Sgblack@eecs.umich.edu} 2237396Sgblack@eecs.umich.edu 2247396Sgblack@eecs.umich.edustatic inline VfpSavedState 2257396Sgblack@eecs.umich.eduprepFpState(uint32_t rMode) 2267396Sgblack@eecs.umich.edu{ 2277396Sgblack@eecs.umich.edu int roundingMode = fegetround(); 2287396Sgblack@eecs.umich.edu feclearexcept(FeAllExceptions); 2297396Sgblack@eecs.umich.edu switch (rMode) { 2307396Sgblack@eecs.umich.edu case VfpRoundNearest: 2317396Sgblack@eecs.umich.edu fesetround(FeRoundNearest); 2327396Sgblack@eecs.umich.edu break; 2337396Sgblack@eecs.umich.edu case VfpRoundUpward: 2347396Sgblack@eecs.umich.edu fesetround(FeRoundUpward); 2357396Sgblack@eecs.umich.edu break; 2367396Sgblack@eecs.umich.edu case VfpRoundDown: 2377396Sgblack@eecs.umich.edu fesetround(FeRoundDown); 2387396Sgblack@eecs.umich.edu break; 2397396Sgblack@eecs.umich.edu case VfpRoundZero: 2407396Sgblack@eecs.umich.edu fesetround(FeRoundZero); 2417396Sgblack@eecs.umich.edu break; 2427396Sgblack@eecs.umich.edu } 2437396Sgblack@eecs.umich.edu return roundingMode; 2447396Sgblack@eecs.umich.edu} 2457396Sgblack@eecs.umich.edu 2467396Sgblack@eecs.umich.edustatic inline FPSCR 2477396Sgblack@eecs.umich.edusetVfpFpscr(FPSCR fpscr, VfpSavedState state) 2487396Sgblack@eecs.umich.edu{ 2497396Sgblack@eecs.umich.edu int exceptions = fetestexcept(FeAllExceptions); 2507396Sgblack@eecs.umich.edu if (exceptions & FeInvalid) { 2517396Sgblack@eecs.umich.edu fpscr.ioc = 1; 2527396Sgblack@eecs.umich.edu } 2537396Sgblack@eecs.umich.edu if (exceptions & FeDivByZero) { 2547396Sgblack@eecs.umich.edu fpscr.dzc = 1; 2557396Sgblack@eecs.umich.edu } 2567396Sgblack@eecs.umich.edu if (exceptions & FeOverflow) { 2577396Sgblack@eecs.umich.edu fpscr.ofc = 1; 2587396Sgblack@eecs.umich.edu } 2597396Sgblack@eecs.umich.edu if (exceptions & FeUnderflow) { 2607396Sgblack@eecs.umich.edu fpscr.ufc = 1; 2617396Sgblack@eecs.umich.edu } 2627396Sgblack@eecs.umich.edu if (exceptions & FeInexact) { 2637396Sgblack@eecs.umich.edu fpscr.ixc = 1; 2647396Sgblack@eecs.umich.edu } 2657396Sgblack@eecs.umich.edu fesetround(state); 2667396Sgblack@eecs.umich.edu return fpscr; 2677396Sgblack@eecs.umich.edu} 2687396Sgblack@eecs.umich.edu 2697396Sgblack@eecs.umich.edustatic inline void 2707396Sgblack@eecs.umich.edufinishVfp(FPSCR &fpscr, VfpSavedState state) 2717396Sgblack@eecs.umich.edu{ 2727396Sgblack@eecs.umich.edu int exceptions = fetestexcept(FeAllExceptions); 2737396Sgblack@eecs.umich.edu bool underflow = false; 2747396Sgblack@eecs.umich.edu if (exceptions & FeInvalid) { 2757396Sgblack@eecs.umich.edu fpscr.ioc = 1; 2767396Sgblack@eecs.umich.edu } 2777396Sgblack@eecs.umich.edu if (exceptions & FeDivByZero) { 2787396Sgblack@eecs.umich.edu fpscr.dzc = 1; 2797396Sgblack@eecs.umich.edu } 2807396Sgblack@eecs.umich.edu if (exceptions & FeOverflow) { 2817396Sgblack@eecs.umich.edu fpscr.ofc = 1; 2827396Sgblack@eecs.umich.edu } 2837396Sgblack@eecs.umich.edu if (exceptions & FeUnderflow) { 2847396Sgblack@eecs.umich.edu underflow = true; 2857396Sgblack@eecs.umich.edu fpscr.ufc = 1; 2867396Sgblack@eecs.umich.edu } 2877396Sgblack@eecs.umich.edu if ((exceptions & FeInexact) && !(underflow && fpscr.fz)) { 2887396Sgblack@eecs.umich.edu fpscr.ixc = 1; 2897396Sgblack@eecs.umich.edu } 2907396Sgblack@eecs.umich.edu fesetround(state); 2917396Sgblack@eecs.umich.edu} 2927396Sgblack@eecs.umich.edu 2937384Sgblack@eecs.umich.edutemplate <class fpType> 2947384Sgblack@eecs.umich.edustatic inline fpType 2957386Sgblack@eecs.umich.edufixDest(FPSCR fpscr, fpType val, fpType op1) 2967386Sgblack@eecs.umich.edu{ 2977386Sgblack@eecs.umich.edu int fpClass = std::fpclassify(val); 2987386Sgblack@eecs.umich.edu fpType junk = 0.0; 2997386Sgblack@eecs.umich.edu if (fpClass == FP_NAN) { 3007386Sgblack@eecs.umich.edu const bool single = (sizeof(val) == sizeof(float)); 3017386Sgblack@eecs.umich.edu const uint64_t qnan = single ? 0x7fc00000 : ULL(0x7ff8000000000000); 3027386Sgblack@eecs.umich.edu const bool nan = std::isnan(op1); 3037386Sgblack@eecs.umich.edu if (!nan || (fpscr.dn == 1)) { 3047386Sgblack@eecs.umich.edu val = bitsToFp(qnan, junk); 3057386Sgblack@eecs.umich.edu } else if (nan) { 3067386Sgblack@eecs.umich.edu val = bitsToFp(fpToBits(op1) | qnan, junk); 3077386Sgblack@eecs.umich.edu } 3087386Sgblack@eecs.umich.edu } else if (fpClass == FP_SUBNORMAL && fpscr.fz == 1) { 3097386Sgblack@eecs.umich.edu // Turn val into a zero with the correct sign; 3107386Sgblack@eecs.umich.edu uint64_t bitMask = ULL(0x1) << (sizeof(fpType) * 8 - 1); 3117386Sgblack@eecs.umich.edu val = bitsToFp(fpToBits(val) & bitMask, junk); 3127396Sgblack@eecs.umich.edu feclearexcept(FeInexact); 3137386Sgblack@eecs.umich.edu feraiseexcept(FeUnderflow); 3147386Sgblack@eecs.umich.edu } 3157386Sgblack@eecs.umich.edu return val; 3167386Sgblack@eecs.umich.edu} 3177386Sgblack@eecs.umich.edu 3187386Sgblack@eecs.umich.edutemplate <class fpType> 3197386Sgblack@eecs.umich.edustatic inline fpType 3207385Sgblack@eecs.umich.edufixDest(FPSCR fpscr, fpType val, fpType op1, fpType op2) 3217384Sgblack@eecs.umich.edu{ 3227385Sgblack@eecs.umich.edu int fpClass = std::fpclassify(val); 3237385Sgblack@eecs.umich.edu fpType junk = 0.0; 3247385Sgblack@eecs.umich.edu if (fpClass == FP_NAN) { 3257384Sgblack@eecs.umich.edu const bool single = (sizeof(val) == sizeof(float)); 3267384Sgblack@eecs.umich.edu const uint64_t qnan = single ? 0x7fc00000 : ULL(0x7ff8000000000000); 3277384Sgblack@eecs.umich.edu const bool nan1 = std::isnan(op1); 3287384Sgblack@eecs.umich.edu const bool nan2 = std::isnan(op2); 3297384Sgblack@eecs.umich.edu const bool signal1 = nan1 && ((fpToBits(op1) & qnan) != qnan); 3307384Sgblack@eecs.umich.edu const bool signal2 = nan2 && ((fpToBits(op2) & qnan) != qnan); 3317384Sgblack@eecs.umich.edu if ((!nan1 && !nan2) || (fpscr.dn == 1)) { 3327384Sgblack@eecs.umich.edu val = bitsToFp(qnan, junk); 3337384Sgblack@eecs.umich.edu } else if (signal1) { 3347384Sgblack@eecs.umich.edu val = bitsToFp(fpToBits(op1) | qnan, junk); 3357384Sgblack@eecs.umich.edu } else if (signal2) { 3367384Sgblack@eecs.umich.edu val = bitsToFp(fpToBits(op2) | qnan, junk); 3377384Sgblack@eecs.umich.edu } else if (nan1) { 3387384Sgblack@eecs.umich.edu val = op1; 3397384Sgblack@eecs.umich.edu } else if (nan2) { 3407384Sgblack@eecs.umich.edu val = op2; 3417384Sgblack@eecs.umich.edu } 3427385Sgblack@eecs.umich.edu } else if (fpClass == FP_SUBNORMAL && fpscr.fz == 1) { 3437385Sgblack@eecs.umich.edu // Turn val into a zero with the correct sign; 3447385Sgblack@eecs.umich.edu uint64_t bitMask = ULL(0x1) << (sizeof(fpType) * 8 - 1); 3457385Sgblack@eecs.umich.edu val = bitsToFp(fpToBits(val) & bitMask, junk); 3467396Sgblack@eecs.umich.edu feclearexcept(FeInexact); 3477385Sgblack@eecs.umich.edu feraiseexcept(FeUnderflow); 3487384Sgblack@eecs.umich.edu } 3497384Sgblack@eecs.umich.edu return val; 3507384Sgblack@eecs.umich.edu} 3517384Sgblack@eecs.umich.edu 3527386Sgblack@eecs.umich.edutemplate <class fpType> 3537386Sgblack@eecs.umich.edustatic inline fpType 3547386Sgblack@eecs.umich.edufixDivDest(FPSCR fpscr, fpType val, fpType op1, fpType op2) 3557386Sgblack@eecs.umich.edu{ 3567386Sgblack@eecs.umich.edu fpType mid = fixDest(fpscr, val, op1, op2); 3577386Sgblack@eecs.umich.edu const bool single = (sizeof(fpType) == sizeof(float)); 3587386Sgblack@eecs.umich.edu const fpType junk = 0.0; 3597386Sgblack@eecs.umich.edu if ((single && (val == bitsToFp(0x00800000, junk) || 3607386Sgblack@eecs.umich.edu val == bitsToFp(0x80800000, junk))) || 3617386Sgblack@eecs.umich.edu (!single && (val == bitsToFp(ULL(0x0010000000000000), junk) || 3627386Sgblack@eecs.umich.edu val == bitsToFp(ULL(0x8010000000000000), junk))) 3637386Sgblack@eecs.umich.edu ) { 3647386Sgblack@eecs.umich.edu __asm__ __volatile__("" : "=m" (op1) : "m" (op1)); 3657386Sgblack@eecs.umich.edu fesetround(FeRoundZero); 3667386Sgblack@eecs.umich.edu fpType temp = 0.0; 3677386Sgblack@eecs.umich.edu __asm__ __volatile__("" : "=m" (temp) : "m" (temp)); 3687386Sgblack@eecs.umich.edu temp = op1 / op2; 3697396Sgblack@eecs.umich.edu if (flushToZero(temp)) { 3707386Sgblack@eecs.umich.edu feraiseexcept(FeUnderflow); 3717396Sgblack@eecs.umich.edu if (fpscr.fz) { 3727396Sgblack@eecs.umich.edu feclearexcept(FeInexact); 3737396Sgblack@eecs.umich.edu mid = temp; 3747396Sgblack@eecs.umich.edu } 3757386Sgblack@eecs.umich.edu } 3767386Sgblack@eecs.umich.edu __asm__ __volatile__("" :: "m" (temp)); 3777386Sgblack@eecs.umich.edu } 3787386Sgblack@eecs.umich.edu return mid; 3797386Sgblack@eecs.umich.edu} 3807386Sgblack@eecs.umich.edu 3817386Sgblack@eecs.umich.edustatic inline float 3827386Sgblack@eecs.umich.edufixFpDFpSDest(FPSCR fpscr, double val) 3837386Sgblack@eecs.umich.edu{ 3847386Sgblack@eecs.umich.edu const float junk = 0.0; 3857386Sgblack@eecs.umich.edu float op1 = 0.0; 3867386Sgblack@eecs.umich.edu if (std::isnan(val)) { 3877386Sgblack@eecs.umich.edu uint64_t valBits = fpToBits(val); 3887386Sgblack@eecs.umich.edu uint32_t op1Bits = bits(valBits, 50, 29) | 3897386Sgblack@eecs.umich.edu (mask(9) << 22) | 3907386Sgblack@eecs.umich.edu (bits(valBits, 63) << 31); 3917386Sgblack@eecs.umich.edu op1 = bitsToFp(op1Bits, junk); 3927386Sgblack@eecs.umich.edu } 3937386Sgblack@eecs.umich.edu float mid = fixDest(fpscr, (float)val, op1); 3947396Sgblack@eecs.umich.edu if (fpscr.fz && fetestexcept(FeUnderflow | FeInexact) == 3957396Sgblack@eecs.umich.edu (FeUnderflow | FeInexact)) { 3967396Sgblack@eecs.umich.edu feclearexcept(FeInexact); 3977396Sgblack@eecs.umich.edu } 3987386Sgblack@eecs.umich.edu if (mid == bitsToFp(0x00800000, junk) || 3997386Sgblack@eecs.umich.edu mid == bitsToFp(0x80800000, junk)) { 4007386Sgblack@eecs.umich.edu __asm__ __volatile__("" : "=m" (val) : "m" (val)); 4017386Sgblack@eecs.umich.edu fesetround(FeRoundZero); 4027386Sgblack@eecs.umich.edu float temp = 0.0; 4037386Sgblack@eecs.umich.edu __asm__ __volatile__("" : "=m" (temp) : "m" (temp)); 4047386Sgblack@eecs.umich.edu temp = val; 4057396Sgblack@eecs.umich.edu if (flushToZero(temp)) { 4067386Sgblack@eecs.umich.edu feraiseexcept(FeUnderflow); 4077396Sgblack@eecs.umich.edu if (fpscr.fz) { 4087396Sgblack@eecs.umich.edu feclearexcept(FeInexact); 4097396Sgblack@eecs.umich.edu mid = temp; 4107396Sgblack@eecs.umich.edu } 4117386Sgblack@eecs.umich.edu } 4127386Sgblack@eecs.umich.edu __asm__ __volatile__("" :: "m" (temp)); 4137386Sgblack@eecs.umich.edu } 4147386Sgblack@eecs.umich.edu return mid; 4157386Sgblack@eecs.umich.edu} 4167386Sgblack@eecs.umich.edu 4177396Sgblack@eecs.umich.edustatic inline double 4187396Sgblack@eecs.umich.edufixFpSFpDDest(FPSCR fpscr, float val) 4197396Sgblack@eecs.umich.edu{ 4207396Sgblack@eecs.umich.edu const double junk = 0.0; 4217396Sgblack@eecs.umich.edu double op1 = 0.0; 4227396Sgblack@eecs.umich.edu if (std::isnan(val)) { 4237396Sgblack@eecs.umich.edu uint32_t valBits = fpToBits(val); 4247396Sgblack@eecs.umich.edu uint64_t op1Bits = ((uint64_t)bits(valBits, 21, 0) << 29) | 4257396Sgblack@eecs.umich.edu (mask(12) << 51) | 4267396Sgblack@eecs.umich.edu ((uint64_t)bits(valBits, 31) << 63); 4277396Sgblack@eecs.umich.edu op1 = bitsToFp(op1Bits, junk); 4287396Sgblack@eecs.umich.edu } 4297396Sgblack@eecs.umich.edu double mid = fixDest(fpscr, (double)val, op1); 4307396Sgblack@eecs.umich.edu if (mid == bitsToFp(ULL(0x0010000000000000), junk) || 4317396Sgblack@eecs.umich.edu mid == bitsToFp(ULL(0x8010000000000000), junk)) { 4327396Sgblack@eecs.umich.edu __asm__ __volatile__("" : "=m" (val) : "m" (val)); 4337396Sgblack@eecs.umich.edu fesetround(FeRoundZero); 4347396Sgblack@eecs.umich.edu double temp = 0.0; 4357396Sgblack@eecs.umich.edu __asm__ __volatile__("" : "=m" (temp) : "m" (temp)); 4367396Sgblack@eecs.umich.edu temp = val; 4377396Sgblack@eecs.umich.edu if (flushToZero(temp)) { 4387396Sgblack@eecs.umich.edu feraiseexcept(FeUnderflow); 4397396Sgblack@eecs.umich.edu if (fpscr.fz) { 4407396Sgblack@eecs.umich.edu feclearexcept(FeInexact); 4417396Sgblack@eecs.umich.edu mid = temp; 4427396Sgblack@eecs.umich.edu } 4437396Sgblack@eecs.umich.edu } 4447396Sgblack@eecs.umich.edu __asm__ __volatile__("" :: "m" (temp)); 4457396Sgblack@eecs.umich.edu } 4467396Sgblack@eecs.umich.edu return mid; 4477396Sgblack@eecs.umich.edu} 4487396Sgblack@eecs.umich.edu 4497396Sgblack@eecs.umich.edustatic inline double 4507396Sgblack@eecs.umich.edumakeDouble(uint32_t low, uint32_t high) 4517396Sgblack@eecs.umich.edu{ 4527396Sgblack@eecs.umich.edu double junk = 0.0; 4537396Sgblack@eecs.umich.edu return bitsToFp((uint64_t)low | ((uint64_t)high << 32), junk); 4547396Sgblack@eecs.umich.edu} 4557396Sgblack@eecs.umich.edu 4567396Sgblack@eecs.umich.edustatic inline uint32_t 4577396Sgblack@eecs.umich.edulowFromDouble(double val) 4587396Sgblack@eecs.umich.edu{ 4597396Sgblack@eecs.umich.edu return fpToBits(val); 4607396Sgblack@eecs.umich.edu} 4617396Sgblack@eecs.umich.edu 4627396Sgblack@eecs.umich.edustatic inline uint32_t 4637396Sgblack@eecs.umich.eduhighFromDouble(double val) 4647396Sgblack@eecs.umich.edu{ 4657396Sgblack@eecs.umich.edu return fpToBits(val) >> 32; 4667396Sgblack@eecs.umich.edu} 4677396Sgblack@eecs.umich.edu 4687379Sgblack@eecs.umich.edustatic inline uint64_t 4697388Sgblack@eecs.umich.eduvfpFpSToFixed(float val, bool isSigned, bool half, 4707388Sgblack@eecs.umich.edu uint8_t imm, bool rzero = true) 4717379Sgblack@eecs.umich.edu{ 4727396Sgblack@eecs.umich.edu int rmode = rzero ? FeRoundZero : fegetround(); 4737396Sgblack@eecs.umich.edu __asm__ __volatile__("" : "=m" (rmode) : "m" (rmode)); 4747388Sgblack@eecs.umich.edu fesetround(FeRoundNearest); 4757379Sgblack@eecs.umich.edu val = val * powf(2.0, imm); 4767379Sgblack@eecs.umich.edu __asm__ __volatile__("" : "=m" (val) : "m" (val)); 4777396Sgblack@eecs.umich.edu fesetround(rmode); 4787379Sgblack@eecs.umich.edu feclearexcept(FeAllExceptions); 4797382Sgblack@eecs.umich.edu __asm__ __volatile__("" : "=m" (val) : "m" (val)); 4807382Sgblack@eecs.umich.edu float origVal = val; 4817382Sgblack@eecs.umich.edu val = rintf(val); 4827382Sgblack@eecs.umich.edu int fpType = std::fpclassify(val); 4837382Sgblack@eecs.umich.edu if (fpType == FP_SUBNORMAL || fpType == FP_NAN) { 4847382Sgblack@eecs.umich.edu if (fpType == FP_NAN) { 4857382Sgblack@eecs.umich.edu feraiseexcept(FeInvalid); 4867382Sgblack@eecs.umich.edu } 4877382Sgblack@eecs.umich.edu val = 0.0; 4887382Sgblack@eecs.umich.edu } else if (origVal != val) { 4897396Sgblack@eecs.umich.edu switch (rmode) { 4907396Sgblack@eecs.umich.edu case FeRoundNearest: 4917396Sgblack@eecs.umich.edu if (origVal - val > 0.5) 4927396Sgblack@eecs.umich.edu val += 1.0; 4937396Sgblack@eecs.umich.edu else if (val - origVal > 0.5) 4947396Sgblack@eecs.umich.edu val -= 1.0; 4957396Sgblack@eecs.umich.edu break; 4967396Sgblack@eecs.umich.edu case FeRoundDown: 4977396Sgblack@eecs.umich.edu if (origVal < val) 4987396Sgblack@eecs.umich.edu val -= 1.0; 4997396Sgblack@eecs.umich.edu break; 5007396Sgblack@eecs.umich.edu case FeRoundUpward: 5017396Sgblack@eecs.umich.edu if (origVal > val) 5027396Sgblack@eecs.umich.edu val += 1.0; 5037396Sgblack@eecs.umich.edu break; 5047396Sgblack@eecs.umich.edu } 5057382Sgblack@eecs.umich.edu feraiseexcept(FeInexact); 5067382Sgblack@eecs.umich.edu } 5077382Sgblack@eecs.umich.edu 5087379Sgblack@eecs.umich.edu if (isSigned) { 5097379Sgblack@eecs.umich.edu if (half) { 5107381Sgblack@eecs.umich.edu if ((double)val < (int16_t)(1 << 15)) { 5117379Sgblack@eecs.umich.edu feraiseexcept(FeInvalid); 5127382Sgblack@eecs.umich.edu feclearexcept(FeInexact); 5137379Sgblack@eecs.umich.edu return (int16_t)(1 << 15); 5147379Sgblack@eecs.umich.edu } 5157381Sgblack@eecs.umich.edu if ((double)val > (int16_t)mask(15)) { 5167379Sgblack@eecs.umich.edu feraiseexcept(FeInvalid); 5177382Sgblack@eecs.umich.edu feclearexcept(FeInexact); 5187379Sgblack@eecs.umich.edu return (int16_t)mask(15); 5197379Sgblack@eecs.umich.edu } 5207379Sgblack@eecs.umich.edu return (int16_t)val; 5217379Sgblack@eecs.umich.edu } else { 5227381Sgblack@eecs.umich.edu if ((double)val < (int32_t)(1 << 31)) { 5237379Sgblack@eecs.umich.edu feraiseexcept(FeInvalid); 5247382Sgblack@eecs.umich.edu feclearexcept(FeInexact); 5257379Sgblack@eecs.umich.edu return (int32_t)(1 << 31); 5267379Sgblack@eecs.umich.edu } 5277381Sgblack@eecs.umich.edu if ((double)val > (int32_t)mask(31)) { 5287379Sgblack@eecs.umich.edu feraiseexcept(FeInvalid); 5297382Sgblack@eecs.umich.edu feclearexcept(FeInexact); 5307379Sgblack@eecs.umich.edu return (int32_t)mask(31); 5317379Sgblack@eecs.umich.edu } 5327379Sgblack@eecs.umich.edu return (int32_t)val; 5337379Sgblack@eecs.umich.edu } 5347379Sgblack@eecs.umich.edu } else { 5357379Sgblack@eecs.umich.edu if (half) { 5367381Sgblack@eecs.umich.edu if ((double)val < 0) { 5377379Sgblack@eecs.umich.edu feraiseexcept(FeInvalid); 5387382Sgblack@eecs.umich.edu feclearexcept(FeInexact); 5397379Sgblack@eecs.umich.edu return 0; 5407379Sgblack@eecs.umich.edu } 5417381Sgblack@eecs.umich.edu if ((double)val > (mask(16))) { 5427379Sgblack@eecs.umich.edu feraiseexcept(FeInvalid); 5437382Sgblack@eecs.umich.edu feclearexcept(FeInexact); 5447379Sgblack@eecs.umich.edu return mask(16); 5457379Sgblack@eecs.umich.edu } 5467379Sgblack@eecs.umich.edu return (uint16_t)val; 5477379Sgblack@eecs.umich.edu } else { 5487381Sgblack@eecs.umich.edu if ((double)val < 0) { 5497379Sgblack@eecs.umich.edu feraiseexcept(FeInvalid); 5507382Sgblack@eecs.umich.edu feclearexcept(FeInexact); 5517379Sgblack@eecs.umich.edu return 0; 5527379Sgblack@eecs.umich.edu } 5537381Sgblack@eecs.umich.edu if ((double)val > (mask(32))) { 5547379Sgblack@eecs.umich.edu feraiseexcept(FeInvalid); 5557382Sgblack@eecs.umich.edu feclearexcept(FeInexact); 5567379Sgblack@eecs.umich.edu return mask(32); 5577379Sgblack@eecs.umich.edu } 5587379Sgblack@eecs.umich.edu return (uint32_t)val; 5597379Sgblack@eecs.umich.edu } 5607379Sgblack@eecs.umich.edu } 5617379Sgblack@eecs.umich.edu} 5627379Sgblack@eecs.umich.edu 5637379Sgblack@eecs.umich.edustatic inline float 5647386Sgblack@eecs.umich.eduvfpUFixedToFpS(FPSCR fpscr, uint32_t val, bool half, uint8_t imm) 5657379Sgblack@eecs.umich.edu{ 5667379Sgblack@eecs.umich.edu fesetround(FeRoundNearest); 5677379Sgblack@eecs.umich.edu if (half) 5687379Sgblack@eecs.umich.edu val = (uint16_t)val; 5697382Sgblack@eecs.umich.edu float scale = powf(2.0, imm); 5707382Sgblack@eecs.umich.edu __asm__ __volatile__("" : "=m" (scale) : "m" (scale)); 5717382Sgblack@eecs.umich.edu feclearexcept(FeAllExceptions); 5727382Sgblack@eecs.umich.edu __asm__ __volatile__("" : "=m" (scale) : "m" (scale)); 5737386Sgblack@eecs.umich.edu return fixDivDest(fpscr, val / scale, (float)val, scale); 5747379Sgblack@eecs.umich.edu} 5757379Sgblack@eecs.umich.edu 5767379Sgblack@eecs.umich.edustatic inline float 5777386Sgblack@eecs.umich.eduvfpSFixedToFpS(FPSCR fpscr, int32_t val, bool half, uint8_t imm) 5787379Sgblack@eecs.umich.edu{ 5797379Sgblack@eecs.umich.edu fesetround(FeRoundNearest); 5807379Sgblack@eecs.umich.edu if (half) 5817379Sgblack@eecs.umich.edu val = sext<16>(val & mask(16)); 5827382Sgblack@eecs.umich.edu float scale = powf(2.0, imm); 5837382Sgblack@eecs.umich.edu __asm__ __volatile__("" : "=m" (scale) : "m" (scale)); 5847382Sgblack@eecs.umich.edu feclearexcept(FeAllExceptions); 5857382Sgblack@eecs.umich.edu __asm__ __volatile__("" : "=m" (scale) : "m" (scale)); 5867386Sgblack@eecs.umich.edu return fixDivDest(fpscr, val / scale, (float)val, scale); 5877379Sgblack@eecs.umich.edu} 5887379Sgblack@eecs.umich.edu 5897379Sgblack@eecs.umich.edustatic inline uint64_t 5907388Sgblack@eecs.umich.eduvfpFpDToFixed(double val, bool isSigned, bool half, 5917388Sgblack@eecs.umich.edu uint8_t imm, bool rzero = true) 5927379Sgblack@eecs.umich.edu{ 5937396Sgblack@eecs.umich.edu int rmode = rzero ? FeRoundZero : fegetround(); 5947382Sgblack@eecs.umich.edu fesetround(FeRoundNearest); 5957379Sgblack@eecs.umich.edu val = val * pow(2.0, imm); 5967379Sgblack@eecs.umich.edu __asm__ __volatile__("" : "=m" (val) : "m" (val)); 5977396Sgblack@eecs.umich.edu fesetround(rmode); 5987379Sgblack@eecs.umich.edu feclearexcept(FeAllExceptions); 5997382Sgblack@eecs.umich.edu __asm__ __volatile__("" : "=m" (val) : "m" (val)); 6007382Sgblack@eecs.umich.edu double origVal = val; 6017382Sgblack@eecs.umich.edu val = rint(val); 6027382Sgblack@eecs.umich.edu int fpType = std::fpclassify(val); 6037382Sgblack@eecs.umich.edu if (fpType == FP_SUBNORMAL || fpType == FP_NAN) { 6047382Sgblack@eecs.umich.edu if (fpType == FP_NAN) { 6057382Sgblack@eecs.umich.edu feraiseexcept(FeInvalid); 6067382Sgblack@eecs.umich.edu } 6077382Sgblack@eecs.umich.edu val = 0.0; 6087382Sgblack@eecs.umich.edu } else if (origVal != val) { 6097396Sgblack@eecs.umich.edu switch (rmode) { 6107396Sgblack@eecs.umich.edu case FeRoundNearest: 6117396Sgblack@eecs.umich.edu if (origVal - val > 0.5) 6127396Sgblack@eecs.umich.edu val += 1.0; 6137396Sgblack@eecs.umich.edu else if (val - origVal > 0.5) 6147396Sgblack@eecs.umich.edu val -= 1.0; 6157396Sgblack@eecs.umich.edu break; 6167396Sgblack@eecs.umich.edu case FeRoundDown: 6177396Sgblack@eecs.umich.edu if (origVal < val) 6187396Sgblack@eecs.umich.edu val -= 1.0; 6197396Sgblack@eecs.umich.edu break; 6207396Sgblack@eecs.umich.edu case FeRoundUpward: 6217396Sgblack@eecs.umich.edu if (origVal > val) 6227396Sgblack@eecs.umich.edu val += 1.0; 6237396Sgblack@eecs.umich.edu break; 6247396Sgblack@eecs.umich.edu } 6257382Sgblack@eecs.umich.edu feraiseexcept(FeInexact); 6267382Sgblack@eecs.umich.edu } 6277379Sgblack@eecs.umich.edu if (isSigned) { 6287379Sgblack@eecs.umich.edu if (half) { 6297379Sgblack@eecs.umich.edu if (val < (int16_t)(1 << 15)) { 6307379Sgblack@eecs.umich.edu feraiseexcept(FeInvalid); 6317382Sgblack@eecs.umich.edu feclearexcept(FeInexact); 6327379Sgblack@eecs.umich.edu return (int16_t)(1 << 15); 6337379Sgblack@eecs.umich.edu } 6347379Sgblack@eecs.umich.edu if (val > (int16_t)mask(15)) { 6357379Sgblack@eecs.umich.edu feraiseexcept(FeInvalid); 6367382Sgblack@eecs.umich.edu feclearexcept(FeInexact); 6377379Sgblack@eecs.umich.edu return (int16_t)mask(15); 6387379Sgblack@eecs.umich.edu } 6397379Sgblack@eecs.umich.edu return (int16_t)val; 6407379Sgblack@eecs.umich.edu } else { 6417379Sgblack@eecs.umich.edu if (val < (int32_t)(1 << 31)) { 6427379Sgblack@eecs.umich.edu feraiseexcept(FeInvalid); 6437382Sgblack@eecs.umich.edu feclearexcept(FeInexact); 6447379Sgblack@eecs.umich.edu return (int32_t)(1 << 31); 6457379Sgblack@eecs.umich.edu } 6467379Sgblack@eecs.umich.edu if (val > (int32_t)mask(31)) { 6477379Sgblack@eecs.umich.edu feraiseexcept(FeInvalid); 6487382Sgblack@eecs.umich.edu feclearexcept(FeInexact); 6497379Sgblack@eecs.umich.edu return (int32_t)mask(31); 6507379Sgblack@eecs.umich.edu } 6517379Sgblack@eecs.umich.edu return (int32_t)val; 6527379Sgblack@eecs.umich.edu } 6537379Sgblack@eecs.umich.edu } else { 6547379Sgblack@eecs.umich.edu if (half) { 6557379Sgblack@eecs.umich.edu if (val < 0) { 6567379Sgblack@eecs.umich.edu feraiseexcept(FeInvalid); 6577382Sgblack@eecs.umich.edu feclearexcept(FeInexact); 6587379Sgblack@eecs.umich.edu return 0; 6597379Sgblack@eecs.umich.edu } 6607379Sgblack@eecs.umich.edu if (val > mask(16)) { 6617379Sgblack@eecs.umich.edu feraiseexcept(FeInvalid); 6627382Sgblack@eecs.umich.edu feclearexcept(FeInexact); 6637379Sgblack@eecs.umich.edu return mask(16); 6647379Sgblack@eecs.umich.edu } 6657379Sgblack@eecs.umich.edu return (uint16_t)val; 6667379Sgblack@eecs.umich.edu } else { 6677379Sgblack@eecs.umich.edu if (val < 0) { 6687379Sgblack@eecs.umich.edu feraiseexcept(FeInvalid); 6697382Sgblack@eecs.umich.edu feclearexcept(FeInexact); 6707379Sgblack@eecs.umich.edu return 0; 6717379Sgblack@eecs.umich.edu } 6727379Sgblack@eecs.umich.edu if (val > mask(32)) { 6737379Sgblack@eecs.umich.edu feraiseexcept(FeInvalid); 6747382Sgblack@eecs.umich.edu feclearexcept(FeInexact); 6757379Sgblack@eecs.umich.edu return mask(32); 6767379Sgblack@eecs.umich.edu } 6777379Sgblack@eecs.umich.edu return (uint32_t)val; 6787379Sgblack@eecs.umich.edu } 6797379Sgblack@eecs.umich.edu } 6807379Sgblack@eecs.umich.edu} 6817379Sgblack@eecs.umich.edu 6827379Sgblack@eecs.umich.edustatic inline double 6837386Sgblack@eecs.umich.eduvfpUFixedToFpD(FPSCR fpscr, uint32_t val, bool half, uint8_t imm) 6847379Sgblack@eecs.umich.edu{ 6857379Sgblack@eecs.umich.edu fesetround(FeRoundNearest); 6867379Sgblack@eecs.umich.edu if (half) 6877379Sgblack@eecs.umich.edu val = (uint16_t)val; 6887382Sgblack@eecs.umich.edu double scale = pow(2.0, imm); 6897382Sgblack@eecs.umich.edu __asm__ __volatile__("" : "=m" (scale) : "m" (scale)); 6907382Sgblack@eecs.umich.edu feclearexcept(FeAllExceptions); 6917382Sgblack@eecs.umich.edu __asm__ __volatile__("" : "=m" (scale) : "m" (scale)); 6927386Sgblack@eecs.umich.edu return fixDivDest(fpscr, val / scale, (double)val, scale); 6937379Sgblack@eecs.umich.edu} 6947379Sgblack@eecs.umich.edu 6957379Sgblack@eecs.umich.edustatic inline double 6967386Sgblack@eecs.umich.eduvfpSFixedToFpD(FPSCR fpscr, int32_t val, bool half, uint8_t imm) 6977379Sgblack@eecs.umich.edu{ 6987379Sgblack@eecs.umich.edu fesetround(FeRoundNearest); 6997379Sgblack@eecs.umich.edu if (half) 7007379Sgblack@eecs.umich.edu val = sext<16>(val & mask(16)); 7017382Sgblack@eecs.umich.edu double scale = pow(2.0, imm); 7027382Sgblack@eecs.umich.edu __asm__ __volatile__("" : "=m" (scale) : "m" (scale)); 7037382Sgblack@eecs.umich.edu feclearexcept(FeAllExceptions); 7047382Sgblack@eecs.umich.edu __asm__ __volatile__("" : "=m" (scale) : "m" (scale)); 7057386Sgblack@eecs.umich.edu return fixDivDest(fpscr, val / scale, (double)val, scale); 7067379Sgblack@eecs.umich.edu} 7077379Sgblack@eecs.umich.edu 7087376Sgblack@eecs.umich.educlass VfpMacroOp : public PredMacroOp 7097376Sgblack@eecs.umich.edu{ 7107376Sgblack@eecs.umich.edu public: 7117376Sgblack@eecs.umich.edu static bool 7127376Sgblack@eecs.umich.edu inScalarBank(IntRegIndex idx) 7137376Sgblack@eecs.umich.edu { 7147376Sgblack@eecs.umich.edu return (idx % 32) < 8; 7157376Sgblack@eecs.umich.edu } 7167376Sgblack@eecs.umich.edu 7177376Sgblack@eecs.umich.edu protected: 7187376Sgblack@eecs.umich.edu bool wide; 7197376Sgblack@eecs.umich.edu 7207376Sgblack@eecs.umich.edu VfpMacroOp(const char *mnem, ExtMachInst _machInst, 7217376Sgblack@eecs.umich.edu OpClass __opClass, bool _wide) : 7227376Sgblack@eecs.umich.edu PredMacroOp(mnem, _machInst, __opClass), wide(_wide) 7237376Sgblack@eecs.umich.edu {} 7247376Sgblack@eecs.umich.edu 7257376Sgblack@eecs.umich.edu IntRegIndex 7267376Sgblack@eecs.umich.edu addStride(IntRegIndex idx, unsigned stride) 7277376Sgblack@eecs.umich.edu { 7287376Sgblack@eecs.umich.edu if (wide) { 7297376Sgblack@eecs.umich.edu stride *= 2; 7307376Sgblack@eecs.umich.edu } 7317376Sgblack@eecs.umich.edu unsigned offset = idx % 8; 7327376Sgblack@eecs.umich.edu idx = (IntRegIndex)(idx - offset); 7337376Sgblack@eecs.umich.edu offset += stride; 7347376Sgblack@eecs.umich.edu idx = (IntRegIndex)(idx + (offset % 8)); 7357376Sgblack@eecs.umich.edu return idx; 7367376Sgblack@eecs.umich.edu } 7377376Sgblack@eecs.umich.edu 7387376Sgblack@eecs.umich.edu void 7397376Sgblack@eecs.umich.edu nextIdxs(IntRegIndex &dest, IntRegIndex &op1, IntRegIndex &op2) 7407376Sgblack@eecs.umich.edu { 7417376Sgblack@eecs.umich.edu unsigned stride = (machInst.fpscrStride == 0) ? 1 : 2; 7427376Sgblack@eecs.umich.edu assert(!inScalarBank(dest)); 7437376Sgblack@eecs.umich.edu dest = addStride(dest, stride); 7447376Sgblack@eecs.umich.edu op1 = addStride(op1, stride); 7457376Sgblack@eecs.umich.edu if (!inScalarBank(op2)) { 7467376Sgblack@eecs.umich.edu op2 = addStride(op2, stride); 7477376Sgblack@eecs.umich.edu } 7487376Sgblack@eecs.umich.edu } 7497376Sgblack@eecs.umich.edu 7507376Sgblack@eecs.umich.edu void 7517376Sgblack@eecs.umich.edu nextIdxs(IntRegIndex &dest, IntRegIndex &op1) 7527376Sgblack@eecs.umich.edu { 7537376Sgblack@eecs.umich.edu unsigned stride = (machInst.fpscrStride == 0) ? 1 : 2; 7547376Sgblack@eecs.umich.edu assert(!inScalarBank(dest)); 7557376Sgblack@eecs.umich.edu dest = addStride(dest, stride); 7567376Sgblack@eecs.umich.edu if (!inScalarBank(op1)) { 7577376Sgblack@eecs.umich.edu op1 = addStride(op1, stride); 7587376Sgblack@eecs.umich.edu } 7597376Sgblack@eecs.umich.edu } 7607376Sgblack@eecs.umich.edu 7617376Sgblack@eecs.umich.edu void 7627376Sgblack@eecs.umich.edu nextIdxs(IntRegIndex &dest) 7637376Sgblack@eecs.umich.edu { 7647376Sgblack@eecs.umich.edu unsigned stride = (machInst.fpscrStride == 0) ? 1 : 2; 7657376Sgblack@eecs.umich.edu assert(!inScalarBank(dest)); 7667376Sgblack@eecs.umich.edu dest = addStride(dest, stride); 7677376Sgblack@eecs.umich.edu } 7687376Sgblack@eecs.umich.edu}; 7697376Sgblack@eecs.umich.edu 7707396Sgblack@eecs.umich.edustatic inline float 7717396Sgblack@eecs.umich.edufpAddS(float a, float b) 7727396Sgblack@eecs.umich.edu{ 7737396Sgblack@eecs.umich.edu return a + b; 7747396Sgblack@eecs.umich.edu} 7757396Sgblack@eecs.umich.edu 7767396Sgblack@eecs.umich.edustatic inline double 7777396Sgblack@eecs.umich.edufpAddD(double a, double b) 7787396Sgblack@eecs.umich.edu{ 7797396Sgblack@eecs.umich.edu return a + b; 7807396Sgblack@eecs.umich.edu} 7817396Sgblack@eecs.umich.edu 7827396Sgblack@eecs.umich.edustatic inline float 7837396Sgblack@eecs.umich.edufpSubS(float a, float b) 7847396Sgblack@eecs.umich.edu{ 7857396Sgblack@eecs.umich.edu return a - b; 7867396Sgblack@eecs.umich.edu} 7877396Sgblack@eecs.umich.edu 7887396Sgblack@eecs.umich.edustatic inline double 7897396Sgblack@eecs.umich.edufpSubD(double a, double b) 7907396Sgblack@eecs.umich.edu{ 7917396Sgblack@eecs.umich.edu return a - b; 7927396Sgblack@eecs.umich.edu} 7937396Sgblack@eecs.umich.edu 7947396Sgblack@eecs.umich.edustatic inline float 7957396Sgblack@eecs.umich.edufpDivS(float a, float b) 7967396Sgblack@eecs.umich.edu{ 7977396Sgblack@eecs.umich.edu return a / b; 7987396Sgblack@eecs.umich.edu} 7997396Sgblack@eecs.umich.edu 8007396Sgblack@eecs.umich.edustatic inline double 8017396Sgblack@eecs.umich.edufpDivD(double a, double b) 8027396Sgblack@eecs.umich.edu{ 8037396Sgblack@eecs.umich.edu return a / b; 8047396Sgblack@eecs.umich.edu} 8057396Sgblack@eecs.umich.edu 8067396Sgblack@eecs.umich.edustatic inline float 8077396Sgblack@eecs.umich.edufpMulS(float a, float b) 8087396Sgblack@eecs.umich.edu{ 8097396Sgblack@eecs.umich.edu return a * b; 8107396Sgblack@eecs.umich.edu} 8117396Sgblack@eecs.umich.edu 8127396Sgblack@eecs.umich.edustatic inline double 8137396Sgblack@eecs.umich.edufpMulD(double a, double b) 8147396Sgblack@eecs.umich.edu{ 8157396Sgblack@eecs.umich.edu return a * b; 8167396Sgblack@eecs.umich.edu} 8177396Sgblack@eecs.umich.edu 8187396Sgblack@eecs.umich.educlass FpOp : public PredOp 8197375Sgblack@eecs.umich.edu{ 8207375Sgblack@eecs.umich.edu protected: 8217396Sgblack@eecs.umich.edu FpOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : 8227396Sgblack@eecs.umich.edu PredOp(mnem, _machInst, __opClass) 8237396Sgblack@eecs.umich.edu {} 8247396Sgblack@eecs.umich.edu 8257396Sgblack@eecs.umich.edu virtual float 8267396Sgblack@eecs.umich.edu doOp(float op1, float op2) const 8277396Sgblack@eecs.umich.edu { 8287396Sgblack@eecs.umich.edu panic("Unimplemented version of doOp called.\n"); 8297396Sgblack@eecs.umich.edu } 8307396Sgblack@eecs.umich.edu 8317396Sgblack@eecs.umich.edu virtual float 8327396Sgblack@eecs.umich.edu doOp(float op1) const 8337396Sgblack@eecs.umich.edu { 8347396Sgblack@eecs.umich.edu panic("Unimplemented version of doOp called.\n"); 8357396Sgblack@eecs.umich.edu } 8367396Sgblack@eecs.umich.edu 8377396Sgblack@eecs.umich.edu virtual double 8387396Sgblack@eecs.umich.edu doOp(double op1, double op2) const 8397396Sgblack@eecs.umich.edu { 8407396Sgblack@eecs.umich.edu panic("Unimplemented version of doOp called.\n"); 8417396Sgblack@eecs.umich.edu } 8427396Sgblack@eecs.umich.edu 8437396Sgblack@eecs.umich.edu virtual double 8447396Sgblack@eecs.umich.edu doOp(double op1) const 8457396Sgblack@eecs.umich.edu { 8467396Sgblack@eecs.umich.edu panic("Unimplemented version of doOp called.\n"); 8477396Sgblack@eecs.umich.edu } 8487396Sgblack@eecs.umich.edu 8497396Sgblack@eecs.umich.edu double 8507396Sgblack@eecs.umich.edu dbl(uint32_t low, uint32_t high) const 8517396Sgblack@eecs.umich.edu { 8527396Sgblack@eecs.umich.edu double junk = 0.0; 8537396Sgblack@eecs.umich.edu return bitsToFp((uint64_t)low | ((uint64_t)high << 32), junk); 8547396Sgblack@eecs.umich.edu } 8557396Sgblack@eecs.umich.edu 8567396Sgblack@eecs.umich.edu uint32_t 8577396Sgblack@eecs.umich.edu dblLow(double val) const 8587396Sgblack@eecs.umich.edu { 8597396Sgblack@eecs.umich.edu return fpToBits(val); 8607396Sgblack@eecs.umich.edu } 8617396Sgblack@eecs.umich.edu 8627396Sgblack@eecs.umich.edu uint32_t 8637396Sgblack@eecs.umich.edu dblHi(double val) const 8647396Sgblack@eecs.umich.edu { 8657396Sgblack@eecs.umich.edu return fpToBits(val) >> 32; 8667396Sgblack@eecs.umich.edu } 8677396Sgblack@eecs.umich.edu 8687396Sgblack@eecs.umich.edu template <class fpType> 8697396Sgblack@eecs.umich.edu fpType 8707396Sgblack@eecs.umich.edu binaryOp(FPSCR &fpscr, fpType op1, fpType op2, 8717396Sgblack@eecs.umich.edu fpType (*func)(fpType, fpType), 8727396Sgblack@eecs.umich.edu bool flush, uint32_t rMode) const 8737396Sgblack@eecs.umich.edu { 8747396Sgblack@eecs.umich.edu const bool single = (sizeof(fpType) == sizeof(float)); 8757396Sgblack@eecs.umich.edu fpType junk = 0.0; 8767396Sgblack@eecs.umich.edu 8777396Sgblack@eecs.umich.edu if (flush && flushToZero(op1, op2)) 8787396Sgblack@eecs.umich.edu fpscr.idc = 1; 8797396Sgblack@eecs.umich.edu VfpSavedState state = prepFpState(rMode); 8807396Sgblack@eecs.umich.edu __asm__ __volatile__ ("" : "=m" (op1), "=m" (op2), "=m" (state) 8817396Sgblack@eecs.umich.edu : "m" (op1), "m" (op2), "m" (state)); 8827396Sgblack@eecs.umich.edu fpType dest = func(op1, op2); 8837396Sgblack@eecs.umich.edu __asm__ __volatile__ ("" : "=m" (dest) : "m" (dest)); 8847396Sgblack@eecs.umich.edu 8857396Sgblack@eecs.umich.edu int fpClass = std::fpclassify(dest); 8867396Sgblack@eecs.umich.edu // Get NAN behavior right. This varies between x86 and ARM. 8877396Sgblack@eecs.umich.edu if (fpClass == FP_NAN) { 8887396Sgblack@eecs.umich.edu const bool single = (sizeof(fpType) == sizeof(float)); 8897396Sgblack@eecs.umich.edu const uint64_t qnan = 8907396Sgblack@eecs.umich.edu single ? 0x7fc00000 : ULL(0x7ff8000000000000); 8917396Sgblack@eecs.umich.edu const bool nan1 = std::isnan(op1); 8927396Sgblack@eecs.umich.edu const bool nan2 = std::isnan(op2); 8937396Sgblack@eecs.umich.edu const bool signal1 = nan1 && ((fpToBits(op1) & qnan) != qnan); 8947396Sgblack@eecs.umich.edu const bool signal2 = nan2 && ((fpToBits(op2) & qnan) != qnan); 8957396Sgblack@eecs.umich.edu if ((!nan1 && !nan2) || (fpscr.dn == 1)) { 8967396Sgblack@eecs.umich.edu dest = bitsToFp(qnan, junk); 8977396Sgblack@eecs.umich.edu } else if (signal1) { 8987396Sgblack@eecs.umich.edu dest = bitsToFp(fpToBits(op1) | qnan, junk); 8997396Sgblack@eecs.umich.edu } else if (signal2) { 9007396Sgblack@eecs.umich.edu dest = bitsToFp(fpToBits(op2) | qnan, junk); 9017396Sgblack@eecs.umich.edu } else if (nan1) { 9027396Sgblack@eecs.umich.edu dest = op1; 9037396Sgblack@eecs.umich.edu } else if (nan2) { 9047396Sgblack@eecs.umich.edu dest = op2; 9057396Sgblack@eecs.umich.edu } 9067396Sgblack@eecs.umich.edu } else if (flush && flushToZero(dest)) { 9077396Sgblack@eecs.umich.edu feraiseexcept(FeUnderflow); 9087396Sgblack@eecs.umich.edu } else if (( 9097396Sgblack@eecs.umich.edu (single && (dest == bitsToFp(0x00800000, junk) || 9107396Sgblack@eecs.umich.edu dest == bitsToFp(0x80800000, junk))) || 9117396Sgblack@eecs.umich.edu (!single && 9127396Sgblack@eecs.umich.edu (dest == bitsToFp(ULL(0x0010000000000000), junk) || 9137396Sgblack@eecs.umich.edu dest == bitsToFp(ULL(0x8010000000000000), junk))) 9147396Sgblack@eecs.umich.edu ) && rMode != VfpRoundZero) { 9157396Sgblack@eecs.umich.edu /* 9167396Sgblack@eecs.umich.edu * Correct for the fact that underflow is detected -before- rounding 9177396Sgblack@eecs.umich.edu * in ARM and -after- rounding in x86. 9187396Sgblack@eecs.umich.edu */ 9197396Sgblack@eecs.umich.edu fesetround(FeRoundZero); 9207396Sgblack@eecs.umich.edu __asm__ __volatile__ ("" : "=m" (op1), "=m" (op2) 9217396Sgblack@eecs.umich.edu : "m" (op1), "m" (op2)); 9227396Sgblack@eecs.umich.edu fpType temp = func(op1, op2); 9237396Sgblack@eecs.umich.edu __asm__ __volatile__ ("" : "=m" (temp) : "m" (temp)); 9247396Sgblack@eecs.umich.edu if (flush && flushToZero(temp)) { 9257396Sgblack@eecs.umich.edu dest = temp; 9267396Sgblack@eecs.umich.edu } 9277396Sgblack@eecs.umich.edu } 9287396Sgblack@eecs.umich.edu finishVfp(fpscr, state); 9297396Sgblack@eecs.umich.edu return dest; 9307396Sgblack@eecs.umich.edu } 9317396Sgblack@eecs.umich.edu 9327396Sgblack@eecs.umich.edu template <class fpType> 9337396Sgblack@eecs.umich.edu fpType 9347396Sgblack@eecs.umich.edu unaryOp(FPSCR &fpscr, fpType op1, 9357396Sgblack@eecs.umich.edu fpType (*func)(fpType), 9367396Sgblack@eecs.umich.edu bool flush, uint32_t rMode) const 9377396Sgblack@eecs.umich.edu { 9387396Sgblack@eecs.umich.edu const bool single = (sizeof(fpType) == sizeof(float)); 9397396Sgblack@eecs.umich.edu fpType junk = 0.0; 9407396Sgblack@eecs.umich.edu 9417396Sgblack@eecs.umich.edu if (flush && flushToZero(op1)) 9427396Sgblack@eecs.umich.edu fpscr.idc = 1; 9437396Sgblack@eecs.umich.edu VfpSavedState state = prepFpState(rMode); 9447396Sgblack@eecs.umich.edu __asm__ __volatile__ ("" : "=m" (op1), "=m" (state) 9457396Sgblack@eecs.umich.edu : "m" (op1), "m" (state)); 9467396Sgblack@eecs.umich.edu fpType dest = func(op1); 9477396Sgblack@eecs.umich.edu __asm__ __volatile__ ("" : "=m" (dest) : "m" (dest)); 9487396Sgblack@eecs.umich.edu 9497396Sgblack@eecs.umich.edu int fpClass = std::fpclassify(dest); 9507396Sgblack@eecs.umich.edu // Get NAN behavior right. This varies between x86 and ARM. 9517396Sgblack@eecs.umich.edu if (fpClass == FP_NAN) { 9527396Sgblack@eecs.umich.edu const bool single = (sizeof(fpType) == sizeof(float)); 9537396Sgblack@eecs.umich.edu const uint64_t qnan = 9547396Sgblack@eecs.umich.edu single ? 0x7fc00000 : ULL(0x7ff8000000000000); 9557396Sgblack@eecs.umich.edu const bool nan = std::isnan(op1); 9567396Sgblack@eecs.umich.edu if (!nan || fpscr.dn == 1) { 9577396Sgblack@eecs.umich.edu dest = bitsToFp(qnan, junk); 9587396Sgblack@eecs.umich.edu } else if (nan) { 9597396Sgblack@eecs.umich.edu dest = bitsToFp(fpToBits(op1) | qnan, junk); 9607396Sgblack@eecs.umich.edu } 9617396Sgblack@eecs.umich.edu } else if (flush && flushToZero(dest)) { 9627396Sgblack@eecs.umich.edu feraiseexcept(FeUnderflow); 9637396Sgblack@eecs.umich.edu } else if (( 9647396Sgblack@eecs.umich.edu (single && (dest == bitsToFp(0x00800000, junk) || 9657396Sgblack@eecs.umich.edu dest == bitsToFp(0x80800000, junk))) || 9667396Sgblack@eecs.umich.edu (!single && 9677396Sgblack@eecs.umich.edu (dest == bitsToFp(ULL(0x0010000000000000), junk) || 9687396Sgblack@eecs.umich.edu dest == bitsToFp(ULL(0x8010000000000000), junk))) 9697396Sgblack@eecs.umich.edu ) && rMode != VfpRoundZero) { 9707396Sgblack@eecs.umich.edu /* 9717396Sgblack@eecs.umich.edu * Correct for the fact that underflow is detected -before- rounding 9727396Sgblack@eecs.umich.edu * in ARM and -after- rounding in x86. 9737396Sgblack@eecs.umich.edu */ 9747396Sgblack@eecs.umich.edu fesetround(FeRoundZero); 9757396Sgblack@eecs.umich.edu __asm__ __volatile__ ("" : "=m" (op1) : "m" (op1)); 9767396Sgblack@eecs.umich.edu fpType temp = func(op1); 9777396Sgblack@eecs.umich.edu __asm__ __volatile__ ("" : "=m" (temp) : "m" (temp)); 9787396Sgblack@eecs.umich.edu if (flush && flushToZero(temp)) { 9797396Sgblack@eecs.umich.edu dest = temp; 9807396Sgblack@eecs.umich.edu } 9817396Sgblack@eecs.umich.edu } 9827396Sgblack@eecs.umich.edu finishVfp(fpscr, state); 9837396Sgblack@eecs.umich.edu return dest; 9847396Sgblack@eecs.umich.edu } 9857396Sgblack@eecs.umich.edu}; 9867396Sgblack@eecs.umich.edu 9877396Sgblack@eecs.umich.educlass FpRegRegOp : public FpOp 9887396Sgblack@eecs.umich.edu{ 9897396Sgblack@eecs.umich.edu protected: 9907396Sgblack@eecs.umich.edu IntRegIndex dest; 9917396Sgblack@eecs.umich.edu IntRegIndex op1; 9927396Sgblack@eecs.umich.edu 9937396Sgblack@eecs.umich.edu FpRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 9947396Sgblack@eecs.umich.edu IntRegIndex _dest, IntRegIndex _op1, 9957396Sgblack@eecs.umich.edu VfpMicroMode mode = VfpNotAMicroop) : 9967396Sgblack@eecs.umich.edu FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1) 9977375Sgblack@eecs.umich.edu { 9987375Sgblack@eecs.umich.edu setVfpMicroFlags(mode, flags); 9997375Sgblack@eecs.umich.edu } 10007396Sgblack@eecs.umich.edu 10017396Sgblack@eecs.umich.edu std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 10027375Sgblack@eecs.umich.edu}; 10037375Sgblack@eecs.umich.edu 10047396Sgblack@eecs.umich.educlass FpRegImmOp : public FpOp 10057375Sgblack@eecs.umich.edu{ 10067375Sgblack@eecs.umich.edu protected: 10077396Sgblack@eecs.umich.edu IntRegIndex dest; 10087396Sgblack@eecs.umich.edu uint64_t imm; 10097396Sgblack@eecs.umich.edu 10107396Sgblack@eecs.umich.edu FpRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 10117396Sgblack@eecs.umich.edu IntRegIndex _dest, uint64_t _imm, 10127396Sgblack@eecs.umich.edu VfpMicroMode mode = VfpNotAMicroop) : 10137396Sgblack@eecs.umich.edu FpOp(mnem, _machInst, __opClass), dest(_dest), imm(_imm) 10147375Sgblack@eecs.umich.edu { 10157375Sgblack@eecs.umich.edu setVfpMicroFlags(mode, flags); 10167375Sgblack@eecs.umich.edu } 10177396Sgblack@eecs.umich.edu 10187396Sgblack@eecs.umich.edu std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 10197375Sgblack@eecs.umich.edu}; 10207375Sgblack@eecs.umich.edu 10217396Sgblack@eecs.umich.educlass FpRegRegImmOp : public FpOp 10227375Sgblack@eecs.umich.edu{ 10237375Sgblack@eecs.umich.edu protected: 10247396Sgblack@eecs.umich.edu IntRegIndex dest; 10257396Sgblack@eecs.umich.edu IntRegIndex op1; 10267396Sgblack@eecs.umich.edu uint64_t imm; 10277396Sgblack@eecs.umich.edu 10287396Sgblack@eecs.umich.edu FpRegRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 10297396Sgblack@eecs.umich.edu IntRegIndex _dest, IntRegIndex _op1, 10307396Sgblack@eecs.umich.edu uint64_t _imm, VfpMicroMode mode = VfpNotAMicroop) : 10317396Sgblack@eecs.umich.edu FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1), imm(_imm) 10327375Sgblack@eecs.umich.edu { 10337375Sgblack@eecs.umich.edu setVfpMicroFlags(mode, flags); 10347375Sgblack@eecs.umich.edu } 10357396Sgblack@eecs.umich.edu 10367396Sgblack@eecs.umich.edu std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 10377375Sgblack@eecs.umich.edu}; 10387375Sgblack@eecs.umich.edu 10397396Sgblack@eecs.umich.educlass FpRegRegRegOp : public FpOp 10407375Sgblack@eecs.umich.edu{ 10417375Sgblack@eecs.umich.edu protected: 10427396Sgblack@eecs.umich.edu IntRegIndex dest; 10437396Sgblack@eecs.umich.edu IntRegIndex op1; 10447396Sgblack@eecs.umich.edu IntRegIndex op2; 10457396Sgblack@eecs.umich.edu 10467396Sgblack@eecs.umich.edu FpRegRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 10477396Sgblack@eecs.umich.edu IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, 10487396Sgblack@eecs.umich.edu VfpMicroMode mode = VfpNotAMicroop) : 10497396Sgblack@eecs.umich.edu FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2) 10507375Sgblack@eecs.umich.edu { 10517375Sgblack@eecs.umich.edu setVfpMicroFlags(mode, flags); 10527375Sgblack@eecs.umich.edu } 10537396Sgblack@eecs.umich.edu 10547396Sgblack@eecs.umich.edu std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 10557375Sgblack@eecs.umich.edu}; 10567375Sgblack@eecs.umich.edu 10577384Sgblack@eecs.umich.edu} 10587384Sgblack@eecs.umich.edu 10597375Sgblack@eecs.umich.edu#endif //__ARCH_ARM_INSTS_VFP_HH__ 1060