vfp.hh revision 7382
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
487375Sgblack@eecs.umich.eduenum VfpMicroMode {
497375Sgblack@eecs.umich.edu    VfpNotAMicroop,
507375Sgblack@eecs.umich.edu    VfpMicroop,
517375Sgblack@eecs.umich.edu    VfpFirstMicroop,
527375Sgblack@eecs.umich.edu    VfpLastMicroop
537375Sgblack@eecs.umich.edu};
547375Sgblack@eecs.umich.edu
557375Sgblack@eecs.umich.edutemplate<class T>
567375Sgblack@eecs.umich.edustatic inline void
577375Sgblack@eecs.umich.edusetVfpMicroFlags(VfpMicroMode mode, T &flags)
587375Sgblack@eecs.umich.edu{
597375Sgblack@eecs.umich.edu    switch (mode) {
607375Sgblack@eecs.umich.edu      case VfpMicroop:
617375Sgblack@eecs.umich.edu        flags[StaticInst::IsMicroop] = true;
627375Sgblack@eecs.umich.edu        break;
637375Sgblack@eecs.umich.edu      case VfpFirstMicroop:
647375Sgblack@eecs.umich.edu        flags[StaticInst::IsMicroop] =
657375Sgblack@eecs.umich.edu            flags[StaticInst::IsFirstMicroop] = true;
667375Sgblack@eecs.umich.edu        break;
677375Sgblack@eecs.umich.edu      case VfpLastMicroop:
687375Sgblack@eecs.umich.edu        flags[StaticInst::IsMicroop] =
697375Sgblack@eecs.umich.edu            flags[StaticInst::IsLastMicroop] = true;
707375Sgblack@eecs.umich.edu        break;
717375Sgblack@eecs.umich.edu      case VfpNotAMicroop:
727375Sgblack@eecs.umich.edu        break;
737375Sgblack@eecs.umich.edu    }
747376Sgblack@eecs.umich.edu    if (mode == VfpMicroop || mode == VfpFirstMicroop) {
757376Sgblack@eecs.umich.edu        flags[StaticInst::IsDelayedCommit] = true;
767376Sgblack@eecs.umich.edu    }
777375Sgblack@eecs.umich.edu}
787375Sgblack@eecs.umich.edu
797378Sgblack@eecs.umich.eduenum FeExceptionBit
807378Sgblack@eecs.umich.edu{
817378Sgblack@eecs.umich.edu    FeDivByZero = FE_DIVBYZERO,
827378Sgblack@eecs.umich.edu    FeInexact = FE_INEXACT,
837378Sgblack@eecs.umich.edu    FeInvalid = FE_INVALID,
847378Sgblack@eecs.umich.edu    FeOverflow = FE_OVERFLOW,
857378Sgblack@eecs.umich.edu    FeUnderflow = FE_UNDERFLOW,
867378Sgblack@eecs.umich.edu    FeAllExceptions = FE_ALL_EXCEPT
877378Sgblack@eecs.umich.edu};
887378Sgblack@eecs.umich.edu
897378Sgblack@eecs.umich.eduenum FeRoundingMode
907378Sgblack@eecs.umich.edu{
917378Sgblack@eecs.umich.edu    FeRoundDown = FE_DOWNWARD,
927378Sgblack@eecs.umich.edu    FeRoundNearest = FE_TONEAREST,
937378Sgblack@eecs.umich.edu    FeRoundZero = FE_TOWARDZERO,
947378Sgblack@eecs.umich.edu    FeRoundUpward = FE_UPWARD
957378Sgblack@eecs.umich.edu};
967378Sgblack@eecs.umich.edu
977378Sgblack@eecs.umich.eduenum VfpRoundingMode
987378Sgblack@eecs.umich.edu{
997378Sgblack@eecs.umich.edu    VfpRoundNearest = 0,
1007378Sgblack@eecs.umich.edu    VfpRoundUpward = 1,
1017378Sgblack@eecs.umich.edu    VfpRoundDown = 2,
1027378Sgblack@eecs.umich.edu    VfpRoundZero = 3
1037378Sgblack@eecs.umich.edu};
1047378Sgblack@eecs.umich.edu
1057382Sgblack@eecs.umich.edutemplate <class fpType>
1067382Sgblack@eecs.umich.edustatic inline void
1077382Sgblack@eecs.umich.eduvfpFlushToZero(uint32_t &_fpscr, fpType &op)
1087382Sgblack@eecs.umich.edu{
1097382Sgblack@eecs.umich.edu    FPSCR fpscr = _fpscr;
1107382Sgblack@eecs.umich.edu    if (fpscr.fz == 1 && (std::fpclassify(op) == FP_SUBNORMAL)) {
1117382Sgblack@eecs.umich.edu        fpscr.idc = 1;
1127382Sgblack@eecs.umich.edu        op = 0;
1137382Sgblack@eecs.umich.edu    }
1147382Sgblack@eecs.umich.edu    _fpscr = fpscr;
1157382Sgblack@eecs.umich.edu}
1167382Sgblack@eecs.umich.edu
1177382Sgblack@eecs.umich.edutemplate <class fpType>
1187382Sgblack@eecs.umich.edustatic inline void
1197382Sgblack@eecs.umich.eduvfpFlushToZero(uint32_t &fpscr, fpType &op1, fpType &op2)
1207382Sgblack@eecs.umich.edu{
1217382Sgblack@eecs.umich.edu    vfpFlushToZero(fpscr, op1);
1227382Sgblack@eecs.umich.edu    vfpFlushToZero(fpscr, op2);
1237382Sgblack@eecs.umich.edu}
1247382Sgblack@eecs.umich.edu
1257379Sgblack@eecs.umich.edustatic inline uint64_t
1267379Sgblack@eecs.umich.eduvfpFpSToFixed(float val, bool isSigned, bool half, uint8_t imm)
1277379Sgblack@eecs.umich.edu{
1287379Sgblack@eecs.umich.edu    fesetround(FeRoundZero);
1297379Sgblack@eecs.umich.edu    val = val * powf(2.0, imm);
1307379Sgblack@eecs.umich.edu    __asm__ __volatile__("" : "=m" (val) : "m" (val));
1317379Sgblack@eecs.umich.edu    feclearexcept(FeAllExceptions);
1327382Sgblack@eecs.umich.edu    __asm__ __volatile__("" : "=m" (val) : "m" (val));
1337382Sgblack@eecs.umich.edu    float origVal = val;
1347382Sgblack@eecs.umich.edu    val = rintf(val);
1357382Sgblack@eecs.umich.edu    int fpType = std::fpclassify(val);
1367382Sgblack@eecs.umich.edu    if (fpType == FP_SUBNORMAL || fpType == FP_NAN) {
1377382Sgblack@eecs.umich.edu        if (fpType == FP_NAN) {
1387382Sgblack@eecs.umich.edu            feraiseexcept(FeInvalid);
1397382Sgblack@eecs.umich.edu        }
1407382Sgblack@eecs.umich.edu        val = 0.0;
1417382Sgblack@eecs.umich.edu    } else if (origVal != val) {
1427382Sgblack@eecs.umich.edu        feraiseexcept(FeInexact);
1437382Sgblack@eecs.umich.edu    }
1447382Sgblack@eecs.umich.edu
1457379Sgblack@eecs.umich.edu    if (isSigned) {
1467379Sgblack@eecs.umich.edu        if (half) {
1477381Sgblack@eecs.umich.edu            if ((double)val < (int16_t)(1 << 15)) {
1487379Sgblack@eecs.umich.edu                feraiseexcept(FeInvalid);
1497382Sgblack@eecs.umich.edu                feclearexcept(FeInexact);
1507379Sgblack@eecs.umich.edu                return (int16_t)(1 << 15);
1517379Sgblack@eecs.umich.edu            }
1527381Sgblack@eecs.umich.edu            if ((double)val > (int16_t)mask(15)) {
1537379Sgblack@eecs.umich.edu                feraiseexcept(FeInvalid);
1547382Sgblack@eecs.umich.edu                feclearexcept(FeInexact);
1557379Sgblack@eecs.umich.edu                return (int16_t)mask(15);
1567379Sgblack@eecs.umich.edu            }
1577379Sgblack@eecs.umich.edu            return (int16_t)val;
1587379Sgblack@eecs.umich.edu        } else {
1597381Sgblack@eecs.umich.edu            if ((double)val < (int32_t)(1 << 31)) {
1607379Sgblack@eecs.umich.edu                feraiseexcept(FeInvalid);
1617382Sgblack@eecs.umich.edu                feclearexcept(FeInexact);
1627379Sgblack@eecs.umich.edu                return (int32_t)(1 << 31);
1637379Sgblack@eecs.umich.edu            }
1647381Sgblack@eecs.umich.edu            if ((double)val > (int32_t)mask(31)) {
1657379Sgblack@eecs.umich.edu                feraiseexcept(FeInvalid);
1667382Sgblack@eecs.umich.edu                feclearexcept(FeInexact);
1677379Sgblack@eecs.umich.edu                return (int32_t)mask(31);
1687379Sgblack@eecs.umich.edu            }
1697379Sgblack@eecs.umich.edu            return (int32_t)val;
1707379Sgblack@eecs.umich.edu        }
1717379Sgblack@eecs.umich.edu    } else {
1727379Sgblack@eecs.umich.edu        if (half) {
1737381Sgblack@eecs.umich.edu            if ((double)val < 0) {
1747379Sgblack@eecs.umich.edu                feraiseexcept(FeInvalid);
1757382Sgblack@eecs.umich.edu                feclearexcept(FeInexact);
1767379Sgblack@eecs.umich.edu                return 0;
1777379Sgblack@eecs.umich.edu            }
1787381Sgblack@eecs.umich.edu            if ((double)val > (mask(16))) {
1797379Sgblack@eecs.umich.edu                feraiseexcept(FeInvalid);
1807382Sgblack@eecs.umich.edu                feclearexcept(FeInexact);
1817379Sgblack@eecs.umich.edu                return mask(16);
1827379Sgblack@eecs.umich.edu            }
1837379Sgblack@eecs.umich.edu            return (uint16_t)val;
1847379Sgblack@eecs.umich.edu        } else {
1857381Sgblack@eecs.umich.edu            if ((double)val < 0) {
1867379Sgblack@eecs.umich.edu                feraiseexcept(FeInvalid);
1877382Sgblack@eecs.umich.edu                feclearexcept(FeInexact);
1887379Sgblack@eecs.umich.edu                return 0;
1897379Sgblack@eecs.umich.edu            }
1907381Sgblack@eecs.umich.edu            if ((double)val > (mask(32))) {
1917379Sgblack@eecs.umich.edu                feraiseexcept(FeInvalid);
1927382Sgblack@eecs.umich.edu                feclearexcept(FeInexact);
1937379Sgblack@eecs.umich.edu                return mask(32);
1947379Sgblack@eecs.umich.edu            }
1957379Sgblack@eecs.umich.edu            return (uint32_t)val;
1967379Sgblack@eecs.umich.edu        }
1977379Sgblack@eecs.umich.edu    }
1987379Sgblack@eecs.umich.edu}
1997379Sgblack@eecs.umich.edu
2007379Sgblack@eecs.umich.edustatic inline float
2017379Sgblack@eecs.umich.eduvfpUFixedToFpS(uint32_t val, bool half, uint8_t imm)
2027379Sgblack@eecs.umich.edu{
2037379Sgblack@eecs.umich.edu    fesetround(FeRoundNearest);
2047379Sgblack@eecs.umich.edu    if (half)
2057379Sgblack@eecs.umich.edu        val = (uint16_t)val;
2067382Sgblack@eecs.umich.edu    float scale = powf(2.0, imm);
2077382Sgblack@eecs.umich.edu    __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
2087382Sgblack@eecs.umich.edu    feclearexcept(FeAllExceptions);
2097382Sgblack@eecs.umich.edu    __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
2107382Sgblack@eecs.umich.edu    return val / scale;
2117379Sgblack@eecs.umich.edu}
2127379Sgblack@eecs.umich.edu
2137379Sgblack@eecs.umich.edustatic inline float
2147379Sgblack@eecs.umich.eduvfpSFixedToFpS(int32_t val, bool half, uint8_t imm)
2157379Sgblack@eecs.umich.edu{
2167379Sgblack@eecs.umich.edu    fesetround(FeRoundNearest);
2177379Sgblack@eecs.umich.edu    if (half)
2187379Sgblack@eecs.umich.edu        val = sext<16>(val & mask(16));
2197382Sgblack@eecs.umich.edu    float scale = powf(2.0, imm);
2207382Sgblack@eecs.umich.edu    __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
2217382Sgblack@eecs.umich.edu    feclearexcept(FeAllExceptions);
2227382Sgblack@eecs.umich.edu    __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
2237382Sgblack@eecs.umich.edu    return val / scale;
2247379Sgblack@eecs.umich.edu}
2257379Sgblack@eecs.umich.edu
2267379Sgblack@eecs.umich.edustatic inline uint64_t
2277379Sgblack@eecs.umich.eduvfpFpDToFixed(double val, bool isSigned, bool half, uint8_t imm)
2287379Sgblack@eecs.umich.edu{
2297382Sgblack@eecs.umich.edu    fesetround(FeRoundNearest);
2307379Sgblack@eecs.umich.edu    val = val * pow(2.0, imm);
2317379Sgblack@eecs.umich.edu    __asm__ __volatile__("" : "=m" (val) : "m" (val));
2327382Sgblack@eecs.umich.edu    fesetround(FeRoundZero);
2337379Sgblack@eecs.umich.edu    feclearexcept(FeAllExceptions);
2347382Sgblack@eecs.umich.edu    __asm__ __volatile__("" : "=m" (val) : "m" (val));
2357382Sgblack@eecs.umich.edu    double origVal = val;
2367382Sgblack@eecs.umich.edu    val = rint(val);
2377382Sgblack@eecs.umich.edu    int fpType = std::fpclassify(val);
2387382Sgblack@eecs.umich.edu    if (fpType == FP_SUBNORMAL || fpType == FP_NAN) {
2397382Sgblack@eecs.umich.edu        if (fpType == FP_NAN) {
2407382Sgblack@eecs.umich.edu            feraiseexcept(FeInvalid);
2417382Sgblack@eecs.umich.edu        }
2427382Sgblack@eecs.umich.edu        val = 0.0;
2437382Sgblack@eecs.umich.edu    } else if (origVal != val) {
2447382Sgblack@eecs.umich.edu        feraiseexcept(FeInexact);
2457382Sgblack@eecs.umich.edu    }
2467379Sgblack@eecs.umich.edu    if (isSigned) {
2477379Sgblack@eecs.umich.edu        if (half) {
2487379Sgblack@eecs.umich.edu            if (val < (int16_t)(1 << 15)) {
2497379Sgblack@eecs.umich.edu                feraiseexcept(FeInvalid);
2507382Sgblack@eecs.umich.edu                feclearexcept(FeInexact);
2517379Sgblack@eecs.umich.edu                return (int16_t)(1 << 15);
2527379Sgblack@eecs.umich.edu            }
2537379Sgblack@eecs.umich.edu            if (val > (int16_t)mask(15)) {
2547379Sgblack@eecs.umich.edu                feraiseexcept(FeInvalid);
2557382Sgblack@eecs.umich.edu                feclearexcept(FeInexact);
2567379Sgblack@eecs.umich.edu                return (int16_t)mask(15);
2577379Sgblack@eecs.umich.edu            }
2587379Sgblack@eecs.umich.edu            return (int16_t)val;
2597379Sgblack@eecs.umich.edu        } else {
2607379Sgblack@eecs.umich.edu            if (val < (int32_t)(1 << 31)) {
2617379Sgblack@eecs.umich.edu                feraiseexcept(FeInvalid);
2627382Sgblack@eecs.umich.edu                feclearexcept(FeInexact);
2637379Sgblack@eecs.umich.edu                return (int32_t)(1 << 31);
2647379Sgblack@eecs.umich.edu            }
2657379Sgblack@eecs.umich.edu            if (val > (int32_t)mask(31)) {
2667379Sgblack@eecs.umich.edu                feraiseexcept(FeInvalid);
2677382Sgblack@eecs.umich.edu                feclearexcept(FeInexact);
2687379Sgblack@eecs.umich.edu                return (int32_t)mask(31);
2697379Sgblack@eecs.umich.edu            }
2707379Sgblack@eecs.umich.edu            return (int32_t)val;
2717379Sgblack@eecs.umich.edu        }
2727379Sgblack@eecs.umich.edu    } else {
2737379Sgblack@eecs.umich.edu        if (half) {
2747379Sgblack@eecs.umich.edu            if (val < 0) {
2757379Sgblack@eecs.umich.edu                feraiseexcept(FeInvalid);
2767382Sgblack@eecs.umich.edu                feclearexcept(FeInexact);
2777379Sgblack@eecs.umich.edu                return 0;
2787379Sgblack@eecs.umich.edu            }
2797379Sgblack@eecs.umich.edu            if (val > mask(16)) {
2807379Sgblack@eecs.umich.edu                feraiseexcept(FeInvalid);
2817382Sgblack@eecs.umich.edu                feclearexcept(FeInexact);
2827379Sgblack@eecs.umich.edu                return mask(16);
2837379Sgblack@eecs.umich.edu            }
2847379Sgblack@eecs.umich.edu            return (uint16_t)val;
2857379Sgblack@eecs.umich.edu        } else {
2867379Sgblack@eecs.umich.edu            if (val < 0) {
2877379Sgblack@eecs.umich.edu                feraiseexcept(FeInvalid);
2887382Sgblack@eecs.umich.edu                feclearexcept(FeInexact);
2897379Sgblack@eecs.umich.edu                return 0;
2907379Sgblack@eecs.umich.edu            }
2917379Sgblack@eecs.umich.edu            if (val > mask(32)) {
2927379Sgblack@eecs.umich.edu                feraiseexcept(FeInvalid);
2937382Sgblack@eecs.umich.edu                feclearexcept(FeInexact);
2947379Sgblack@eecs.umich.edu                return mask(32);
2957379Sgblack@eecs.umich.edu            }
2967379Sgblack@eecs.umich.edu            return (uint32_t)val;
2977379Sgblack@eecs.umich.edu        }
2987379Sgblack@eecs.umich.edu    }
2997379Sgblack@eecs.umich.edu}
3007379Sgblack@eecs.umich.edu
3017379Sgblack@eecs.umich.edustatic inline double
3027379Sgblack@eecs.umich.eduvfpUFixedToFpD(uint32_t val, bool half, uint8_t imm)
3037379Sgblack@eecs.umich.edu{
3047379Sgblack@eecs.umich.edu    fesetround(FeRoundNearest);
3057379Sgblack@eecs.umich.edu    if (half)
3067379Sgblack@eecs.umich.edu        val = (uint16_t)val;
3077382Sgblack@eecs.umich.edu    double scale = pow(2.0, imm);
3087382Sgblack@eecs.umich.edu    __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
3097382Sgblack@eecs.umich.edu    feclearexcept(FeAllExceptions);
3107382Sgblack@eecs.umich.edu    __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
3117382Sgblack@eecs.umich.edu    return val / scale;
3127379Sgblack@eecs.umich.edu}
3137379Sgblack@eecs.umich.edu
3147379Sgblack@eecs.umich.edustatic inline double
3157379Sgblack@eecs.umich.eduvfpSFixedToFpD(int32_t val, bool half, uint8_t imm)
3167379Sgblack@eecs.umich.edu{
3177379Sgblack@eecs.umich.edu    fesetround(FeRoundNearest);
3187379Sgblack@eecs.umich.edu    if (half)
3197379Sgblack@eecs.umich.edu        val = sext<16>(val & mask(16));
3207382Sgblack@eecs.umich.edu    double scale = pow(2.0, imm);
3217382Sgblack@eecs.umich.edu    __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
3227382Sgblack@eecs.umich.edu    feclearexcept(FeAllExceptions);
3237382Sgblack@eecs.umich.edu    __asm__ __volatile__("" : "=m" (scale) : "m" (scale));
3247382Sgblack@eecs.umich.edu    return val / scale;
3257379Sgblack@eecs.umich.edu}
3267379Sgblack@eecs.umich.edu
3277378Sgblack@eecs.umich.edutypedef int VfpSavedState;
3287378Sgblack@eecs.umich.edu
3297378Sgblack@eecs.umich.edustatic inline VfpSavedState
3307378Sgblack@eecs.umich.eduprepVfpFpscr(FPSCR fpscr)
3317378Sgblack@eecs.umich.edu{
3327378Sgblack@eecs.umich.edu    int roundingMode = fegetround();
3337378Sgblack@eecs.umich.edu    feclearexcept(FeAllExceptions);
3347378Sgblack@eecs.umich.edu    switch (fpscr.rMode) {
3357378Sgblack@eecs.umich.edu      case VfpRoundNearest:
3367378Sgblack@eecs.umich.edu        fesetround(FeRoundNearest);
3377378Sgblack@eecs.umich.edu        break;
3387378Sgblack@eecs.umich.edu      case VfpRoundUpward:
3397378Sgblack@eecs.umich.edu        fesetround(FeRoundUpward);
3407378Sgblack@eecs.umich.edu        break;
3417378Sgblack@eecs.umich.edu      case VfpRoundDown:
3427378Sgblack@eecs.umich.edu        fesetround(FeRoundDown);
3437378Sgblack@eecs.umich.edu        break;
3447378Sgblack@eecs.umich.edu      case VfpRoundZero:
3457378Sgblack@eecs.umich.edu        fesetround(FeRoundZero);
3467378Sgblack@eecs.umich.edu        break;
3477378Sgblack@eecs.umich.edu    }
3487378Sgblack@eecs.umich.edu    return roundingMode;
3497378Sgblack@eecs.umich.edu}
3507378Sgblack@eecs.umich.edu
3517378Sgblack@eecs.umich.edustatic inline FPSCR
3527378Sgblack@eecs.umich.edusetVfpFpscr(FPSCR fpscr, VfpSavedState state)
3537378Sgblack@eecs.umich.edu{
3547378Sgblack@eecs.umich.edu    int exceptions = fetestexcept(FeAllExceptions);
3557378Sgblack@eecs.umich.edu    if (exceptions & FeInvalid) {
3567378Sgblack@eecs.umich.edu        fpscr.ioc = 1;
3577378Sgblack@eecs.umich.edu    }
3587378Sgblack@eecs.umich.edu    if (exceptions & FeDivByZero) {
3597378Sgblack@eecs.umich.edu        fpscr.dzc = 1;
3607378Sgblack@eecs.umich.edu    }
3617378Sgblack@eecs.umich.edu    if (exceptions & FeOverflow) {
3627378Sgblack@eecs.umich.edu        fpscr.ofc = 1;
3637378Sgblack@eecs.umich.edu    }
3647378Sgblack@eecs.umich.edu    if (exceptions & FeUnderflow) {
3657378Sgblack@eecs.umich.edu        fpscr.ufc = 1;
3667378Sgblack@eecs.umich.edu    }
3677378Sgblack@eecs.umich.edu    if (exceptions & FeInexact) {
3687378Sgblack@eecs.umich.edu        fpscr.ixc = 1;
3697378Sgblack@eecs.umich.edu    }
3707378Sgblack@eecs.umich.edu    fesetround(state);
3717378Sgblack@eecs.umich.edu    return fpscr;
3727378Sgblack@eecs.umich.edu}
3737378Sgblack@eecs.umich.edu
3747376Sgblack@eecs.umich.educlass VfpMacroOp : public PredMacroOp
3757376Sgblack@eecs.umich.edu{
3767376Sgblack@eecs.umich.edu  public:
3777376Sgblack@eecs.umich.edu    static bool
3787376Sgblack@eecs.umich.edu    inScalarBank(IntRegIndex idx)
3797376Sgblack@eecs.umich.edu    {
3807376Sgblack@eecs.umich.edu        return (idx % 32) < 8;
3817376Sgblack@eecs.umich.edu    }
3827376Sgblack@eecs.umich.edu
3837376Sgblack@eecs.umich.edu  protected:
3847376Sgblack@eecs.umich.edu    bool wide;
3857376Sgblack@eecs.umich.edu
3867376Sgblack@eecs.umich.edu    VfpMacroOp(const char *mnem, ExtMachInst _machInst,
3877376Sgblack@eecs.umich.edu            OpClass __opClass, bool _wide) :
3887376Sgblack@eecs.umich.edu        PredMacroOp(mnem, _machInst, __opClass), wide(_wide)
3897376Sgblack@eecs.umich.edu    {}
3907376Sgblack@eecs.umich.edu
3917376Sgblack@eecs.umich.edu    IntRegIndex
3927376Sgblack@eecs.umich.edu    addStride(IntRegIndex idx, unsigned stride)
3937376Sgblack@eecs.umich.edu    {
3947376Sgblack@eecs.umich.edu        if (wide) {
3957376Sgblack@eecs.umich.edu            stride *= 2;
3967376Sgblack@eecs.umich.edu        }
3977376Sgblack@eecs.umich.edu        unsigned offset = idx % 8;
3987376Sgblack@eecs.umich.edu        idx = (IntRegIndex)(idx - offset);
3997376Sgblack@eecs.umich.edu        offset += stride;
4007376Sgblack@eecs.umich.edu        idx = (IntRegIndex)(idx + (offset % 8));
4017376Sgblack@eecs.umich.edu        return idx;
4027376Sgblack@eecs.umich.edu    }
4037376Sgblack@eecs.umich.edu
4047376Sgblack@eecs.umich.edu    void
4057376Sgblack@eecs.umich.edu    nextIdxs(IntRegIndex &dest, IntRegIndex &op1, IntRegIndex &op2)
4067376Sgblack@eecs.umich.edu    {
4077376Sgblack@eecs.umich.edu        unsigned stride = (machInst.fpscrStride == 0) ? 1 : 2;
4087376Sgblack@eecs.umich.edu        assert(!inScalarBank(dest));
4097376Sgblack@eecs.umich.edu        dest = addStride(dest, stride);
4107376Sgblack@eecs.umich.edu        op1 = addStride(op1, stride);
4117376Sgblack@eecs.umich.edu        if (!inScalarBank(op2)) {
4127376Sgblack@eecs.umich.edu            op2 = addStride(op2, stride);
4137376Sgblack@eecs.umich.edu        }
4147376Sgblack@eecs.umich.edu    }
4157376Sgblack@eecs.umich.edu
4167376Sgblack@eecs.umich.edu    void
4177376Sgblack@eecs.umich.edu    nextIdxs(IntRegIndex &dest, IntRegIndex &op1)
4187376Sgblack@eecs.umich.edu    {
4197376Sgblack@eecs.umich.edu        unsigned stride = (machInst.fpscrStride == 0) ? 1 : 2;
4207376Sgblack@eecs.umich.edu        assert(!inScalarBank(dest));
4217376Sgblack@eecs.umich.edu        dest = addStride(dest, stride);
4227376Sgblack@eecs.umich.edu        if (!inScalarBank(op1)) {
4237376Sgblack@eecs.umich.edu            op1 = addStride(op1, stride);
4247376Sgblack@eecs.umich.edu        }
4257376Sgblack@eecs.umich.edu    }
4267376Sgblack@eecs.umich.edu
4277376Sgblack@eecs.umich.edu    void
4287376Sgblack@eecs.umich.edu    nextIdxs(IntRegIndex &dest)
4297376Sgblack@eecs.umich.edu    {
4307376Sgblack@eecs.umich.edu        unsigned stride = (machInst.fpscrStride == 0) ? 1 : 2;
4317376Sgblack@eecs.umich.edu        assert(!inScalarBank(dest));
4327376Sgblack@eecs.umich.edu        dest = addStride(dest, stride);
4337376Sgblack@eecs.umich.edu    }
4347376Sgblack@eecs.umich.edu};
4357376Sgblack@eecs.umich.edu
4367375Sgblack@eecs.umich.educlass VfpRegRegOp : public RegRegOp
4377375Sgblack@eecs.umich.edu{
4387375Sgblack@eecs.umich.edu  protected:
4397375Sgblack@eecs.umich.edu    VfpRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
4407375Sgblack@eecs.umich.edu                IntRegIndex _dest, IntRegIndex _op1,
4417375Sgblack@eecs.umich.edu                VfpMicroMode mode = VfpNotAMicroop) :
4427375Sgblack@eecs.umich.edu        RegRegOp(mnem, _machInst, __opClass, _dest, _op1)
4437375Sgblack@eecs.umich.edu    {
4447375Sgblack@eecs.umich.edu        setVfpMicroFlags(mode, flags);
4457375Sgblack@eecs.umich.edu    }
4467375Sgblack@eecs.umich.edu};
4477375Sgblack@eecs.umich.edu
4487375Sgblack@eecs.umich.educlass VfpRegImmOp : public RegImmOp
4497375Sgblack@eecs.umich.edu{
4507375Sgblack@eecs.umich.edu  protected:
4517375Sgblack@eecs.umich.edu    VfpRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
4527375Sgblack@eecs.umich.edu                IntRegIndex _dest, uint64_t _imm,
4537375Sgblack@eecs.umich.edu                VfpMicroMode mode = VfpNotAMicroop) :
4547375Sgblack@eecs.umich.edu        RegImmOp(mnem, _machInst, __opClass, _dest, _imm)
4557375Sgblack@eecs.umich.edu    {
4567375Sgblack@eecs.umich.edu        setVfpMicroFlags(mode, flags);
4577375Sgblack@eecs.umich.edu    }
4587375Sgblack@eecs.umich.edu};
4597375Sgblack@eecs.umich.edu
4607375Sgblack@eecs.umich.educlass VfpRegRegImmOp : public RegRegImmOp
4617375Sgblack@eecs.umich.edu{
4627375Sgblack@eecs.umich.edu  protected:
4637375Sgblack@eecs.umich.edu    VfpRegRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
4647375Sgblack@eecs.umich.edu                   IntRegIndex _dest, IntRegIndex _op1,
4657375Sgblack@eecs.umich.edu                   uint64_t _imm, VfpMicroMode mode = VfpNotAMicroop) :
4667375Sgblack@eecs.umich.edu        RegRegImmOp(mnem, _machInst, __opClass, _dest, _op1, _imm)
4677375Sgblack@eecs.umich.edu    {
4687375Sgblack@eecs.umich.edu        setVfpMicroFlags(mode, flags);
4697375Sgblack@eecs.umich.edu    }
4707375Sgblack@eecs.umich.edu};
4717375Sgblack@eecs.umich.edu
4727375Sgblack@eecs.umich.educlass VfpRegRegRegOp : public RegRegRegOp
4737375Sgblack@eecs.umich.edu{
4747375Sgblack@eecs.umich.edu  protected:
4757375Sgblack@eecs.umich.edu    VfpRegRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
4767375Sgblack@eecs.umich.edu                   IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
4777375Sgblack@eecs.umich.edu                   VfpMicroMode mode = VfpNotAMicroop) :
4787375Sgblack@eecs.umich.edu        RegRegRegOp(mnem, _machInst, __opClass, _dest, _op1, _op2)
4797375Sgblack@eecs.umich.edu    {
4807375Sgblack@eecs.umich.edu        setVfpMicroFlags(mode, flags);
4817375Sgblack@eecs.umich.edu    }
4827375Sgblack@eecs.umich.edu};
4837375Sgblack@eecs.umich.edu
4847375Sgblack@eecs.umich.edu#endif //__ARCH_ARM_INSTS_VFP_HH__
485