neon.isa revision 10037
17639Sgblack@eecs.umich.edu// -*- mode:c++ -*-
27639Sgblack@eecs.umich.edu
310037SARM gem5 Developers// Copyright (c) 2010-2012 ARM Limited
47639Sgblack@eecs.umich.edu// All rights reserved
57639Sgblack@eecs.umich.edu//
67639Sgblack@eecs.umich.edu// The license below extends only to copyright in the software and shall
77639Sgblack@eecs.umich.edu// not be construed as granting a license to any other intellectual
87639Sgblack@eecs.umich.edu// property including but not limited to intellectual property relating
97639Sgblack@eecs.umich.edu// to a hardware implementation of the functionality of the software
107639Sgblack@eecs.umich.edu// licensed hereunder.  You may use the software subject to the license
117639Sgblack@eecs.umich.edu// terms below provided that you ensure that this notice is replicated
127639Sgblack@eecs.umich.edu// unmodified and in its entirety in all distributions of the software,
137639Sgblack@eecs.umich.edu// modified or unmodified, in source code or in binary form.
147639Sgblack@eecs.umich.edu//
157639Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
167639Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
177639Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
187639Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
197639Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
207639Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
217639Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
227639Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
237639Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
247639Sgblack@eecs.umich.edu// this software without specific prior written permission.
257639Sgblack@eecs.umich.edu//
267639Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
277639Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
287639Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
297639Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
307639Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
317639Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
327639Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
337639Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
347639Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
357639Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
367639Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
377639Sgblack@eecs.umich.edu//
387639Sgblack@eecs.umich.edu// Authors: Gabe Black
397639Sgblack@eecs.umich.edu
407644Sali.saidi@arm.comlet {{
417644Sali.saidi@arm.com    simdEnabledCheckCode = '''
4210037SARM gem5 Developers    {
4310037SARM gem5 Developers        uint32_t issEnCheck;
4410037SARM gem5 Developers        bool trapEnCheck;
4510037SARM gem5 Developers        uint32_t seq;
4610037SARM gem5 Developers        if (!vfpNeonEnabled(seq, Hcptr, Nsacr, Cpacr, Cpsr, issEnCheck,
4710037SARM gem5 Developers                            trapEnCheck, xc->tcBase(), Fpexc, true))
4810037SARM gem5 Developers            {return disabledFault();}
4910037SARM gem5 Developers        if (trapEnCheck) {
5010037SARM gem5 Developers            CPSR cpsrEnCheck = Cpsr;
5110037SARM gem5 Developers            if (cpsrEnCheck.mode == MODE_HYP) {
5210037SARM gem5 Developers                return new UndefinedInstruction(machInst, issEnCheck,
5310037SARM gem5 Developers                                                EC_TRAPPED_HCPTR);
5410037SARM gem5 Developers            } else {
5510037SARM gem5 Developers                if (!inSecureState(Scr, Cpsr)) {
5610037SARM gem5 Developers                    return new HypervisorTrap(machInst, issEnCheck,
5710037SARM gem5 Developers                                              EC_TRAPPED_HCPTR);
5810037SARM gem5 Developers                }
5910037SARM gem5 Developers            }
6010037SARM gem5 Developers        }
6110037SARM gem5 Developers    }
627644Sali.saidi@arm.com    '''
637644Sali.saidi@arm.com}};
647644Sali.saidi@arm.com
657644Sali.saidi@arm.com
667639Sgblack@eecs.umich.edudef template NeonRegRegRegOpDeclare {{
677639Sgblack@eecs.umich.edutemplate <class _Element>
687639Sgblack@eecs.umich.educlass %(class_name)s : public %(base_class)s
697639Sgblack@eecs.umich.edu{
707639Sgblack@eecs.umich.edu  protected:
717639Sgblack@eecs.umich.edu    typedef _Element Element;
727639Sgblack@eecs.umich.edu  public:
737639Sgblack@eecs.umich.edu    // Constructor
747639Sgblack@eecs.umich.edu    %(class_name)s(ExtMachInst machInst,
757639Sgblack@eecs.umich.edu                   IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2)
767639Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
777639Sgblack@eecs.umich.edu                         _dest, _op1, _op2)
787639Sgblack@eecs.umich.edu    {
797639Sgblack@eecs.umich.edu        %(constructor)s;
807848SAli.Saidi@ARM.com        if (!(condCode == COND_AL || condCode == COND_UC)) {
817848SAli.Saidi@ARM.com            for (int x = 0; x < _numDestRegs; x++) {
827848SAli.Saidi@ARM.com                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
837848SAli.Saidi@ARM.com            }
847848SAli.Saidi@ARM.com        }
857639Sgblack@eecs.umich.edu    }
867639Sgblack@eecs.umich.edu
877639Sgblack@eecs.umich.edu    %(BasicExecDeclare)s
887639Sgblack@eecs.umich.edu};
897639Sgblack@eecs.umich.edu}};
907639Sgblack@eecs.umich.edu
917639Sgblack@eecs.umich.edudef template NeonRegRegRegImmOpDeclare {{
927639Sgblack@eecs.umich.edutemplate <class _Element>
937639Sgblack@eecs.umich.educlass %(class_name)s : public %(base_class)s
947639Sgblack@eecs.umich.edu{
957639Sgblack@eecs.umich.edu  protected:
967639Sgblack@eecs.umich.edu    typedef _Element Element;
977639Sgblack@eecs.umich.edu  public:
987639Sgblack@eecs.umich.edu    // Constructor
997639Sgblack@eecs.umich.edu    %(class_name)s(ExtMachInst machInst,
1007639Sgblack@eecs.umich.edu                   IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
1017639Sgblack@eecs.umich.edu                   uint64_t _imm)
1027639Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1037639Sgblack@eecs.umich.edu                         _dest, _op1, _op2, _imm)
1047639Sgblack@eecs.umich.edu    {
1057639Sgblack@eecs.umich.edu        %(constructor)s;
1067848SAli.Saidi@ARM.com        if (!(condCode == COND_AL || condCode == COND_UC)) {
1077848SAli.Saidi@ARM.com            for (int x = 0; x < _numDestRegs; x++) {
1087848SAli.Saidi@ARM.com                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1097848SAli.Saidi@ARM.com            }
1107848SAli.Saidi@ARM.com        }
1117639Sgblack@eecs.umich.edu    }
1127639Sgblack@eecs.umich.edu
1137639Sgblack@eecs.umich.edu    %(BasicExecDeclare)s
1147639Sgblack@eecs.umich.edu};
1157639Sgblack@eecs.umich.edu}};
1167639Sgblack@eecs.umich.edu
1177639Sgblack@eecs.umich.edudef template NeonRegRegImmOpDeclare {{
1187639Sgblack@eecs.umich.edutemplate <class _Element>
1197639Sgblack@eecs.umich.educlass %(class_name)s : public %(base_class)s
1207639Sgblack@eecs.umich.edu{
1217639Sgblack@eecs.umich.edu  protected:
1227639Sgblack@eecs.umich.edu    typedef _Element Element;
1237639Sgblack@eecs.umich.edu  public:
1247639Sgblack@eecs.umich.edu    // Constructor
1257639Sgblack@eecs.umich.edu    %(class_name)s(ExtMachInst machInst,
1267639Sgblack@eecs.umich.edu                   IntRegIndex _dest, IntRegIndex _op1, uint64_t _imm)
1277639Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1287639Sgblack@eecs.umich.edu                         _dest, _op1, _imm)
1297639Sgblack@eecs.umich.edu    {
1307639Sgblack@eecs.umich.edu        %(constructor)s;
1317848SAli.Saidi@ARM.com        if (!(condCode == COND_AL || condCode == COND_UC)) {
1327848SAli.Saidi@ARM.com            for (int x = 0; x < _numDestRegs; x++) {
1337848SAli.Saidi@ARM.com                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1347848SAli.Saidi@ARM.com            }
1357848SAli.Saidi@ARM.com        }
1367639Sgblack@eecs.umich.edu    }
1377639Sgblack@eecs.umich.edu
1387639Sgblack@eecs.umich.edu    %(BasicExecDeclare)s
1397639Sgblack@eecs.umich.edu};
1407639Sgblack@eecs.umich.edu}};
1417639Sgblack@eecs.umich.edu
1427639Sgblack@eecs.umich.edudef template NeonRegImmOpDeclare {{
1437639Sgblack@eecs.umich.edutemplate <class _Element>
1447639Sgblack@eecs.umich.educlass %(class_name)s : public %(base_class)s
1457639Sgblack@eecs.umich.edu{
1467639Sgblack@eecs.umich.edu  protected:
1477639Sgblack@eecs.umich.edu    typedef _Element Element;
1487639Sgblack@eecs.umich.edu  public:
1497639Sgblack@eecs.umich.edu    // Constructor
1507639Sgblack@eecs.umich.edu    %(class_name)s(ExtMachInst machInst, IntRegIndex _dest, uint64_t _imm)
1517639Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest, _imm)
1527639Sgblack@eecs.umich.edu    {
1537639Sgblack@eecs.umich.edu        %(constructor)s;
1547848SAli.Saidi@ARM.com        if (!(condCode == COND_AL || condCode == COND_UC)) {
1557848SAli.Saidi@ARM.com            for (int x = 0; x < _numDestRegs; x++) {
1567848SAli.Saidi@ARM.com                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1577848SAli.Saidi@ARM.com            }
1587848SAli.Saidi@ARM.com        }
1597639Sgblack@eecs.umich.edu    }
1607639Sgblack@eecs.umich.edu
1617639Sgblack@eecs.umich.edu    %(BasicExecDeclare)s
1627639Sgblack@eecs.umich.edu};
1637639Sgblack@eecs.umich.edu}};
1647639Sgblack@eecs.umich.edu
1657639Sgblack@eecs.umich.edudef template NeonRegRegOpDeclare {{
1667639Sgblack@eecs.umich.edutemplate <class _Element>
1677639Sgblack@eecs.umich.educlass %(class_name)s : public %(base_class)s
1687639Sgblack@eecs.umich.edu{
1697639Sgblack@eecs.umich.edu  protected:
1707639Sgblack@eecs.umich.edu    typedef _Element Element;
1717639Sgblack@eecs.umich.edu  public:
1727639Sgblack@eecs.umich.edu    // Constructor
1737639Sgblack@eecs.umich.edu    %(class_name)s(ExtMachInst machInst,
1747639Sgblack@eecs.umich.edu                   IntRegIndex _dest, IntRegIndex _op1)
1757639Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1767639Sgblack@eecs.umich.edu                         _dest, _op1)
1777639Sgblack@eecs.umich.edu    {
1787639Sgblack@eecs.umich.edu        %(constructor)s;
1797848SAli.Saidi@ARM.com        if (!(condCode == COND_AL || condCode == COND_UC)) {
1807848SAli.Saidi@ARM.com            for (int x = 0; x < _numDestRegs; x++) {
1817848SAli.Saidi@ARM.com                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1827848SAli.Saidi@ARM.com            }
1837848SAli.Saidi@ARM.com        }
1847639Sgblack@eecs.umich.edu    }
1857639Sgblack@eecs.umich.edu
1867639Sgblack@eecs.umich.edu    %(BasicExecDeclare)s
1877639Sgblack@eecs.umich.edu};
1887639Sgblack@eecs.umich.edu}};
1897639Sgblack@eecs.umich.edu
1907639Sgblack@eecs.umich.edudef template NeonExecDeclare {{
1917639Sgblack@eecs.umich.edu    template
1927639Sgblack@eecs.umich.edu    Fault %(class_name)s<%(targs)s>::execute(
1937639Sgblack@eecs.umich.edu            %(CPU_exec_context)s *, Trace::InstRecord *) const;
1947639Sgblack@eecs.umich.edu}};
1957639Sgblack@eecs.umich.edu
1967641Sgblack@eecs.umich.eduoutput header {{
1977641Sgblack@eecs.umich.edu    template <class T>
1987641Sgblack@eecs.umich.edu    // Implement a less-than-zero function: ltz()
1997641Sgblack@eecs.umich.edu    // this function exists because some versions of GCC complain when a
2007641Sgblack@eecs.umich.edu    // comparison is done between a unsigned variable and 0 and for GCC 4.2
2017641Sgblack@eecs.umich.edu    // there is no way to disable this warning
2027641Sgblack@eecs.umich.edu    inline bool ltz(T t);
2037641Sgblack@eecs.umich.edu
2047641Sgblack@eecs.umich.edu    template <>
2057641Sgblack@eecs.umich.edu    inline bool ltz(uint8_t) { return false; }
2067641Sgblack@eecs.umich.edu    template <>
2077641Sgblack@eecs.umich.edu    inline bool ltz(uint16_t) { return false; }
2087641Sgblack@eecs.umich.edu    template <>
2097641Sgblack@eecs.umich.edu    inline bool ltz(uint32_t) { return false; }
2107641Sgblack@eecs.umich.edu    template <>
2117641Sgblack@eecs.umich.edu    inline bool ltz(uint64_t) { return false; }
2127641Sgblack@eecs.umich.edu    template <>
2137641Sgblack@eecs.umich.edu    inline bool ltz(int8_t v) { return v < 0; }
2147641Sgblack@eecs.umich.edu    template <>
2157641Sgblack@eecs.umich.edu    inline bool ltz(int16_t v) { return v < 0; }
2167641Sgblack@eecs.umich.edu    template <>
2177641Sgblack@eecs.umich.edu    inline bool ltz(int32_t v) { return v < 0; }
2187641Sgblack@eecs.umich.edu    template <>
2197641Sgblack@eecs.umich.edu    inline bool ltz(int64_t v) { return v < 0; }
2207641Sgblack@eecs.umich.edu}};
2217641Sgblack@eecs.umich.edu
2227639Sgblack@eecs.umich.edudef template NeonEqualRegExecute {{
2237639Sgblack@eecs.umich.edu    template <class Element>
2247639Sgblack@eecs.umich.edu    Fault %(class_name)s<Element>::execute(%(CPU_exec_context)s *xc,
2257639Sgblack@eecs.umich.edu            Trace::InstRecord *traceData) const
2267639Sgblack@eecs.umich.edu    {
2277639Sgblack@eecs.umich.edu        Fault fault = NoFault;
2287639Sgblack@eecs.umich.edu        %(op_decl)s;
2297639Sgblack@eecs.umich.edu        %(op_rd)s;
2307639Sgblack@eecs.umich.edu
2317639Sgblack@eecs.umich.edu        const unsigned rCount = %(r_count)d;
2327639Sgblack@eecs.umich.edu        const unsigned eCount = rCount * sizeof(FloatRegBits) / sizeof(Element);
2337639Sgblack@eecs.umich.edu
2347639Sgblack@eecs.umich.edu        union RegVect {
2357639Sgblack@eecs.umich.edu            FloatRegBits regs[rCount];
2367639Sgblack@eecs.umich.edu            Element elements[eCount];
2377639Sgblack@eecs.umich.edu        };
2387639Sgblack@eecs.umich.edu
2397639Sgblack@eecs.umich.edu        if (%(predicate_test)s)
2407639Sgblack@eecs.umich.edu        {
2417639Sgblack@eecs.umich.edu            %(code)s;
2427639Sgblack@eecs.umich.edu            if (fault == NoFault)
2437639Sgblack@eecs.umich.edu            {
2447639Sgblack@eecs.umich.edu                %(op_wb)s;
2457639Sgblack@eecs.umich.edu            }
2468072SGiacomo.Gabrielli@arm.com        } else {
2478072SGiacomo.Gabrielli@arm.com            xc->setPredicate(false);
2487639Sgblack@eecs.umich.edu        }
2497639Sgblack@eecs.umich.edu
2507639Sgblack@eecs.umich.edu        return fault;
2517639Sgblack@eecs.umich.edu    }
2527639Sgblack@eecs.umich.edu}};
2537639Sgblack@eecs.umich.edu
2547639Sgblack@eecs.umich.eduoutput header {{
2558902Sandreas.hansson@arm.com        template <typename T>
2568902Sandreas.hansson@arm.com            struct bigger_type_t;
2578902Sandreas.hansson@arm.com
2588902Sandreas.hansson@arm.com        template<> struct bigger_type_t<uint8_t> { typedef uint16_t type; };
2598902Sandreas.hansson@arm.com        template<> struct bigger_type_t<uint16_t> { typedef uint32_t type; };
2608902Sandreas.hansson@arm.com        template<> struct bigger_type_t<uint32_t> { typedef uint64_t type; };
2618902Sandreas.hansson@arm.com
2628902Sandreas.hansson@arm.com        template<> struct bigger_type_t<int8_t> { typedef int16_t type; };
2638902Sandreas.hansson@arm.com        template<> struct bigger_type_t<int16_t> { typedef int32_t type; };
2648902Sandreas.hansson@arm.com        template<> struct bigger_type_t<int32_t> { typedef int64_t type; };
2657639Sgblack@eecs.umich.edu}};
2667639Sgblack@eecs.umich.edu
2677639Sgblack@eecs.umich.edudef template NeonUnequalRegExecute {{
2687639Sgblack@eecs.umich.edu    template <class Element>
2697639Sgblack@eecs.umich.edu    Fault %(class_name)s<Element>::execute(%(CPU_exec_context)s *xc,
2707639Sgblack@eecs.umich.edu            Trace::InstRecord *traceData) const
2717639Sgblack@eecs.umich.edu    {
2728902Sandreas.hansson@arm.com        typedef typename bigger_type_t<Element>::type BigElement;
2737639Sgblack@eecs.umich.edu        Fault fault = NoFault;
2747639Sgblack@eecs.umich.edu        %(op_decl)s;
2757639Sgblack@eecs.umich.edu        %(op_rd)s;
2767639Sgblack@eecs.umich.edu
2777639Sgblack@eecs.umich.edu        const unsigned rCount = %(r_count)d;
2787639Sgblack@eecs.umich.edu        const unsigned eCount = rCount * sizeof(FloatRegBits) / sizeof(Element);
2797639Sgblack@eecs.umich.edu
2807639Sgblack@eecs.umich.edu        union RegVect {
2817639Sgblack@eecs.umich.edu            FloatRegBits regs[rCount];
2827639Sgblack@eecs.umich.edu            Element elements[eCount];
2837639Sgblack@eecs.umich.edu            BigElement bigElements[eCount / 2];
2847639Sgblack@eecs.umich.edu        };
2857639Sgblack@eecs.umich.edu
2867639Sgblack@eecs.umich.edu        union BigRegVect {
2877639Sgblack@eecs.umich.edu            FloatRegBits regs[2 * rCount];
2887639Sgblack@eecs.umich.edu            BigElement elements[eCount];
2897639Sgblack@eecs.umich.edu        };
2907639Sgblack@eecs.umich.edu
2917639Sgblack@eecs.umich.edu        if (%(predicate_test)s)
2927639Sgblack@eecs.umich.edu        {
2937639Sgblack@eecs.umich.edu            %(code)s;
2947639Sgblack@eecs.umich.edu            if (fault == NoFault)
2957639Sgblack@eecs.umich.edu            {
2967639Sgblack@eecs.umich.edu                %(op_wb)s;
2977639Sgblack@eecs.umich.edu            }
2988072SGiacomo.Gabrielli@arm.com        } else {
2998072SGiacomo.Gabrielli@arm.com            xc->setPredicate(false);
3007639Sgblack@eecs.umich.edu        }
3017639Sgblack@eecs.umich.edu
3027639Sgblack@eecs.umich.edu        return fault;
3037639Sgblack@eecs.umich.edu    }
3047639Sgblack@eecs.umich.edu}};
305