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