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