vfp.hh revision 8865
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 438229Snate@binkert.org#include <fenv.h> 448229Snate@binkert.org 458229Snate@binkert.org#include <cmath> 468229Snate@binkert.org 477375Sgblack@eecs.umich.edu#include "arch/arm/insts/misc.hh" 487378Sgblack@eecs.umich.edu#include "arch/arm/miscregs.hh" 497375Sgblack@eecs.umich.edu 507384Sgblack@eecs.umich.edunamespace ArmISA 517384Sgblack@eecs.umich.edu{ 527384Sgblack@eecs.umich.edu 537375Sgblack@eecs.umich.eduenum VfpMicroMode { 547375Sgblack@eecs.umich.edu VfpNotAMicroop, 557375Sgblack@eecs.umich.edu VfpMicroop, 567375Sgblack@eecs.umich.edu VfpFirstMicroop, 577375Sgblack@eecs.umich.edu VfpLastMicroop 587375Sgblack@eecs.umich.edu}; 597375Sgblack@eecs.umich.edu 607375Sgblack@eecs.umich.edutemplate<class T> 617375Sgblack@eecs.umich.edustatic inline void 627375Sgblack@eecs.umich.edusetVfpMicroFlags(VfpMicroMode mode, T &flags) 637375Sgblack@eecs.umich.edu{ 647375Sgblack@eecs.umich.edu switch (mode) { 657375Sgblack@eecs.umich.edu case VfpMicroop: 667375Sgblack@eecs.umich.edu flags[StaticInst::IsMicroop] = true; 677375Sgblack@eecs.umich.edu break; 687375Sgblack@eecs.umich.edu case VfpFirstMicroop: 697375Sgblack@eecs.umich.edu flags[StaticInst::IsMicroop] = 707375Sgblack@eecs.umich.edu flags[StaticInst::IsFirstMicroop] = true; 717375Sgblack@eecs.umich.edu break; 727375Sgblack@eecs.umich.edu case VfpLastMicroop: 737375Sgblack@eecs.umich.edu flags[StaticInst::IsMicroop] = 747375Sgblack@eecs.umich.edu flags[StaticInst::IsLastMicroop] = true; 757375Sgblack@eecs.umich.edu break; 767375Sgblack@eecs.umich.edu case VfpNotAMicroop: 777375Sgblack@eecs.umich.edu break; 787375Sgblack@eecs.umich.edu } 797376Sgblack@eecs.umich.edu if (mode == VfpMicroop || mode == VfpFirstMicroop) { 807376Sgblack@eecs.umich.edu flags[StaticInst::IsDelayedCommit] = true; 817376Sgblack@eecs.umich.edu } 827375Sgblack@eecs.umich.edu} 837375Sgblack@eecs.umich.edu 847378Sgblack@eecs.umich.eduenum FeExceptionBit 857378Sgblack@eecs.umich.edu{ 867378Sgblack@eecs.umich.edu FeDivByZero = FE_DIVBYZERO, 877378Sgblack@eecs.umich.edu FeInexact = FE_INEXACT, 887378Sgblack@eecs.umich.edu FeInvalid = FE_INVALID, 897378Sgblack@eecs.umich.edu FeOverflow = FE_OVERFLOW, 907378Sgblack@eecs.umich.edu FeUnderflow = FE_UNDERFLOW, 917378Sgblack@eecs.umich.edu FeAllExceptions = FE_ALL_EXCEPT 927378Sgblack@eecs.umich.edu}; 937378Sgblack@eecs.umich.edu 947378Sgblack@eecs.umich.eduenum FeRoundingMode 957378Sgblack@eecs.umich.edu{ 967378Sgblack@eecs.umich.edu FeRoundDown = FE_DOWNWARD, 977378Sgblack@eecs.umich.edu FeRoundNearest = FE_TONEAREST, 987378Sgblack@eecs.umich.edu FeRoundZero = FE_TOWARDZERO, 997378Sgblack@eecs.umich.edu FeRoundUpward = FE_UPWARD 1007378Sgblack@eecs.umich.edu}; 1017378Sgblack@eecs.umich.edu 1027378Sgblack@eecs.umich.eduenum VfpRoundingMode 1037378Sgblack@eecs.umich.edu{ 1047378Sgblack@eecs.umich.edu VfpRoundNearest = 0, 1057378Sgblack@eecs.umich.edu VfpRoundUpward = 1, 1067378Sgblack@eecs.umich.edu VfpRoundDown = 2, 1077378Sgblack@eecs.umich.edu VfpRoundZero = 3 1087378Sgblack@eecs.umich.edu}; 1097378Sgblack@eecs.umich.edu 1108737Skoansin.tan@gmail.comstatic inline float bitsToFp(uint64_t, float); 1118865SGiacomo.Gabrielli@arm.comstatic inline double bitsToFp(uint64_t, double); 1128737Skoansin.tan@gmail.comstatic inline uint32_t fpToBits(float); 1138865SGiacomo.Gabrielli@arm.comstatic inline uint64_t fpToBits(double); 1148737Skoansin.tan@gmail.com 1157382Sgblack@eecs.umich.edutemplate <class fpType> 1167396Sgblack@eecs.umich.edustatic inline bool 1177396Sgblack@eecs.umich.eduflushToZero(fpType &op) 1187396Sgblack@eecs.umich.edu{ 1197396Sgblack@eecs.umich.edu fpType junk = 0.0; 1207396Sgblack@eecs.umich.edu if (std::fpclassify(op) == FP_SUBNORMAL) { 1217396Sgblack@eecs.umich.edu uint64_t bitMask = ULL(0x1) << (sizeof(fpType) * 8 - 1); 1227396Sgblack@eecs.umich.edu op = bitsToFp(fpToBits(op) & bitMask, junk); 1237396Sgblack@eecs.umich.edu return true; 1247396Sgblack@eecs.umich.edu } 1257396Sgblack@eecs.umich.edu return false; 1267396Sgblack@eecs.umich.edu} 1277396Sgblack@eecs.umich.edu 1287396Sgblack@eecs.umich.edutemplate <class fpType> 1297396Sgblack@eecs.umich.edustatic inline bool 1307396Sgblack@eecs.umich.eduflushToZero(fpType &op1, fpType &op2) 1317396Sgblack@eecs.umich.edu{ 1327396Sgblack@eecs.umich.edu bool flush1 = flushToZero(op1); 1337396Sgblack@eecs.umich.edu bool flush2 = flushToZero(op2); 1347396Sgblack@eecs.umich.edu return flush1 || flush2; 1357396Sgblack@eecs.umich.edu} 1367396Sgblack@eecs.umich.edu 1377397Sgblack@eecs.umich.edutemplate <class fpType> 1387397Sgblack@eecs.umich.edustatic inline void 1397397Sgblack@eecs.umich.eduvfpFlushToZero(FPSCR &fpscr, fpType &op) 1407397Sgblack@eecs.umich.edu{ 1417397Sgblack@eecs.umich.edu if (fpscr.fz == 1 && flushToZero(op)) { 1427397Sgblack@eecs.umich.edu fpscr.idc = 1; 1437397Sgblack@eecs.umich.edu } 1447397Sgblack@eecs.umich.edu} 1457397Sgblack@eecs.umich.edu 1467397Sgblack@eecs.umich.edutemplate <class fpType> 1477397Sgblack@eecs.umich.edustatic inline void 1487397Sgblack@eecs.umich.eduvfpFlushToZero(FPSCR &fpscr, fpType &op1, fpType &op2) 1497397Sgblack@eecs.umich.edu{ 1507397Sgblack@eecs.umich.edu vfpFlushToZero(fpscr, op1); 1517397Sgblack@eecs.umich.edu vfpFlushToZero(fpscr, op2); 1527397Sgblack@eecs.umich.edu} 1537397Sgblack@eecs.umich.edu 1547384Sgblack@eecs.umich.edustatic inline uint32_t 1557384Sgblack@eecs.umich.edufpToBits(float fp) 1567384Sgblack@eecs.umich.edu{ 1577384Sgblack@eecs.umich.edu union 1587384Sgblack@eecs.umich.edu { 1597384Sgblack@eecs.umich.edu float fp; 1607384Sgblack@eecs.umich.edu uint32_t bits; 1617384Sgblack@eecs.umich.edu } val; 1627384Sgblack@eecs.umich.edu val.fp = fp; 1637384Sgblack@eecs.umich.edu return val.bits; 1647384Sgblack@eecs.umich.edu} 1657384Sgblack@eecs.umich.edu 1667384Sgblack@eecs.umich.edustatic inline uint64_t 1677384Sgblack@eecs.umich.edufpToBits(double fp) 1687384Sgblack@eecs.umich.edu{ 1697384Sgblack@eecs.umich.edu union 1707384Sgblack@eecs.umich.edu { 1717384Sgblack@eecs.umich.edu double fp; 1727384Sgblack@eecs.umich.edu uint64_t bits; 1737384Sgblack@eecs.umich.edu } val; 1747384Sgblack@eecs.umich.edu val.fp = fp; 1757384Sgblack@eecs.umich.edu return val.bits; 1767384Sgblack@eecs.umich.edu} 1777384Sgblack@eecs.umich.edu 1787384Sgblack@eecs.umich.edustatic inline float 1797384Sgblack@eecs.umich.edubitsToFp(uint64_t bits, float junk) 1807384Sgblack@eecs.umich.edu{ 1817384Sgblack@eecs.umich.edu union 1827384Sgblack@eecs.umich.edu { 1837384Sgblack@eecs.umich.edu float fp; 1847384Sgblack@eecs.umich.edu uint32_t bits; 1857384Sgblack@eecs.umich.edu } val; 1867384Sgblack@eecs.umich.edu val.bits = bits; 1877384Sgblack@eecs.umich.edu return val.fp; 1887384Sgblack@eecs.umich.edu} 1897384Sgblack@eecs.umich.edu 1907384Sgblack@eecs.umich.edustatic inline double 1917384Sgblack@eecs.umich.edubitsToFp(uint64_t bits, double junk) 1927384Sgblack@eecs.umich.edu{ 1937384Sgblack@eecs.umich.edu union 1947384Sgblack@eecs.umich.edu { 1957384Sgblack@eecs.umich.edu double fp; 1967384Sgblack@eecs.umich.edu uint64_t bits; 1977384Sgblack@eecs.umich.edu } val; 1987384Sgblack@eecs.umich.edu val.bits = bits; 1997384Sgblack@eecs.umich.edu return val.fp; 2007384Sgblack@eecs.umich.edu} 2017384Sgblack@eecs.umich.edu 2027639Sgblack@eecs.umich.edutemplate <class fpType> 2037639Sgblack@eecs.umich.edustatic bool 2047639Sgblack@eecs.umich.eduisSnan(fpType val) 2057639Sgblack@eecs.umich.edu{ 2067639Sgblack@eecs.umich.edu const bool single = (sizeof(fpType) == sizeof(float)); 2077639Sgblack@eecs.umich.edu const uint64_t qnan = 2087639Sgblack@eecs.umich.edu single ? 0x7fc00000 : ULL(0x7ff8000000000000); 2097639Sgblack@eecs.umich.edu return std::isnan(val) && ((fpToBits(val) & qnan) != qnan); 2107639Sgblack@eecs.umich.edu} 2117639Sgblack@eecs.umich.edu 2127396Sgblack@eecs.umich.edutypedef int VfpSavedState; 2137396Sgblack@eecs.umich.edu 2147430Sgblack@eecs.umich.eduVfpSavedState prepFpState(uint32_t rMode); 2157639Sgblack@eecs.umich.eduvoid finishVfp(FPSCR &fpscr, VfpSavedState state, bool flush); 2167396Sgblack@eecs.umich.edu 2177384Sgblack@eecs.umich.edutemplate <class fpType> 2187430Sgblack@eecs.umich.edufpType fixDest(FPSCR fpscr, fpType val, fpType op1); 2197386Sgblack@eecs.umich.edu 2207386Sgblack@eecs.umich.edutemplate <class fpType> 2217430Sgblack@eecs.umich.edufpType fixDest(FPSCR fpscr, fpType val, fpType op1, fpType op2); 2227384Sgblack@eecs.umich.edu 2237386Sgblack@eecs.umich.edutemplate <class fpType> 2247430Sgblack@eecs.umich.edufpType fixDivDest(FPSCR fpscr, fpType val, fpType op1, fpType op2); 2257386Sgblack@eecs.umich.edu 2267430Sgblack@eecs.umich.edufloat fixFpDFpSDest(FPSCR fpscr, double val); 2277430Sgblack@eecs.umich.edudouble fixFpSFpDDest(FPSCR fpscr, float val); 2287386Sgblack@eecs.umich.edu 2297639Sgblack@eecs.umich.eduuint16_t vcvtFpSFpH(FPSCR &fpscr, bool flush, bool defaultNan, 2307639Sgblack@eecs.umich.edu uint32_t rMode, bool ahp, float op); 2317639Sgblack@eecs.umich.edufloat vcvtFpHFpS(FPSCR &fpscr, bool defaultNan, bool ahp, uint16_t op); 2327398Sgblack@eecs.umich.edu 2337396Sgblack@eecs.umich.edustatic inline double 2347396Sgblack@eecs.umich.edumakeDouble(uint32_t low, uint32_t high) 2357396Sgblack@eecs.umich.edu{ 2367396Sgblack@eecs.umich.edu double junk = 0.0; 2377396Sgblack@eecs.umich.edu return bitsToFp((uint64_t)low | ((uint64_t)high << 32), junk); 2387396Sgblack@eecs.umich.edu} 2397396Sgblack@eecs.umich.edu 2407396Sgblack@eecs.umich.edustatic inline uint32_t 2417396Sgblack@eecs.umich.edulowFromDouble(double val) 2427396Sgblack@eecs.umich.edu{ 2437396Sgblack@eecs.umich.edu return fpToBits(val); 2447396Sgblack@eecs.umich.edu} 2457396Sgblack@eecs.umich.edu 2467396Sgblack@eecs.umich.edustatic inline uint32_t 2477396Sgblack@eecs.umich.eduhighFromDouble(double val) 2487396Sgblack@eecs.umich.edu{ 2497396Sgblack@eecs.umich.edu return fpToBits(val) >> 32; 2507396Sgblack@eecs.umich.edu} 2517396Sgblack@eecs.umich.edu 2527430Sgblack@eecs.umich.eduuint64_t vfpFpSToFixed(float val, bool isSigned, bool half, 2537430Sgblack@eecs.umich.edu uint8_t imm, bool rzero = true); 2547639Sgblack@eecs.umich.edufloat vfpUFixedToFpS(bool flush, bool defaultNan, 2557639Sgblack@eecs.umich.edu uint32_t val, bool half, uint8_t imm); 2567639Sgblack@eecs.umich.edufloat vfpSFixedToFpS(bool flush, bool defaultNan, 2577639Sgblack@eecs.umich.edu int32_t val, bool half, uint8_t imm); 2587382Sgblack@eecs.umich.edu 2597430Sgblack@eecs.umich.eduuint64_t vfpFpDToFixed(double val, bool isSigned, bool half, 2607430Sgblack@eecs.umich.edu uint8_t imm, bool rzero = true); 2617639Sgblack@eecs.umich.edudouble vfpUFixedToFpD(bool flush, bool defaultNan, 2627639Sgblack@eecs.umich.edu uint32_t val, bool half, uint8_t imm); 2637639Sgblack@eecs.umich.edudouble vfpSFixedToFpD(bool flush, bool defaultNan, 2647639Sgblack@eecs.umich.edu int32_t val, bool half, uint8_t imm); 2657639Sgblack@eecs.umich.edu 2667639Sgblack@eecs.umich.edufloat fprSqrtEstimate(FPSCR &fpscr, float op); 2677639Sgblack@eecs.umich.eduuint32_t unsignedRSqrtEstimate(uint32_t op); 2687639Sgblack@eecs.umich.edu 2697639Sgblack@eecs.umich.edufloat fpRecipEstimate(FPSCR &fpscr, float op); 2707639Sgblack@eecs.umich.eduuint32_t unsignedRecipEstimate(uint32_t op); 2717379Sgblack@eecs.umich.edu 2727376Sgblack@eecs.umich.educlass VfpMacroOp : public PredMacroOp 2737376Sgblack@eecs.umich.edu{ 2747376Sgblack@eecs.umich.edu public: 2757376Sgblack@eecs.umich.edu static bool 2767376Sgblack@eecs.umich.edu inScalarBank(IntRegIndex idx) 2777376Sgblack@eecs.umich.edu { 2787376Sgblack@eecs.umich.edu return (idx % 32) < 8; 2797376Sgblack@eecs.umich.edu } 2807376Sgblack@eecs.umich.edu 2817376Sgblack@eecs.umich.edu protected: 2827376Sgblack@eecs.umich.edu bool wide; 2837376Sgblack@eecs.umich.edu 2847376Sgblack@eecs.umich.edu VfpMacroOp(const char *mnem, ExtMachInst _machInst, 2857376Sgblack@eecs.umich.edu OpClass __opClass, bool _wide) : 2867376Sgblack@eecs.umich.edu PredMacroOp(mnem, _machInst, __opClass), wide(_wide) 2877376Sgblack@eecs.umich.edu {} 2887376Sgblack@eecs.umich.edu 2897430Sgblack@eecs.umich.edu IntRegIndex addStride(IntRegIndex idx, unsigned stride); 2907430Sgblack@eecs.umich.edu void nextIdxs(IntRegIndex &dest, IntRegIndex &op1, IntRegIndex &op2); 2917430Sgblack@eecs.umich.edu void nextIdxs(IntRegIndex &dest, IntRegIndex &op1); 2927430Sgblack@eecs.umich.edu void nextIdxs(IntRegIndex &dest); 2937376Sgblack@eecs.umich.edu}; 2947376Sgblack@eecs.umich.edu 2957396Sgblack@eecs.umich.edustatic inline float 2967396Sgblack@eecs.umich.edufpAddS(float a, float b) 2977396Sgblack@eecs.umich.edu{ 2987396Sgblack@eecs.umich.edu return a + b; 2997396Sgblack@eecs.umich.edu} 3007396Sgblack@eecs.umich.edu 3017396Sgblack@eecs.umich.edustatic inline double 3027396Sgblack@eecs.umich.edufpAddD(double a, double b) 3037396Sgblack@eecs.umich.edu{ 3047396Sgblack@eecs.umich.edu return a + b; 3057396Sgblack@eecs.umich.edu} 3067396Sgblack@eecs.umich.edu 3077396Sgblack@eecs.umich.edustatic inline float 3087396Sgblack@eecs.umich.edufpSubS(float a, float b) 3097396Sgblack@eecs.umich.edu{ 3107396Sgblack@eecs.umich.edu return a - b; 3117396Sgblack@eecs.umich.edu} 3127396Sgblack@eecs.umich.edu 3137396Sgblack@eecs.umich.edustatic inline double 3147396Sgblack@eecs.umich.edufpSubD(double a, double b) 3157396Sgblack@eecs.umich.edu{ 3167396Sgblack@eecs.umich.edu return a - b; 3177396Sgblack@eecs.umich.edu} 3187396Sgblack@eecs.umich.edu 3197396Sgblack@eecs.umich.edustatic inline float 3207396Sgblack@eecs.umich.edufpDivS(float a, float b) 3217396Sgblack@eecs.umich.edu{ 3227396Sgblack@eecs.umich.edu return a / b; 3237396Sgblack@eecs.umich.edu} 3247396Sgblack@eecs.umich.edu 3257396Sgblack@eecs.umich.edustatic inline double 3267396Sgblack@eecs.umich.edufpDivD(double a, double b) 3277396Sgblack@eecs.umich.edu{ 3287396Sgblack@eecs.umich.edu return a / b; 3297396Sgblack@eecs.umich.edu} 3307396Sgblack@eecs.umich.edu 3317396Sgblack@eecs.umich.edustatic inline float 3327396Sgblack@eecs.umich.edufpMulS(float a, float b) 3337396Sgblack@eecs.umich.edu{ 3347396Sgblack@eecs.umich.edu return a * b; 3357396Sgblack@eecs.umich.edu} 3367396Sgblack@eecs.umich.edu 3377396Sgblack@eecs.umich.edustatic inline double 3387396Sgblack@eecs.umich.edufpMulD(double a, double b) 3397396Sgblack@eecs.umich.edu{ 3407396Sgblack@eecs.umich.edu return a * b; 3417396Sgblack@eecs.umich.edu} 3427396Sgblack@eecs.umich.edu 3437639Sgblack@eecs.umich.edustatic inline float 3447639Sgblack@eecs.umich.edufpMaxS(float a, float b) 3457639Sgblack@eecs.umich.edu{ 3467639Sgblack@eecs.umich.edu // Handle comparisons of +0 and -0. 3477639Sgblack@eecs.umich.edu if (!std::signbit(a) && std::signbit(b)) 3487639Sgblack@eecs.umich.edu return a; 3497639Sgblack@eecs.umich.edu return fmaxf(a, b); 3507639Sgblack@eecs.umich.edu} 3517639Sgblack@eecs.umich.edu 3527639Sgblack@eecs.umich.edustatic inline float 3537639Sgblack@eecs.umich.edufpMinS(float a, float b) 3547639Sgblack@eecs.umich.edu{ 3557639Sgblack@eecs.umich.edu // Handle comparisons of +0 and -0. 3567639Sgblack@eecs.umich.edu if (std::signbit(a) && !std::signbit(b)) 3577639Sgblack@eecs.umich.edu return a; 3587639Sgblack@eecs.umich.edu return fminf(a, b); 3597639Sgblack@eecs.umich.edu} 3607639Sgblack@eecs.umich.edu 3617639Sgblack@eecs.umich.edustatic inline float 3627639Sgblack@eecs.umich.edufpRSqrtsS(float a, float b) 3637639Sgblack@eecs.umich.edu{ 3647639Sgblack@eecs.umich.edu int fpClassA = std::fpclassify(a); 3657639Sgblack@eecs.umich.edu int fpClassB = std::fpclassify(b); 3667639Sgblack@eecs.umich.edu float aXb; 3677639Sgblack@eecs.umich.edu int fpClassAxB; 3687639Sgblack@eecs.umich.edu 3697639Sgblack@eecs.umich.edu if ((fpClassA == FP_ZERO && fpClassB == FP_INFINITE) || 3707639Sgblack@eecs.umich.edu (fpClassA == FP_INFINITE && fpClassB == FP_ZERO)) { 3717639Sgblack@eecs.umich.edu return 1.5; 3727639Sgblack@eecs.umich.edu } 3737639Sgblack@eecs.umich.edu aXb = a*b; 3747639Sgblack@eecs.umich.edu fpClassAxB = std::fpclassify(aXb); 3757639Sgblack@eecs.umich.edu if(fpClassAxB == FP_SUBNORMAL) { 3767639Sgblack@eecs.umich.edu feraiseexcept(FeUnderflow); 3777639Sgblack@eecs.umich.edu return 1.5; 3787639Sgblack@eecs.umich.edu } 3797639Sgblack@eecs.umich.edu return (3.0 - (a * b)) / 2.0; 3807639Sgblack@eecs.umich.edu} 3817639Sgblack@eecs.umich.edu 3827639Sgblack@eecs.umich.edustatic inline float 3837639Sgblack@eecs.umich.edufpRecpsS(float a, float b) 3847639Sgblack@eecs.umich.edu{ 3857639Sgblack@eecs.umich.edu int fpClassA = std::fpclassify(a); 3867639Sgblack@eecs.umich.edu int fpClassB = std::fpclassify(b); 3877639Sgblack@eecs.umich.edu float aXb; 3887639Sgblack@eecs.umich.edu int fpClassAxB; 3897639Sgblack@eecs.umich.edu 3907639Sgblack@eecs.umich.edu if ((fpClassA == FP_ZERO && fpClassB == FP_INFINITE) || 3917639Sgblack@eecs.umich.edu (fpClassA == FP_INFINITE && fpClassB == FP_ZERO)) { 3927639Sgblack@eecs.umich.edu return 2.0; 3937639Sgblack@eecs.umich.edu } 3947639Sgblack@eecs.umich.edu aXb = a*b; 3957639Sgblack@eecs.umich.edu fpClassAxB = std::fpclassify(aXb); 3967639Sgblack@eecs.umich.edu if(fpClassAxB == FP_SUBNORMAL) { 3977639Sgblack@eecs.umich.edu feraiseexcept(FeUnderflow); 3987639Sgblack@eecs.umich.edu return 2.0; 3997639Sgblack@eecs.umich.edu } 4007639Sgblack@eecs.umich.edu return 2.0 - (a * b); 4017639Sgblack@eecs.umich.edu} 4027639Sgblack@eecs.umich.edu 4037396Sgblack@eecs.umich.educlass FpOp : public PredOp 4047375Sgblack@eecs.umich.edu{ 4057375Sgblack@eecs.umich.edu protected: 4067396Sgblack@eecs.umich.edu FpOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : 4077396Sgblack@eecs.umich.edu PredOp(mnem, _machInst, __opClass) 4087396Sgblack@eecs.umich.edu {} 4097396Sgblack@eecs.umich.edu 4107396Sgblack@eecs.umich.edu virtual float 4117396Sgblack@eecs.umich.edu doOp(float op1, float op2) const 4127396Sgblack@eecs.umich.edu { 4137396Sgblack@eecs.umich.edu panic("Unimplemented version of doOp called.\n"); 4147396Sgblack@eecs.umich.edu } 4157396Sgblack@eecs.umich.edu 4167396Sgblack@eecs.umich.edu virtual float 4177396Sgblack@eecs.umich.edu doOp(float op1) const 4187396Sgblack@eecs.umich.edu { 4197396Sgblack@eecs.umich.edu panic("Unimplemented version of doOp called.\n"); 4207396Sgblack@eecs.umich.edu } 4217396Sgblack@eecs.umich.edu 4227396Sgblack@eecs.umich.edu virtual double 4237396Sgblack@eecs.umich.edu doOp(double op1, double op2) const 4247396Sgblack@eecs.umich.edu { 4257396Sgblack@eecs.umich.edu panic("Unimplemented version of doOp called.\n"); 4267396Sgblack@eecs.umich.edu } 4277396Sgblack@eecs.umich.edu 4287396Sgblack@eecs.umich.edu virtual double 4297396Sgblack@eecs.umich.edu doOp(double op1) const 4307396Sgblack@eecs.umich.edu { 4317396Sgblack@eecs.umich.edu panic("Unimplemented version of doOp called.\n"); 4327396Sgblack@eecs.umich.edu } 4337396Sgblack@eecs.umich.edu 4347396Sgblack@eecs.umich.edu double 4357396Sgblack@eecs.umich.edu dbl(uint32_t low, uint32_t high) const 4367396Sgblack@eecs.umich.edu { 4377396Sgblack@eecs.umich.edu double junk = 0.0; 4387396Sgblack@eecs.umich.edu return bitsToFp((uint64_t)low | ((uint64_t)high << 32), junk); 4397396Sgblack@eecs.umich.edu } 4407396Sgblack@eecs.umich.edu 4417396Sgblack@eecs.umich.edu uint32_t 4427396Sgblack@eecs.umich.edu dblLow(double val) const 4437396Sgblack@eecs.umich.edu { 4447396Sgblack@eecs.umich.edu return fpToBits(val); 4457396Sgblack@eecs.umich.edu } 4467396Sgblack@eecs.umich.edu 4477396Sgblack@eecs.umich.edu uint32_t 4487396Sgblack@eecs.umich.edu dblHi(double val) const 4497396Sgblack@eecs.umich.edu { 4507396Sgblack@eecs.umich.edu return fpToBits(val) >> 32; 4517396Sgblack@eecs.umich.edu } 4527396Sgblack@eecs.umich.edu 4537396Sgblack@eecs.umich.edu template <class fpType> 4547396Sgblack@eecs.umich.edu fpType 4557639Sgblack@eecs.umich.edu processNans(FPSCR &fpscr, bool &done, bool defaultNan, 4567639Sgblack@eecs.umich.edu fpType op1, fpType op2) const; 4577639Sgblack@eecs.umich.edu 4587639Sgblack@eecs.umich.edu template <class fpType> 4597639Sgblack@eecs.umich.edu fpType 4607396Sgblack@eecs.umich.edu binaryOp(FPSCR &fpscr, fpType op1, fpType op2, 4617396Sgblack@eecs.umich.edu fpType (*func)(fpType, fpType), 4627639Sgblack@eecs.umich.edu bool flush, bool defaultNan, uint32_t rMode) const; 4637396Sgblack@eecs.umich.edu 4647396Sgblack@eecs.umich.edu template <class fpType> 4657396Sgblack@eecs.umich.edu fpType 4667396Sgblack@eecs.umich.edu unaryOp(FPSCR &fpscr, fpType op1, 4677396Sgblack@eecs.umich.edu fpType (*func)(fpType), 4687430Sgblack@eecs.umich.edu bool flush, uint32_t rMode) const; 4697720Sgblack@eecs.umich.edu 4707720Sgblack@eecs.umich.edu void 4717720Sgblack@eecs.umich.edu advancePC(PCState &pcState) const 4727720Sgblack@eecs.umich.edu { 4737720Sgblack@eecs.umich.edu if (flags[IsLastMicroop]) { 4747720Sgblack@eecs.umich.edu pcState.uEnd(); 4757720Sgblack@eecs.umich.edu } else if (flags[IsMicroop]) { 4767720Sgblack@eecs.umich.edu pcState.uAdvance(); 4777720Sgblack@eecs.umich.edu } else { 4787720Sgblack@eecs.umich.edu pcState.advance(); 4797720Sgblack@eecs.umich.edu } 4807720Sgblack@eecs.umich.edu } 4817396Sgblack@eecs.umich.edu}; 4827396Sgblack@eecs.umich.edu 4837396Sgblack@eecs.umich.educlass FpRegRegOp : public FpOp 4847396Sgblack@eecs.umich.edu{ 4857396Sgblack@eecs.umich.edu protected: 4867396Sgblack@eecs.umich.edu IntRegIndex dest; 4877396Sgblack@eecs.umich.edu IntRegIndex op1; 4887396Sgblack@eecs.umich.edu 4897396Sgblack@eecs.umich.edu FpRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 4907396Sgblack@eecs.umich.edu IntRegIndex _dest, IntRegIndex _op1, 4917396Sgblack@eecs.umich.edu VfpMicroMode mode = VfpNotAMicroop) : 4927396Sgblack@eecs.umich.edu FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1) 4937375Sgblack@eecs.umich.edu { 4947375Sgblack@eecs.umich.edu setVfpMicroFlags(mode, flags); 4957375Sgblack@eecs.umich.edu } 4967396Sgblack@eecs.umich.edu 4977396Sgblack@eecs.umich.edu std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 4987375Sgblack@eecs.umich.edu}; 4997375Sgblack@eecs.umich.edu 5007396Sgblack@eecs.umich.educlass FpRegImmOp : public FpOp 5017375Sgblack@eecs.umich.edu{ 5027375Sgblack@eecs.umich.edu protected: 5037396Sgblack@eecs.umich.edu IntRegIndex dest; 5047396Sgblack@eecs.umich.edu uint64_t imm; 5057396Sgblack@eecs.umich.edu 5067396Sgblack@eecs.umich.edu FpRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 5077396Sgblack@eecs.umich.edu IntRegIndex _dest, uint64_t _imm, 5087396Sgblack@eecs.umich.edu VfpMicroMode mode = VfpNotAMicroop) : 5097396Sgblack@eecs.umich.edu FpOp(mnem, _machInst, __opClass), dest(_dest), imm(_imm) 5107375Sgblack@eecs.umich.edu { 5117375Sgblack@eecs.umich.edu setVfpMicroFlags(mode, flags); 5127375Sgblack@eecs.umich.edu } 5137396Sgblack@eecs.umich.edu 5147396Sgblack@eecs.umich.edu std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 5157375Sgblack@eecs.umich.edu}; 5167375Sgblack@eecs.umich.edu 5177396Sgblack@eecs.umich.educlass FpRegRegImmOp : public FpOp 5187375Sgblack@eecs.umich.edu{ 5197375Sgblack@eecs.umich.edu protected: 5207396Sgblack@eecs.umich.edu IntRegIndex dest; 5217396Sgblack@eecs.umich.edu IntRegIndex op1; 5227396Sgblack@eecs.umich.edu uint64_t imm; 5237396Sgblack@eecs.umich.edu 5247396Sgblack@eecs.umich.edu FpRegRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 5257396Sgblack@eecs.umich.edu IntRegIndex _dest, IntRegIndex _op1, 5267396Sgblack@eecs.umich.edu uint64_t _imm, VfpMicroMode mode = VfpNotAMicroop) : 5277396Sgblack@eecs.umich.edu FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1), imm(_imm) 5287375Sgblack@eecs.umich.edu { 5297375Sgblack@eecs.umich.edu setVfpMicroFlags(mode, flags); 5307375Sgblack@eecs.umich.edu } 5317396Sgblack@eecs.umich.edu 5327396Sgblack@eecs.umich.edu std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 5337375Sgblack@eecs.umich.edu}; 5347375Sgblack@eecs.umich.edu 5357396Sgblack@eecs.umich.educlass FpRegRegRegOp : public FpOp 5367375Sgblack@eecs.umich.edu{ 5377375Sgblack@eecs.umich.edu protected: 5387396Sgblack@eecs.umich.edu IntRegIndex dest; 5397396Sgblack@eecs.umich.edu IntRegIndex op1; 5407396Sgblack@eecs.umich.edu IntRegIndex op2; 5417396Sgblack@eecs.umich.edu 5427396Sgblack@eecs.umich.edu FpRegRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 5437396Sgblack@eecs.umich.edu IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, 5447396Sgblack@eecs.umich.edu VfpMicroMode mode = VfpNotAMicroop) : 5457396Sgblack@eecs.umich.edu FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2) 5467375Sgblack@eecs.umich.edu { 5477375Sgblack@eecs.umich.edu setVfpMicroFlags(mode, flags); 5487375Sgblack@eecs.umich.edu } 5497396Sgblack@eecs.umich.edu 5507396Sgblack@eecs.umich.edu std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 5517375Sgblack@eecs.umich.edu}; 5527375Sgblack@eecs.umich.edu 5537639Sgblack@eecs.umich.educlass FpRegRegRegImmOp : public FpOp 5547639Sgblack@eecs.umich.edu{ 5557639Sgblack@eecs.umich.edu protected: 5567639Sgblack@eecs.umich.edu IntRegIndex dest; 5577639Sgblack@eecs.umich.edu IntRegIndex op1; 5587639Sgblack@eecs.umich.edu IntRegIndex op2; 5597639Sgblack@eecs.umich.edu uint64_t imm; 5607639Sgblack@eecs.umich.edu 5617639Sgblack@eecs.umich.edu FpRegRegRegImmOp(const char *mnem, ExtMachInst _machInst, 5627639Sgblack@eecs.umich.edu OpClass __opClass, IntRegIndex _dest, 5637639Sgblack@eecs.umich.edu IntRegIndex _op1, IntRegIndex _op2, 5647639Sgblack@eecs.umich.edu uint64_t _imm, VfpMicroMode mode = VfpNotAMicroop) : 5657639Sgblack@eecs.umich.edu FpOp(mnem, _machInst, __opClass), 5667639Sgblack@eecs.umich.edu dest(_dest), op1(_op1), op2(_op2), imm(_imm) 5677639Sgblack@eecs.umich.edu { 5687639Sgblack@eecs.umich.edu setVfpMicroFlags(mode, flags); 5697639Sgblack@eecs.umich.edu } 5707639Sgblack@eecs.umich.edu 5717639Sgblack@eecs.umich.edu std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 5727639Sgblack@eecs.umich.edu}; 5737639Sgblack@eecs.umich.edu 5747384Sgblack@eecs.umich.edu} 5757384Sgblack@eecs.umich.edu 5767375Sgblack@eecs.umich.edu#endif //__ARCH_ARM_INSTS_VFP_HH__ 577