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