vfp.hh revision 7378
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> 467375Sgblack@eecs.umich.edu 477375Sgblack@eecs.umich.eduenum VfpMicroMode { 487375Sgblack@eecs.umich.edu VfpNotAMicroop, 497375Sgblack@eecs.umich.edu VfpMicroop, 507375Sgblack@eecs.umich.edu VfpFirstMicroop, 517375Sgblack@eecs.umich.edu VfpLastMicroop 527375Sgblack@eecs.umich.edu}; 537375Sgblack@eecs.umich.edu 547375Sgblack@eecs.umich.edutemplate<class T> 557375Sgblack@eecs.umich.edustatic inline void 567375Sgblack@eecs.umich.edusetVfpMicroFlags(VfpMicroMode mode, T &flags) 577375Sgblack@eecs.umich.edu{ 587375Sgblack@eecs.umich.edu switch (mode) { 597375Sgblack@eecs.umich.edu case VfpMicroop: 607375Sgblack@eecs.umich.edu flags[StaticInst::IsMicroop] = true; 617375Sgblack@eecs.umich.edu break; 627375Sgblack@eecs.umich.edu case VfpFirstMicroop: 637375Sgblack@eecs.umich.edu flags[StaticInst::IsMicroop] = 647375Sgblack@eecs.umich.edu flags[StaticInst::IsFirstMicroop] = true; 657375Sgblack@eecs.umich.edu break; 667375Sgblack@eecs.umich.edu case VfpLastMicroop: 677375Sgblack@eecs.umich.edu flags[StaticInst::IsMicroop] = 687375Sgblack@eecs.umich.edu flags[StaticInst::IsLastMicroop] = true; 697375Sgblack@eecs.umich.edu break; 707375Sgblack@eecs.umich.edu case VfpNotAMicroop: 717375Sgblack@eecs.umich.edu break; 727375Sgblack@eecs.umich.edu } 737376Sgblack@eecs.umich.edu if (mode == VfpMicroop || mode == VfpFirstMicroop) { 747376Sgblack@eecs.umich.edu flags[StaticInst::IsDelayedCommit] = true; 757376Sgblack@eecs.umich.edu } 767375Sgblack@eecs.umich.edu} 777375Sgblack@eecs.umich.edu 787378Sgblack@eecs.umich.eduenum FeExceptionBit 797378Sgblack@eecs.umich.edu{ 807378Sgblack@eecs.umich.edu FeDivByZero = FE_DIVBYZERO, 817378Sgblack@eecs.umich.edu FeInexact = FE_INEXACT, 827378Sgblack@eecs.umich.edu FeInvalid = FE_INVALID, 837378Sgblack@eecs.umich.edu FeOverflow = FE_OVERFLOW, 847378Sgblack@eecs.umich.edu FeUnderflow = FE_UNDERFLOW, 857378Sgblack@eecs.umich.edu FeAllExceptions = FE_ALL_EXCEPT 867378Sgblack@eecs.umich.edu}; 877378Sgblack@eecs.umich.edu 887378Sgblack@eecs.umich.eduenum FeRoundingMode 897378Sgblack@eecs.umich.edu{ 907378Sgblack@eecs.umich.edu FeRoundDown = FE_DOWNWARD, 917378Sgblack@eecs.umich.edu FeRoundNearest = FE_TONEAREST, 927378Sgblack@eecs.umich.edu FeRoundZero = FE_TOWARDZERO, 937378Sgblack@eecs.umich.edu FeRoundUpward = FE_UPWARD 947378Sgblack@eecs.umich.edu}; 957378Sgblack@eecs.umich.edu 967378Sgblack@eecs.umich.eduenum VfpRoundingMode 977378Sgblack@eecs.umich.edu{ 987378Sgblack@eecs.umich.edu VfpRoundNearest = 0, 997378Sgblack@eecs.umich.edu VfpRoundUpward = 1, 1007378Sgblack@eecs.umich.edu VfpRoundDown = 2, 1017378Sgblack@eecs.umich.edu VfpRoundZero = 3 1027378Sgblack@eecs.umich.edu}; 1037378Sgblack@eecs.umich.edu 1047378Sgblack@eecs.umich.edutypedef int VfpSavedState; 1057378Sgblack@eecs.umich.edu 1067378Sgblack@eecs.umich.edustatic inline VfpSavedState 1077378Sgblack@eecs.umich.eduprepVfpFpscr(FPSCR fpscr) 1087378Sgblack@eecs.umich.edu{ 1097378Sgblack@eecs.umich.edu int roundingMode = fegetround(); 1107378Sgblack@eecs.umich.edu feclearexcept(FeAllExceptions); 1117378Sgblack@eecs.umich.edu switch (fpscr.rMode) { 1127378Sgblack@eecs.umich.edu case VfpRoundNearest: 1137378Sgblack@eecs.umich.edu fesetround(FeRoundNearest); 1147378Sgblack@eecs.umich.edu break; 1157378Sgblack@eecs.umich.edu case VfpRoundUpward: 1167378Sgblack@eecs.umich.edu fesetround(FeRoundUpward); 1177378Sgblack@eecs.umich.edu break; 1187378Sgblack@eecs.umich.edu case VfpRoundDown: 1197378Sgblack@eecs.umich.edu fesetround(FeRoundDown); 1207378Sgblack@eecs.umich.edu break; 1217378Sgblack@eecs.umich.edu case VfpRoundZero: 1227378Sgblack@eecs.umich.edu fesetround(FeRoundZero); 1237378Sgblack@eecs.umich.edu break; 1247378Sgblack@eecs.umich.edu } 1257378Sgblack@eecs.umich.edu return roundingMode; 1267378Sgblack@eecs.umich.edu} 1277378Sgblack@eecs.umich.edu 1287378Sgblack@eecs.umich.edustatic inline FPSCR 1297378Sgblack@eecs.umich.edusetVfpFpscr(FPSCR fpscr, VfpSavedState state) 1307378Sgblack@eecs.umich.edu{ 1317378Sgblack@eecs.umich.edu int exceptions = fetestexcept(FeAllExceptions); 1327378Sgblack@eecs.umich.edu if (exceptions & FeInvalid) { 1337378Sgblack@eecs.umich.edu fpscr.ioc = 1; 1347378Sgblack@eecs.umich.edu } 1357378Sgblack@eecs.umich.edu if (exceptions & FeDivByZero) { 1367378Sgblack@eecs.umich.edu fpscr.dzc = 1; 1377378Sgblack@eecs.umich.edu } 1387378Sgblack@eecs.umich.edu if (exceptions & FeOverflow) { 1397378Sgblack@eecs.umich.edu fpscr.ofc = 1; 1407378Sgblack@eecs.umich.edu } 1417378Sgblack@eecs.umich.edu if (exceptions & FeUnderflow) { 1427378Sgblack@eecs.umich.edu fpscr.ufc = 1; 1437378Sgblack@eecs.umich.edu } 1447378Sgblack@eecs.umich.edu if (exceptions & FeInexact) { 1457378Sgblack@eecs.umich.edu fpscr.ixc = 1; 1467378Sgblack@eecs.umich.edu } 1477378Sgblack@eecs.umich.edu fesetround(state); 1487378Sgblack@eecs.umich.edu return fpscr; 1497378Sgblack@eecs.umich.edu} 1507378Sgblack@eecs.umich.edu 1517376Sgblack@eecs.umich.educlass VfpMacroOp : public PredMacroOp 1527376Sgblack@eecs.umich.edu{ 1537376Sgblack@eecs.umich.edu public: 1547376Sgblack@eecs.umich.edu static bool 1557376Sgblack@eecs.umich.edu inScalarBank(IntRegIndex idx) 1567376Sgblack@eecs.umich.edu { 1577376Sgblack@eecs.umich.edu return (idx % 32) < 8; 1587376Sgblack@eecs.umich.edu } 1597376Sgblack@eecs.umich.edu 1607376Sgblack@eecs.umich.edu protected: 1617376Sgblack@eecs.umich.edu bool wide; 1627376Sgblack@eecs.umich.edu 1637376Sgblack@eecs.umich.edu VfpMacroOp(const char *mnem, ExtMachInst _machInst, 1647376Sgblack@eecs.umich.edu OpClass __opClass, bool _wide) : 1657376Sgblack@eecs.umich.edu PredMacroOp(mnem, _machInst, __opClass), wide(_wide) 1667376Sgblack@eecs.umich.edu {} 1677376Sgblack@eecs.umich.edu 1687376Sgblack@eecs.umich.edu IntRegIndex 1697376Sgblack@eecs.umich.edu addStride(IntRegIndex idx, unsigned stride) 1707376Sgblack@eecs.umich.edu { 1717376Sgblack@eecs.umich.edu if (wide) { 1727376Sgblack@eecs.umich.edu stride *= 2; 1737376Sgblack@eecs.umich.edu } 1747376Sgblack@eecs.umich.edu unsigned offset = idx % 8; 1757376Sgblack@eecs.umich.edu idx = (IntRegIndex)(idx - offset); 1767376Sgblack@eecs.umich.edu offset += stride; 1777376Sgblack@eecs.umich.edu idx = (IntRegIndex)(idx + (offset % 8)); 1787376Sgblack@eecs.umich.edu return idx; 1797376Sgblack@eecs.umich.edu } 1807376Sgblack@eecs.umich.edu 1817376Sgblack@eecs.umich.edu void 1827376Sgblack@eecs.umich.edu nextIdxs(IntRegIndex &dest, IntRegIndex &op1, IntRegIndex &op2) 1837376Sgblack@eecs.umich.edu { 1847376Sgblack@eecs.umich.edu unsigned stride = (machInst.fpscrStride == 0) ? 1 : 2; 1857376Sgblack@eecs.umich.edu assert(!inScalarBank(dest)); 1867376Sgblack@eecs.umich.edu dest = addStride(dest, stride); 1877376Sgblack@eecs.umich.edu op1 = addStride(op1, stride); 1887376Sgblack@eecs.umich.edu if (!inScalarBank(op2)) { 1897376Sgblack@eecs.umich.edu op2 = addStride(op2, stride); 1907376Sgblack@eecs.umich.edu } 1917376Sgblack@eecs.umich.edu } 1927376Sgblack@eecs.umich.edu 1937376Sgblack@eecs.umich.edu void 1947376Sgblack@eecs.umich.edu nextIdxs(IntRegIndex &dest, IntRegIndex &op1) 1957376Sgblack@eecs.umich.edu { 1967376Sgblack@eecs.umich.edu unsigned stride = (machInst.fpscrStride == 0) ? 1 : 2; 1977376Sgblack@eecs.umich.edu assert(!inScalarBank(dest)); 1987376Sgblack@eecs.umich.edu dest = addStride(dest, stride); 1997376Sgblack@eecs.umich.edu if (!inScalarBank(op1)) { 2007376Sgblack@eecs.umich.edu op1 = addStride(op1, stride); 2017376Sgblack@eecs.umich.edu } 2027376Sgblack@eecs.umich.edu } 2037376Sgblack@eecs.umich.edu 2047376Sgblack@eecs.umich.edu void 2057376Sgblack@eecs.umich.edu nextIdxs(IntRegIndex &dest) 2067376Sgblack@eecs.umich.edu { 2077376Sgblack@eecs.umich.edu unsigned stride = (machInst.fpscrStride == 0) ? 1 : 2; 2087376Sgblack@eecs.umich.edu assert(!inScalarBank(dest)); 2097376Sgblack@eecs.umich.edu dest = addStride(dest, stride); 2107376Sgblack@eecs.umich.edu } 2117376Sgblack@eecs.umich.edu}; 2127376Sgblack@eecs.umich.edu 2137375Sgblack@eecs.umich.educlass VfpRegRegOp : public RegRegOp 2147375Sgblack@eecs.umich.edu{ 2157375Sgblack@eecs.umich.edu protected: 2167375Sgblack@eecs.umich.edu VfpRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 2177375Sgblack@eecs.umich.edu IntRegIndex _dest, IntRegIndex _op1, 2187375Sgblack@eecs.umich.edu VfpMicroMode mode = VfpNotAMicroop) : 2197375Sgblack@eecs.umich.edu RegRegOp(mnem, _machInst, __opClass, _dest, _op1) 2207375Sgblack@eecs.umich.edu { 2217375Sgblack@eecs.umich.edu setVfpMicroFlags(mode, flags); 2227375Sgblack@eecs.umich.edu } 2237375Sgblack@eecs.umich.edu}; 2247375Sgblack@eecs.umich.edu 2257375Sgblack@eecs.umich.educlass VfpRegImmOp : public RegImmOp 2267375Sgblack@eecs.umich.edu{ 2277375Sgblack@eecs.umich.edu protected: 2287375Sgblack@eecs.umich.edu VfpRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 2297375Sgblack@eecs.umich.edu IntRegIndex _dest, uint64_t _imm, 2307375Sgblack@eecs.umich.edu VfpMicroMode mode = VfpNotAMicroop) : 2317375Sgblack@eecs.umich.edu RegImmOp(mnem, _machInst, __opClass, _dest, _imm) 2327375Sgblack@eecs.umich.edu { 2337375Sgblack@eecs.umich.edu setVfpMicroFlags(mode, flags); 2347375Sgblack@eecs.umich.edu } 2357375Sgblack@eecs.umich.edu}; 2367375Sgblack@eecs.umich.edu 2377375Sgblack@eecs.umich.educlass VfpRegRegImmOp : public RegRegImmOp 2387375Sgblack@eecs.umich.edu{ 2397375Sgblack@eecs.umich.edu protected: 2407375Sgblack@eecs.umich.edu VfpRegRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 2417375Sgblack@eecs.umich.edu IntRegIndex _dest, IntRegIndex _op1, 2427375Sgblack@eecs.umich.edu uint64_t _imm, VfpMicroMode mode = VfpNotAMicroop) : 2437375Sgblack@eecs.umich.edu RegRegImmOp(mnem, _machInst, __opClass, _dest, _op1, _imm) 2447375Sgblack@eecs.umich.edu { 2457375Sgblack@eecs.umich.edu setVfpMicroFlags(mode, flags); 2467375Sgblack@eecs.umich.edu } 2477375Sgblack@eecs.umich.edu}; 2487375Sgblack@eecs.umich.edu 2497375Sgblack@eecs.umich.educlass VfpRegRegRegOp : public RegRegRegOp 2507375Sgblack@eecs.umich.edu{ 2517375Sgblack@eecs.umich.edu protected: 2527375Sgblack@eecs.umich.edu VfpRegRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 2537375Sgblack@eecs.umich.edu IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, 2547375Sgblack@eecs.umich.edu VfpMicroMode mode = VfpNotAMicroop) : 2557375Sgblack@eecs.umich.edu RegRegRegOp(mnem, _machInst, __opClass, _dest, _op1, _op2) 2567375Sgblack@eecs.umich.edu { 2577375Sgblack@eecs.umich.edu setVfpMicroFlags(mode, flags); 2587375Sgblack@eecs.umich.edu } 2597375Sgblack@eecs.umich.edu}; 2607375Sgblack@eecs.umich.edu 2617375Sgblack@eecs.umich.edu#endif //__ARCH_ARM_INSTS_VFP_HH__ 262