neon.isa revision 7644
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;
627639Sgblack@eecs.umich.edu    }
637639Sgblack@eecs.umich.edu
647639Sgblack@eecs.umich.edu    %(BasicExecDeclare)s
657639Sgblack@eecs.umich.edu};
667639Sgblack@eecs.umich.edu}};
677639Sgblack@eecs.umich.edu
687639Sgblack@eecs.umich.edudef template NeonRegRegRegImmOpDeclare {{
697639Sgblack@eecs.umich.edutemplate <class _Element>
707639Sgblack@eecs.umich.educlass %(class_name)s : public %(base_class)s
717639Sgblack@eecs.umich.edu{
727639Sgblack@eecs.umich.edu  protected:
737639Sgblack@eecs.umich.edu    typedef _Element Element;
747639Sgblack@eecs.umich.edu  public:
757639Sgblack@eecs.umich.edu    // Constructor
767639Sgblack@eecs.umich.edu    %(class_name)s(ExtMachInst machInst,
777639Sgblack@eecs.umich.edu                   IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
787639Sgblack@eecs.umich.edu                   uint64_t _imm)
797639Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
807639Sgblack@eecs.umich.edu                         _dest, _op1, _op2, _imm)
817639Sgblack@eecs.umich.edu    {
827639Sgblack@eecs.umich.edu        %(constructor)s;
837639Sgblack@eecs.umich.edu    }
847639Sgblack@eecs.umich.edu
857639Sgblack@eecs.umich.edu    %(BasicExecDeclare)s
867639Sgblack@eecs.umich.edu};
877639Sgblack@eecs.umich.edu}};
887639Sgblack@eecs.umich.edu
897639Sgblack@eecs.umich.edudef template NeonRegRegImmOpDeclare {{
907639Sgblack@eecs.umich.edutemplate <class _Element>
917639Sgblack@eecs.umich.educlass %(class_name)s : public %(base_class)s
927639Sgblack@eecs.umich.edu{
937639Sgblack@eecs.umich.edu  protected:
947639Sgblack@eecs.umich.edu    typedef _Element Element;
957639Sgblack@eecs.umich.edu  public:
967639Sgblack@eecs.umich.edu    // Constructor
977639Sgblack@eecs.umich.edu    %(class_name)s(ExtMachInst machInst,
987639Sgblack@eecs.umich.edu                   IntRegIndex _dest, IntRegIndex _op1, uint64_t _imm)
997639Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1007639Sgblack@eecs.umich.edu                         _dest, _op1, _imm)
1017639Sgblack@eecs.umich.edu    {
1027639Sgblack@eecs.umich.edu        %(constructor)s;
1037639Sgblack@eecs.umich.edu    }
1047639Sgblack@eecs.umich.edu
1057639Sgblack@eecs.umich.edu    %(BasicExecDeclare)s
1067639Sgblack@eecs.umich.edu};
1077639Sgblack@eecs.umich.edu}};
1087639Sgblack@eecs.umich.edu
1097639Sgblack@eecs.umich.edudef template NeonRegImmOpDeclare {{
1107639Sgblack@eecs.umich.edutemplate <class _Element>
1117639Sgblack@eecs.umich.educlass %(class_name)s : public %(base_class)s
1127639Sgblack@eecs.umich.edu{
1137639Sgblack@eecs.umich.edu  protected:
1147639Sgblack@eecs.umich.edu    typedef _Element Element;
1157639Sgblack@eecs.umich.edu  public:
1167639Sgblack@eecs.umich.edu    // Constructor
1177639Sgblack@eecs.umich.edu    %(class_name)s(ExtMachInst machInst, IntRegIndex _dest, uint64_t _imm)
1187639Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest, _imm)
1197639Sgblack@eecs.umich.edu    {
1207639Sgblack@eecs.umich.edu        %(constructor)s;
1217639Sgblack@eecs.umich.edu    }
1227639Sgblack@eecs.umich.edu
1237639Sgblack@eecs.umich.edu    %(BasicExecDeclare)s
1247639Sgblack@eecs.umich.edu};
1257639Sgblack@eecs.umich.edu}};
1267639Sgblack@eecs.umich.edu
1277639Sgblack@eecs.umich.edudef template NeonRegRegOpDeclare {{
1287639Sgblack@eecs.umich.edutemplate <class _Element>
1297639Sgblack@eecs.umich.educlass %(class_name)s : public %(base_class)s
1307639Sgblack@eecs.umich.edu{
1317639Sgblack@eecs.umich.edu  protected:
1327639Sgblack@eecs.umich.edu    typedef _Element Element;
1337639Sgblack@eecs.umich.edu  public:
1347639Sgblack@eecs.umich.edu    // Constructor
1357639Sgblack@eecs.umich.edu    %(class_name)s(ExtMachInst machInst,
1367639Sgblack@eecs.umich.edu                   IntRegIndex _dest, IntRegIndex _op1)
1377639Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1387639Sgblack@eecs.umich.edu                         _dest, _op1)
1397639Sgblack@eecs.umich.edu    {
1407639Sgblack@eecs.umich.edu        %(constructor)s;
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 NeonExecDeclare {{
1487639Sgblack@eecs.umich.edu    template
1497639Sgblack@eecs.umich.edu    Fault %(class_name)s<%(targs)s>::execute(
1507639Sgblack@eecs.umich.edu            %(CPU_exec_context)s *, Trace::InstRecord *) const;
1517639Sgblack@eecs.umich.edu}};
1527639Sgblack@eecs.umich.edu
1537641Sgblack@eecs.umich.eduoutput header {{
1547641Sgblack@eecs.umich.edu    template <class T>
1557641Sgblack@eecs.umich.edu    // Implement a less-than-zero function: ltz()
1567641Sgblack@eecs.umich.edu    // this function exists because some versions of GCC complain when a
1577641Sgblack@eecs.umich.edu    // comparison is done between a unsigned variable and 0 and for GCC 4.2
1587641Sgblack@eecs.umich.edu    // there is no way to disable this warning
1597641Sgblack@eecs.umich.edu    inline bool ltz(T t);
1607641Sgblack@eecs.umich.edu
1617641Sgblack@eecs.umich.edu    template <>
1627641Sgblack@eecs.umich.edu    inline bool ltz(uint8_t) { return false; }
1637641Sgblack@eecs.umich.edu    template <>
1647641Sgblack@eecs.umich.edu    inline bool ltz(uint16_t) { return false; }
1657641Sgblack@eecs.umich.edu    template <>
1667641Sgblack@eecs.umich.edu    inline bool ltz(uint32_t) { return false; }
1677641Sgblack@eecs.umich.edu    template <>
1687641Sgblack@eecs.umich.edu    inline bool ltz(uint64_t) { return false; }
1697641Sgblack@eecs.umich.edu    template <>
1707641Sgblack@eecs.umich.edu    inline bool ltz(int8_t v) { return v < 0; }
1717641Sgblack@eecs.umich.edu    template <>
1727641Sgblack@eecs.umich.edu    inline bool ltz(int16_t v) { return v < 0; }
1737641Sgblack@eecs.umich.edu    template <>
1747641Sgblack@eecs.umich.edu    inline bool ltz(int32_t v) { return v < 0; }
1757641Sgblack@eecs.umich.edu    template <>
1767641Sgblack@eecs.umich.edu    inline bool ltz(int64_t v) { return v < 0; }
1777641Sgblack@eecs.umich.edu}};
1787641Sgblack@eecs.umich.edu
1797639Sgblack@eecs.umich.edudef template NeonEqualRegExecute {{
1807639Sgblack@eecs.umich.edu    template <class Element>
1817639Sgblack@eecs.umich.edu    Fault %(class_name)s<Element>::execute(%(CPU_exec_context)s *xc,
1827639Sgblack@eecs.umich.edu            Trace::InstRecord *traceData) const
1837639Sgblack@eecs.umich.edu    {
1847639Sgblack@eecs.umich.edu        Fault fault = NoFault;
1857639Sgblack@eecs.umich.edu        %(op_decl)s;
1867639Sgblack@eecs.umich.edu        %(op_rd)s;
1877639Sgblack@eecs.umich.edu
1887639Sgblack@eecs.umich.edu        const unsigned rCount = %(r_count)d;
1897639Sgblack@eecs.umich.edu        const unsigned eCount = rCount * sizeof(FloatRegBits) / sizeof(Element);
1907639Sgblack@eecs.umich.edu
1917639Sgblack@eecs.umich.edu        union RegVect {
1927639Sgblack@eecs.umich.edu            FloatRegBits regs[rCount];
1937639Sgblack@eecs.umich.edu            Element elements[eCount];
1947639Sgblack@eecs.umich.edu        };
1957639Sgblack@eecs.umich.edu
1967639Sgblack@eecs.umich.edu        if (%(predicate_test)s)
1977639Sgblack@eecs.umich.edu        {
1987639Sgblack@eecs.umich.edu            %(code)s;
1997639Sgblack@eecs.umich.edu            if (fault == NoFault)
2007639Sgblack@eecs.umich.edu            {
2017639Sgblack@eecs.umich.edu                %(op_wb)s;
2027639Sgblack@eecs.umich.edu            }
2037639Sgblack@eecs.umich.edu        }
2047639Sgblack@eecs.umich.edu
2057639Sgblack@eecs.umich.edu        if (fault == NoFault && machInst.itstateMask != 0) {
2067639Sgblack@eecs.umich.edu            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
2077639Sgblack@eecs.umich.edu        }
2087639Sgblack@eecs.umich.edu
2097639Sgblack@eecs.umich.edu        return fault;
2107639Sgblack@eecs.umich.edu    }
2117639Sgblack@eecs.umich.edu}};
2127639Sgblack@eecs.umich.edu
2137639Sgblack@eecs.umich.eduoutput header {{
2147639Sgblack@eecs.umich.edu    uint16_t nextBiggerType(uint8_t);
2157639Sgblack@eecs.umich.edu    uint32_t nextBiggerType(uint16_t);
2167639Sgblack@eecs.umich.edu    uint64_t nextBiggerType(uint32_t);
2177639Sgblack@eecs.umich.edu    int16_t nextBiggerType(int8_t);
2187639Sgblack@eecs.umich.edu    int32_t nextBiggerType(int16_t);
2197639Sgblack@eecs.umich.edu    int64_t nextBiggerType(int32_t);
2207639Sgblack@eecs.umich.edu}};
2217639Sgblack@eecs.umich.edu
2227639Sgblack@eecs.umich.edudef template NeonUnequalRegExecute {{
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        typedef typeof(nextBiggerType((Element)0)) BigElement;
2287639Sgblack@eecs.umich.edu        Fault fault = NoFault;
2297639Sgblack@eecs.umich.edu        %(op_decl)s;
2307639Sgblack@eecs.umich.edu        %(op_rd)s;
2317639Sgblack@eecs.umich.edu
2327639Sgblack@eecs.umich.edu        const unsigned rCount = %(r_count)d;
2337639Sgblack@eecs.umich.edu        const unsigned eCount = rCount * sizeof(FloatRegBits) / sizeof(Element);
2347639Sgblack@eecs.umich.edu
2357639Sgblack@eecs.umich.edu        union RegVect {
2367639Sgblack@eecs.umich.edu            FloatRegBits regs[rCount];
2377639Sgblack@eecs.umich.edu            Element elements[eCount];
2387639Sgblack@eecs.umich.edu            BigElement bigElements[eCount / 2];
2397639Sgblack@eecs.umich.edu        };
2407639Sgblack@eecs.umich.edu
2417639Sgblack@eecs.umich.edu        union BigRegVect {
2427639Sgblack@eecs.umich.edu            FloatRegBits regs[2 * rCount];
2437639Sgblack@eecs.umich.edu            BigElement elements[eCount];
2447639Sgblack@eecs.umich.edu        };
2457639Sgblack@eecs.umich.edu
2467639Sgblack@eecs.umich.edu        if (%(predicate_test)s)
2477639Sgblack@eecs.umich.edu        {
2487639Sgblack@eecs.umich.edu            %(code)s;
2497639Sgblack@eecs.umich.edu            if (fault == NoFault)
2507639Sgblack@eecs.umich.edu            {
2517639Sgblack@eecs.umich.edu                %(op_wb)s;
2527639Sgblack@eecs.umich.edu            }
2537639Sgblack@eecs.umich.edu        }
2547639Sgblack@eecs.umich.edu
2557639Sgblack@eecs.umich.edu        if (fault == NoFault && machInst.itstateMask != 0) {
2567639Sgblack@eecs.umich.edu            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
2577639Sgblack@eecs.umich.edu        }
2587639Sgblack@eecs.umich.edu
2597639Sgblack@eecs.umich.edu        return fault;
2607639Sgblack@eecs.umich.edu    }
2617639Sgblack@eecs.umich.edu}};
262