17639Sgblack@eecs.umich.edu// -*- mode:c++ -*-
27639Sgblack@eecs.umich.edu
311513Sandreas.sandberg@arm.com// Copyright (c) 2010-2012, 2016 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    {
4311513Sandreas.sandberg@arm.com        Fault fault = checkAdvSIMDOrFPEnabled32(xc->tcBase(),
4411513Sandreas.sandberg@arm.com                                                Cpsr, Cpacr, Nsacr, Fpexc,
4511513Sandreas.sandberg@arm.com                                                true, true);
4611513Sandreas.sandberg@arm.com        if (fault != NoFault)
4711513Sandreas.sandberg@arm.com            return fault;
4810037SARM gem5 Developers    }
497644Sali.saidi@arm.com    '''
507644Sali.saidi@arm.com}};
517644Sali.saidi@arm.com
527644Sali.saidi@arm.com
537639Sgblack@eecs.umich.edudef template NeonRegRegRegOpDeclare {{
547639Sgblack@eecs.umich.edutemplate <class _Element>
557639Sgblack@eecs.umich.educlass %(class_name)s : public %(base_class)s
567639Sgblack@eecs.umich.edu{
577639Sgblack@eecs.umich.edu  protected:
587639Sgblack@eecs.umich.edu    typedef _Element Element;
597639Sgblack@eecs.umich.edu  public:
607639Sgblack@eecs.umich.edu    // Constructor
617639Sgblack@eecs.umich.edu    %(class_name)s(ExtMachInst machInst,
627639Sgblack@eecs.umich.edu                   IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2)
637639Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
647639Sgblack@eecs.umich.edu                         _dest, _op1, _op2)
657639Sgblack@eecs.umich.edu    {
667639Sgblack@eecs.umich.edu        %(constructor)s;
677848SAli.Saidi@ARM.com        if (!(condCode == COND_AL || condCode == COND_UC)) {
687848SAli.Saidi@ARM.com            for (int x = 0; x < _numDestRegs; x++) {
697848SAli.Saidi@ARM.com                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
707848SAli.Saidi@ARM.com            }
717848SAli.Saidi@ARM.com        }
727639Sgblack@eecs.umich.edu    }
737639Sgblack@eecs.umich.edu
7412616Sgabeblack@google.com    Fault execute(ExecContext *, Trace::InstRecord *) const override;
757639Sgblack@eecs.umich.edu};
767639Sgblack@eecs.umich.edu}};
777639Sgblack@eecs.umich.edu
787639Sgblack@eecs.umich.edudef template NeonRegRegRegImmOpDeclare {{
797639Sgblack@eecs.umich.edutemplate <class _Element>
807639Sgblack@eecs.umich.educlass %(class_name)s : public %(base_class)s
817639Sgblack@eecs.umich.edu{
827639Sgblack@eecs.umich.edu  protected:
837639Sgblack@eecs.umich.edu    typedef _Element Element;
847639Sgblack@eecs.umich.edu  public:
857639Sgblack@eecs.umich.edu    // Constructor
867639Sgblack@eecs.umich.edu    %(class_name)s(ExtMachInst machInst,
877639Sgblack@eecs.umich.edu                   IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
887639Sgblack@eecs.umich.edu                   uint64_t _imm)
897639Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
907639Sgblack@eecs.umich.edu                         _dest, _op1, _op2, _imm)
917639Sgblack@eecs.umich.edu    {
927639Sgblack@eecs.umich.edu        %(constructor)s;
937848SAli.Saidi@ARM.com        if (!(condCode == COND_AL || condCode == COND_UC)) {
947848SAli.Saidi@ARM.com            for (int x = 0; x < _numDestRegs; x++) {
957848SAli.Saidi@ARM.com                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
967848SAli.Saidi@ARM.com            }
977848SAli.Saidi@ARM.com        }
987639Sgblack@eecs.umich.edu    }
997639Sgblack@eecs.umich.edu
10012616Sgabeblack@google.com    Fault execute(ExecContext *, Trace::InstRecord *) const override;
1017639Sgblack@eecs.umich.edu};
1027639Sgblack@eecs.umich.edu}};
1037639Sgblack@eecs.umich.edu
1047639Sgblack@eecs.umich.edudef template NeonRegRegImmOpDeclare {{
1057639Sgblack@eecs.umich.edutemplate <class _Element>
1067639Sgblack@eecs.umich.educlass %(class_name)s : public %(base_class)s
1077639Sgblack@eecs.umich.edu{
1087639Sgblack@eecs.umich.edu  protected:
1097639Sgblack@eecs.umich.edu    typedef _Element Element;
1107639Sgblack@eecs.umich.edu  public:
1117639Sgblack@eecs.umich.edu    // Constructor
1127639Sgblack@eecs.umich.edu    %(class_name)s(ExtMachInst machInst,
1137639Sgblack@eecs.umich.edu                   IntRegIndex _dest, IntRegIndex _op1, uint64_t _imm)
1147639Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1157639Sgblack@eecs.umich.edu                         _dest, _op1, _imm)
1167639Sgblack@eecs.umich.edu    {
1177639Sgblack@eecs.umich.edu        %(constructor)s;
1187848SAli.Saidi@ARM.com        if (!(condCode == COND_AL || condCode == COND_UC)) {
1197848SAli.Saidi@ARM.com            for (int x = 0; x < _numDestRegs; x++) {
1207848SAli.Saidi@ARM.com                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1217848SAli.Saidi@ARM.com            }
1227848SAli.Saidi@ARM.com        }
1237639Sgblack@eecs.umich.edu    }
1247639Sgblack@eecs.umich.edu
12512616Sgabeblack@google.com    Fault execute(ExecContext *, Trace::InstRecord *) const override;
1267639Sgblack@eecs.umich.edu};
1277639Sgblack@eecs.umich.edu}};
1287639Sgblack@eecs.umich.edu
1297639Sgblack@eecs.umich.edudef template NeonRegImmOpDeclare {{
1307639Sgblack@eecs.umich.edutemplate <class _Element>
1317639Sgblack@eecs.umich.educlass %(class_name)s : public %(base_class)s
1327639Sgblack@eecs.umich.edu{
1337639Sgblack@eecs.umich.edu  protected:
1347639Sgblack@eecs.umich.edu    typedef _Element Element;
1357639Sgblack@eecs.umich.edu  public:
1367639Sgblack@eecs.umich.edu    // Constructor
1377639Sgblack@eecs.umich.edu    %(class_name)s(ExtMachInst machInst, IntRegIndex _dest, uint64_t _imm)
1387639Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest, _imm)
1397639Sgblack@eecs.umich.edu    {
1407639Sgblack@eecs.umich.edu        %(constructor)s;
1417848SAli.Saidi@ARM.com        if (!(condCode == COND_AL || condCode == COND_UC)) {
1427848SAli.Saidi@ARM.com            for (int x = 0; x < _numDestRegs; x++) {
1437848SAli.Saidi@ARM.com                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1447848SAli.Saidi@ARM.com            }
1457848SAli.Saidi@ARM.com        }
1467639Sgblack@eecs.umich.edu    }
1477639Sgblack@eecs.umich.edu
14812616Sgabeblack@google.com    Fault execute(ExecContext *, Trace::InstRecord *) const override;
1497639Sgblack@eecs.umich.edu};
1507639Sgblack@eecs.umich.edu}};
1517639Sgblack@eecs.umich.edu
1527639Sgblack@eecs.umich.edudef template NeonRegRegOpDeclare {{
1537639Sgblack@eecs.umich.edutemplate <class _Element>
1547639Sgblack@eecs.umich.educlass %(class_name)s : public %(base_class)s
1557639Sgblack@eecs.umich.edu{
1567639Sgblack@eecs.umich.edu  protected:
1577639Sgblack@eecs.umich.edu    typedef _Element Element;
1587639Sgblack@eecs.umich.edu  public:
1597639Sgblack@eecs.umich.edu    // Constructor
1607639Sgblack@eecs.umich.edu    %(class_name)s(ExtMachInst machInst,
1617639Sgblack@eecs.umich.edu                   IntRegIndex _dest, IntRegIndex _op1)
1627639Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1637639Sgblack@eecs.umich.edu                         _dest, _op1)
1647639Sgblack@eecs.umich.edu    {
1657639Sgblack@eecs.umich.edu        %(constructor)s;
1667848SAli.Saidi@ARM.com        if (!(condCode == COND_AL || condCode == COND_UC)) {
1677848SAli.Saidi@ARM.com            for (int x = 0; x < _numDestRegs; x++) {
1687848SAli.Saidi@ARM.com                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1697848SAli.Saidi@ARM.com            }
1707848SAli.Saidi@ARM.com        }
1717639Sgblack@eecs.umich.edu    }
1727639Sgblack@eecs.umich.edu
17312616Sgabeblack@google.com    Fault execute(ExecContext *, Trace::InstRecord *) const override;
1747639Sgblack@eecs.umich.edu};
1757639Sgblack@eecs.umich.edu}};
1767639Sgblack@eecs.umich.edu
1777639Sgblack@eecs.umich.edudef template NeonExecDeclare {{
1787639Sgblack@eecs.umich.edu    template
1797639Sgblack@eecs.umich.edu    Fault %(class_name)s<%(targs)s>::execute(
18012234Sgabeblack@google.com            ExecContext *, Trace::InstRecord *) const;
1817639Sgblack@eecs.umich.edu}};
1827639Sgblack@eecs.umich.edu
1837641Sgblack@eecs.umich.eduoutput header {{
1847641Sgblack@eecs.umich.edu    template <class T>
1857641Sgblack@eecs.umich.edu    // Implement a less-than-zero function: ltz()
1867641Sgblack@eecs.umich.edu    // this function exists because some versions of GCC complain when a
1877641Sgblack@eecs.umich.edu    // comparison is done between a unsigned variable and 0 and for GCC 4.2
1887641Sgblack@eecs.umich.edu    // there is no way to disable this warning
1897641Sgblack@eecs.umich.edu    inline bool ltz(T t);
1907641Sgblack@eecs.umich.edu
1917641Sgblack@eecs.umich.edu    template <>
1927641Sgblack@eecs.umich.edu    inline bool ltz(uint8_t) { return false; }
1937641Sgblack@eecs.umich.edu    template <>
1947641Sgblack@eecs.umich.edu    inline bool ltz(uint16_t) { return false; }
1957641Sgblack@eecs.umich.edu    template <>
1967641Sgblack@eecs.umich.edu    inline bool ltz(uint32_t) { return false; }
1977641Sgblack@eecs.umich.edu    template <>
1987641Sgblack@eecs.umich.edu    inline bool ltz(uint64_t) { return false; }
1997641Sgblack@eecs.umich.edu    template <>
2007641Sgblack@eecs.umich.edu    inline bool ltz(int8_t v) { return v < 0; }
2017641Sgblack@eecs.umich.edu    template <>
2027641Sgblack@eecs.umich.edu    inline bool ltz(int16_t v) { return v < 0; }
2037641Sgblack@eecs.umich.edu    template <>
2047641Sgblack@eecs.umich.edu    inline bool ltz(int32_t v) { return v < 0; }
2057641Sgblack@eecs.umich.edu    template <>
2067641Sgblack@eecs.umich.edu    inline bool ltz(int64_t v) { return v < 0; }
2077641Sgblack@eecs.umich.edu}};
2087641Sgblack@eecs.umich.edu
2097639Sgblack@eecs.umich.edudef template NeonEqualRegExecute {{
2107639Sgblack@eecs.umich.edu    template <class Element>
21112234Sgabeblack@google.com    Fault %(class_name)s<Element>::execute(ExecContext *xc,
2127639Sgblack@eecs.umich.edu            Trace::InstRecord *traceData) const
2137639Sgblack@eecs.umich.edu    {
2147639Sgblack@eecs.umich.edu        Fault fault = NoFault;
2157639Sgblack@eecs.umich.edu        %(op_decl)s;
2167639Sgblack@eecs.umich.edu        %(op_rd)s;
2177639Sgblack@eecs.umich.edu
2187639Sgblack@eecs.umich.edu        const unsigned rCount = %(r_count)d;
21913544Sgabeblack@google.com        const unsigned eCount = rCount * sizeof(uint32_t) / sizeof(Element);
2207639Sgblack@eecs.umich.edu
2217639Sgblack@eecs.umich.edu        union RegVect {
22213544Sgabeblack@google.com            uint32_t regs[rCount];
2237639Sgblack@eecs.umich.edu            Element elements[eCount];
2247639Sgblack@eecs.umich.edu        };
2257639Sgblack@eecs.umich.edu
2267639Sgblack@eecs.umich.edu        if (%(predicate_test)s)
2277639Sgblack@eecs.umich.edu        {
2287639Sgblack@eecs.umich.edu            %(code)s;
2297639Sgblack@eecs.umich.edu            if (fault == NoFault)
2307639Sgblack@eecs.umich.edu            {
2317639Sgblack@eecs.umich.edu                %(op_wb)s;
2327639Sgblack@eecs.umich.edu            }
2338072SGiacomo.Gabrielli@arm.com        } else {
2348072SGiacomo.Gabrielli@arm.com            xc->setPredicate(false);
2357639Sgblack@eecs.umich.edu        }
2367639Sgblack@eecs.umich.edu
2377639Sgblack@eecs.umich.edu        return fault;
2387639Sgblack@eecs.umich.edu    }
2397639Sgblack@eecs.umich.edu}};
2407639Sgblack@eecs.umich.edu
2417639Sgblack@eecs.umich.eduoutput header {{
2428902Sandreas.hansson@arm.com        template <typename T>
2438902Sandreas.hansson@arm.com            struct bigger_type_t;
2448902Sandreas.hansson@arm.com
2458902Sandreas.hansson@arm.com        template<> struct bigger_type_t<uint8_t> { typedef uint16_t type; };
2468902Sandreas.hansson@arm.com        template<> struct bigger_type_t<uint16_t> { typedef uint32_t type; };
2478902Sandreas.hansson@arm.com        template<> struct bigger_type_t<uint32_t> { typedef uint64_t type; };
2488902Sandreas.hansson@arm.com
2498902Sandreas.hansson@arm.com        template<> struct bigger_type_t<int8_t> { typedef int16_t type; };
2508902Sandreas.hansson@arm.com        template<> struct bigger_type_t<int16_t> { typedef int32_t type; };
2518902Sandreas.hansson@arm.com        template<> struct bigger_type_t<int32_t> { typedef int64_t type; };
2527639Sgblack@eecs.umich.edu}};
2537639Sgblack@eecs.umich.edu
2547639Sgblack@eecs.umich.edudef template NeonUnequalRegExecute {{
2557639Sgblack@eecs.umich.edu    template <class Element>
25612234Sgabeblack@google.com    Fault %(class_name)s<Element>::execute(ExecContext *xc,
2577639Sgblack@eecs.umich.edu            Trace::InstRecord *traceData) const
2587639Sgblack@eecs.umich.edu    {
2598902Sandreas.hansson@arm.com        typedef typename bigger_type_t<Element>::type BigElement;
2607639Sgblack@eecs.umich.edu        Fault fault = NoFault;
2617639Sgblack@eecs.umich.edu        %(op_decl)s;
2627639Sgblack@eecs.umich.edu        %(op_rd)s;
2637639Sgblack@eecs.umich.edu
2647639Sgblack@eecs.umich.edu        const unsigned rCount = %(r_count)d;
26513544Sgabeblack@google.com        const unsigned eCount = rCount * sizeof(uint32_t) / sizeof(Element);
2667639Sgblack@eecs.umich.edu
2677639Sgblack@eecs.umich.edu        union RegVect {
26813544Sgabeblack@google.com            uint32_t regs[rCount];
2697639Sgblack@eecs.umich.edu            Element elements[eCount];
2707639Sgblack@eecs.umich.edu            BigElement bigElements[eCount / 2];
2717639Sgblack@eecs.umich.edu        };
2727639Sgblack@eecs.umich.edu
2737639Sgblack@eecs.umich.edu        union BigRegVect {
27413544Sgabeblack@google.com            uint32_t regs[2 * rCount];
2757639Sgblack@eecs.umich.edu            BigElement elements[eCount];
2767639Sgblack@eecs.umich.edu        };
2777639Sgblack@eecs.umich.edu
2787639Sgblack@eecs.umich.edu        if (%(predicate_test)s)
2797639Sgblack@eecs.umich.edu        {
2807639Sgblack@eecs.umich.edu            %(code)s;
2817639Sgblack@eecs.umich.edu            if (fault == NoFault)
2827639Sgblack@eecs.umich.edu            {
2837639Sgblack@eecs.umich.edu                %(op_wb)s;
2847639Sgblack@eecs.umich.edu            }
2858072SGiacomo.Gabrielli@arm.com        } else {
2868072SGiacomo.Gabrielli@arm.com            xc->setPredicate(false);
2877639Sgblack@eecs.umich.edu        }
2887639Sgblack@eecs.umich.edu
2897639Sgblack@eecs.umich.edu        return fault;
2907639Sgblack@eecs.umich.edu    }
2917639Sgblack@eecs.umich.edu}};
292