neon.isa revision 8902
17639Sgblack@eecs.umich.edu// -*- mode:c++ -*-
27639Sgblack@eecs.umich.edu
37639Sgblack@eecs.umich.edu// Copyright (c) 2010 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 = '''
427644Sali.saidi@arm.com        if (!neonEnabled(Cpacr, Cpsr, Fpexc))
437644Sali.saidi@arm.com            return disabledFault();
447644Sali.saidi@arm.com    '''
457644Sali.saidi@arm.com}};
467644Sali.saidi@arm.com
477644Sali.saidi@arm.com
487639Sgblack@eecs.umich.edudef template NeonRegRegRegOpDeclare {{
497639Sgblack@eecs.umich.edutemplate <class _Element>
507639Sgblack@eecs.umich.educlass %(class_name)s : public %(base_class)s
517639Sgblack@eecs.umich.edu{
527639Sgblack@eecs.umich.edu  protected:
537639Sgblack@eecs.umich.edu    typedef _Element Element;
547639Sgblack@eecs.umich.edu  public:
557639Sgblack@eecs.umich.edu    // Constructor
567639Sgblack@eecs.umich.edu    %(class_name)s(ExtMachInst machInst,
577639Sgblack@eecs.umich.edu                   IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2)
587639Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
597639Sgblack@eecs.umich.edu                         _dest, _op1, _op2)
607639Sgblack@eecs.umich.edu    {
617639Sgblack@eecs.umich.edu        %(constructor)s;
627848SAli.Saidi@ARM.com        if (!(condCode == COND_AL || condCode == COND_UC)) {
637848SAli.Saidi@ARM.com            for (int x = 0; x < _numDestRegs; x++) {
647848SAli.Saidi@ARM.com                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
657848SAli.Saidi@ARM.com            }
667848SAli.Saidi@ARM.com        }
677639Sgblack@eecs.umich.edu    }
687639Sgblack@eecs.umich.edu
697639Sgblack@eecs.umich.edu    %(BasicExecDeclare)s
707639Sgblack@eecs.umich.edu};
717639Sgblack@eecs.umich.edu}};
727639Sgblack@eecs.umich.edu
737639Sgblack@eecs.umich.edudef template NeonRegRegRegImmOpDeclare {{
747639Sgblack@eecs.umich.edutemplate <class _Element>
757639Sgblack@eecs.umich.educlass %(class_name)s : public %(base_class)s
767639Sgblack@eecs.umich.edu{
777639Sgblack@eecs.umich.edu  protected:
787639Sgblack@eecs.umich.edu    typedef _Element Element;
797639Sgblack@eecs.umich.edu  public:
807639Sgblack@eecs.umich.edu    // Constructor
817639Sgblack@eecs.umich.edu    %(class_name)s(ExtMachInst machInst,
827639Sgblack@eecs.umich.edu                   IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
837639Sgblack@eecs.umich.edu                   uint64_t _imm)
847639Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
857639Sgblack@eecs.umich.edu                         _dest, _op1, _op2, _imm)
867639Sgblack@eecs.umich.edu    {
877639Sgblack@eecs.umich.edu        %(constructor)s;
887848SAli.Saidi@ARM.com        if (!(condCode == COND_AL || condCode == COND_UC)) {
897848SAli.Saidi@ARM.com            for (int x = 0; x < _numDestRegs; x++) {
907848SAli.Saidi@ARM.com                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
917848SAli.Saidi@ARM.com            }
927848SAli.Saidi@ARM.com        }
937639Sgblack@eecs.umich.edu    }
947639Sgblack@eecs.umich.edu
957639Sgblack@eecs.umich.edu    %(BasicExecDeclare)s
967639Sgblack@eecs.umich.edu};
977639Sgblack@eecs.umich.edu}};
987639Sgblack@eecs.umich.edu
997639Sgblack@eecs.umich.edudef template NeonRegRegImmOpDeclare {{
1007639Sgblack@eecs.umich.edutemplate <class _Element>
1017639Sgblack@eecs.umich.educlass %(class_name)s : public %(base_class)s
1027639Sgblack@eecs.umich.edu{
1037639Sgblack@eecs.umich.edu  protected:
1047639Sgblack@eecs.umich.edu    typedef _Element Element;
1057639Sgblack@eecs.umich.edu  public:
1067639Sgblack@eecs.umich.edu    // Constructor
1077639Sgblack@eecs.umich.edu    %(class_name)s(ExtMachInst machInst,
1087639Sgblack@eecs.umich.edu                   IntRegIndex _dest, IntRegIndex _op1, uint64_t _imm)
1097639Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1107639Sgblack@eecs.umich.edu                         _dest, _op1, _imm)
1117639Sgblack@eecs.umich.edu    {
1127639Sgblack@eecs.umich.edu        %(constructor)s;
1137848SAli.Saidi@ARM.com        if (!(condCode == COND_AL || condCode == COND_UC)) {
1147848SAli.Saidi@ARM.com            for (int x = 0; x < _numDestRegs; x++) {
1157848SAli.Saidi@ARM.com                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1167848SAli.Saidi@ARM.com            }
1177848SAli.Saidi@ARM.com        }
1187639Sgblack@eecs.umich.edu    }
1197639Sgblack@eecs.umich.edu
1207639Sgblack@eecs.umich.edu    %(BasicExecDeclare)s
1217639Sgblack@eecs.umich.edu};
1227639Sgblack@eecs.umich.edu}};
1237639Sgblack@eecs.umich.edu
1247639Sgblack@eecs.umich.edudef template NeonRegImmOpDeclare {{
1257639Sgblack@eecs.umich.edutemplate <class _Element>
1267639Sgblack@eecs.umich.educlass %(class_name)s : public %(base_class)s
1277639Sgblack@eecs.umich.edu{
1287639Sgblack@eecs.umich.edu  protected:
1297639Sgblack@eecs.umich.edu    typedef _Element Element;
1307639Sgblack@eecs.umich.edu  public:
1317639Sgblack@eecs.umich.edu    // Constructor
1327639Sgblack@eecs.umich.edu    %(class_name)s(ExtMachInst machInst, IntRegIndex _dest, uint64_t _imm)
1337639Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest, _imm)
1347639Sgblack@eecs.umich.edu    {
1357639Sgblack@eecs.umich.edu        %(constructor)s;
1367848SAli.Saidi@ARM.com        if (!(condCode == COND_AL || condCode == COND_UC)) {
1377848SAli.Saidi@ARM.com            for (int x = 0; x < _numDestRegs; x++) {
1387848SAli.Saidi@ARM.com                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1397848SAli.Saidi@ARM.com            }
1407848SAli.Saidi@ARM.com        }
1417639Sgblack@eecs.umich.edu    }
1427639Sgblack@eecs.umich.edu
1437639Sgblack@eecs.umich.edu    %(BasicExecDeclare)s
1447639Sgblack@eecs.umich.edu};
1457639Sgblack@eecs.umich.edu}};
1467639Sgblack@eecs.umich.edu
1477639Sgblack@eecs.umich.edudef template NeonRegRegOpDeclare {{
1487639Sgblack@eecs.umich.edutemplate <class _Element>
1497639Sgblack@eecs.umich.educlass %(class_name)s : public %(base_class)s
1507639Sgblack@eecs.umich.edu{
1517639Sgblack@eecs.umich.edu  protected:
1527639Sgblack@eecs.umich.edu    typedef _Element Element;
1537639Sgblack@eecs.umich.edu  public:
1547639Sgblack@eecs.umich.edu    // Constructor
1557639Sgblack@eecs.umich.edu    %(class_name)s(ExtMachInst machInst,
1567639Sgblack@eecs.umich.edu                   IntRegIndex _dest, IntRegIndex _op1)
1577639Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1587639Sgblack@eecs.umich.edu                         _dest, _op1)
1597639Sgblack@eecs.umich.edu    {
1607639Sgblack@eecs.umich.edu        %(constructor)s;
1617848SAli.Saidi@ARM.com        if (!(condCode == COND_AL || condCode == COND_UC)) {
1627848SAli.Saidi@ARM.com            for (int x = 0; x < _numDestRegs; x++) {
1637848SAli.Saidi@ARM.com                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1647848SAli.Saidi@ARM.com            }
1657848SAli.Saidi@ARM.com        }
1667639Sgblack@eecs.umich.edu    }
1677639Sgblack@eecs.umich.edu
1687639Sgblack@eecs.umich.edu    %(BasicExecDeclare)s
1697639Sgblack@eecs.umich.edu};
1707639Sgblack@eecs.umich.edu}};
1717639Sgblack@eecs.umich.edu
1727639Sgblack@eecs.umich.edudef template NeonExecDeclare {{
1737639Sgblack@eecs.umich.edu    template
1747639Sgblack@eecs.umich.edu    Fault %(class_name)s<%(targs)s>::execute(
1757639Sgblack@eecs.umich.edu            %(CPU_exec_context)s *, Trace::InstRecord *) const;
1767639Sgblack@eecs.umich.edu}};
1777639Sgblack@eecs.umich.edu
1787641Sgblack@eecs.umich.eduoutput header {{
1797641Sgblack@eecs.umich.edu    template <class T>
1807641Sgblack@eecs.umich.edu    // Implement a less-than-zero function: ltz()
1817641Sgblack@eecs.umich.edu    // this function exists because some versions of GCC complain when a
1827641Sgblack@eecs.umich.edu    // comparison is done between a unsigned variable and 0 and for GCC 4.2
1837641Sgblack@eecs.umich.edu    // there is no way to disable this warning
1847641Sgblack@eecs.umich.edu    inline bool ltz(T t);
1857641Sgblack@eecs.umich.edu
1867641Sgblack@eecs.umich.edu    template <>
1877641Sgblack@eecs.umich.edu    inline bool ltz(uint8_t) { return false; }
1887641Sgblack@eecs.umich.edu    template <>
1897641Sgblack@eecs.umich.edu    inline bool ltz(uint16_t) { return false; }
1907641Sgblack@eecs.umich.edu    template <>
1917641Sgblack@eecs.umich.edu    inline bool ltz(uint32_t) { return false; }
1927641Sgblack@eecs.umich.edu    template <>
1937641Sgblack@eecs.umich.edu    inline bool ltz(uint64_t) { return false; }
1947641Sgblack@eecs.umich.edu    template <>
1957641Sgblack@eecs.umich.edu    inline bool ltz(int8_t v) { return v < 0; }
1967641Sgblack@eecs.umich.edu    template <>
1977641Sgblack@eecs.umich.edu    inline bool ltz(int16_t v) { return v < 0; }
1987641Sgblack@eecs.umich.edu    template <>
1997641Sgblack@eecs.umich.edu    inline bool ltz(int32_t v) { return v < 0; }
2007641Sgblack@eecs.umich.edu    template <>
2017641Sgblack@eecs.umich.edu    inline bool ltz(int64_t v) { return v < 0; }
2027641Sgblack@eecs.umich.edu}};
2037641Sgblack@eecs.umich.edu
2047639Sgblack@eecs.umich.edudef template NeonEqualRegExecute {{
2057639Sgblack@eecs.umich.edu    template <class Element>
2067639Sgblack@eecs.umich.edu    Fault %(class_name)s<Element>::execute(%(CPU_exec_context)s *xc,
2077639Sgblack@eecs.umich.edu            Trace::InstRecord *traceData) const
2087639Sgblack@eecs.umich.edu    {
2097639Sgblack@eecs.umich.edu        Fault fault = NoFault;
2107639Sgblack@eecs.umich.edu        %(op_decl)s;
2117639Sgblack@eecs.umich.edu        %(op_rd)s;
2127639Sgblack@eecs.umich.edu
2137639Sgblack@eecs.umich.edu        const unsigned rCount = %(r_count)d;
2147639Sgblack@eecs.umich.edu        const unsigned eCount = rCount * sizeof(FloatRegBits) / sizeof(Element);
2157639Sgblack@eecs.umich.edu
2167639Sgblack@eecs.umich.edu        union RegVect {
2177639Sgblack@eecs.umich.edu            FloatRegBits regs[rCount];
2187639Sgblack@eecs.umich.edu            Element elements[eCount];
2197639Sgblack@eecs.umich.edu        };
2207639Sgblack@eecs.umich.edu
2217639Sgblack@eecs.umich.edu        if (%(predicate_test)s)
2227639Sgblack@eecs.umich.edu        {
2237639Sgblack@eecs.umich.edu            %(code)s;
2247639Sgblack@eecs.umich.edu            if (fault == NoFault)
2257639Sgblack@eecs.umich.edu            {
2267639Sgblack@eecs.umich.edu                %(op_wb)s;
2277639Sgblack@eecs.umich.edu            }
2288072SGiacomo.Gabrielli@arm.com        } else {
2298072SGiacomo.Gabrielli@arm.com            xc->setPredicate(false);
2307639Sgblack@eecs.umich.edu        }
2317639Sgblack@eecs.umich.edu
2327639Sgblack@eecs.umich.edu        return fault;
2337639Sgblack@eecs.umich.edu    }
2347639Sgblack@eecs.umich.edu}};
2357639Sgblack@eecs.umich.edu
2367639Sgblack@eecs.umich.eduoutput header {{
2378902Sandreas.hansson@arm.com        template <typename T>
2388902Sandreas.hansson@arm.com            struct bigger_type_t;
2398902Sandreas.hansson@arm.com
2408902Sandreas.hansson@arm.com        template<> struct bigger_type_t<uint8_t> { typedef uint16_t type; };
2418902Sandreas.hansson@arm.com        template<> struct bigger_type_t<uint16_t> { typedef uint32_t type; };
2428902Sandreas.hansson@arm.com        template<> struct bigger_type_t<uint32_t> { typedef uint64_t type; };
2438902Sandreas.hansson@arm.com
2448902Sandreas.hansson@arm.com        template<> struct bigger_type_t<int8_t> { typedef int16_t type; };
2458902Sandreas.hansson@arm.com        template<> struct bigger_type_t<int16_t> { typedef int32_t type; };
2468902Sandreas.hansson@arm.com        template<> struct bigger_type_t<int32_t> { typedef int64_t type; };
2477639Sgblack@eecs.umich.edu}};
2487639Sgblack@eecs.umich.edu
2497639Sgblack@eecs.umich.edudef template NeonUnequalRegExecute {{
2507639Sgblack@eecs.umich.edu    template <class Element>
2517639Sgblack@eecs.umich.edu    Fault %(class_name)s<Element>::execute(%(CPU_exec_context)s *xc,
2527639Sgblack@eecs.umich.edu            Trace::InstRecord *traceData) const
2537639Sgblack@eecs.umich.edu    {
2548902Sandreas.hansson@arm.com        typedef typename bigger_type_t<Element>::type BigElement;
2557639Sgblack@eecs.umich.edu        Fault fault = NoFault;
2567639Sgblack@eecs.umich.edu        %(op_decl)s;
2577639Sgblack@eecs.umich.edu        %(op_rd)s;
2587639Sgblack@eecs.umich.edu
2597639Sgblack@eecs.umich.edu        const unsigned rCount = %(r_count)d;
2607639Sgblack@eecs.umich.edu        const unsigned eCount = rCount * sizeof(FloatRegBits) / sizeof(Element);
2617639Sgblack@eecs.umich.edu
2627639Sgblack@eecs.umich.edu        union RegVect {
2637639Sgblack@eecs.umich.edu            FloatRegBits regs[rCount];
2647639Sgblack@eecs.umich.edu            Element elements[eCount];
2657639Sgblack@eecs.umich.edu            BigElement bigElements[eCount / 2];
2667639Sgblack@eecs.umich.edu        };
2677639Sgblack@eecs.umich.edu
2687639Sgblack@eecs.umich.edu        union BigRegVect {
2697639Sgblack@eecs.umich.edu            FloatRegBits regs[2 * rCount];
2707639Sgblack@eecs.umich.edu            BigElement elements[eCount];
2717639Sgblack@eecs.umich.edu        };
2727639Sgblack@eecs.umich.edu
2737639Sgblack@eecs.umich.edu        if (%(predicate_test)s)
2747639Sgblack@eecs.umich.edu        {
2757639Sgblack@eecs.umich.edu            %(code)s;
2767639Sgblack@eecs.umich.edu            if (fault == NoFault)
2777639Sgblack@eecs.umich.edu            {
2787639Sgblack@eecs.umich.edu                %(op_wb)s;
2797639Sgblack@eecs.umich.edu            }
2808072SGiacomo.Gabrielli@arm.com        } else {
2818072SGiacomo.Gabrielli@arm.com            xc->setPredicate(false);
2827639Sgblack@eecs.umich.edu        }
2837639Sgblack@eecs.umich.edu
2847639Sgblack@eecs.umich.edu        return fault;
2857639Sgblack@eecs.umich.edu    }
2867639Sgblack@eecs.umich.edu}};
287