mem.isa revision 10184
12292SN/A// -*- mode:c++ -*-
22292SN/A
32292SN/A// Copyright (c) 2010, 2012 ARM Limited
42292SN/A// All rights reserved
52292SN/A//
62292SN/A// The license below extends only to copyright in the software and shall
72292SN/A// not be construed as granting a license to any other intellectual
82292SN/A// property including but not limited to intellectual property relating
92292SN/A// to a hardware implementation of the functionality of the software
102292SN/A// licensed hereunder.  You may use the software subject to the license
112292SN/A// terms below provided that you ensure that this notice is replicated
122292SN/A// unmodified and in its entirety in all distributions of the software,
132292SN/A// modified or unmodified, in source code or in binary form.
142292SN/A//
152292SN/A// Copyright (c) 2007-2008 The Florida State University
162292SN/A// All rights reserved.
172292SN/A//
182292SN/A// Redistribution and use in source and binary forms, with or without
192292SN/A// modification, are permitted provided that the following conditions are
202292SN/A// met: redistributions of source code must retain the above copyright
212292SN/A// notice, this list of conditions and the following disclaimer;
222292SN/A// redistributions in binary form must reproduce the above copyright
232292SN/A// notice, this list of conditions and the following disclaimer in the
242292SN/A// documentation and/or other materials provided with the distribution;
252292SN/A// neither the name of the copyright holders nor the names of its
262292SN/A// contributors may be used to endorse or promote products derived from
272689Sktlim@umich.edu// this software without specific prior written permission.
282689Sktlim@umich.edu//
292689Sktlim@umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
302292SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
312292SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
323326Sktlim@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
332733Sktlim@umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
342733Sktlim@umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
352907Sktlim@umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
362292SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
372292SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
382722Sktlim@umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
392669Sktlim@umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
402292SN/A//
412790Sktlim@umich.edu// Authors: Stephen Hines
422790Sktlim@umich.edu
432790Sktlim@umich.edu
442790Sktlim@umich.edudef template PanicExecute {{
452669Sktlim@umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
462678Sktlim@umich.edu                                  Trace::InstRecord *traceData) const
472678Sktlim@umich.edu    {
482678Sktlim@umich.edu        panic("Execute function executed when it shouldn't be!\n");
492292SN/A        return NoFault;
502678Sktlim@umich.edu    }
512292SN/A}};
522292SN/A
532669Sktlim@umich.edudef template PanicInitiateAcc {{
542292SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
552678Sktlim@umich.edu                                      Trace::InstRecord *traceData) const
562292SN/A    {
572678Sktlim@umich.edu        panic("InitiateAcc function executed when it shouldn't be!\n");
582678Sktlim@umich.edu        return NoFault;
592678Sktlim@umich.edu    }
602678Sktlim@umich.edu}};
612678Sktlim@umich.edu
622292SN/Adef template PanicCompleteAcc {{
632678Sktlim@umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt,
642678Sktlim@umich.edu                                      %(CPU_exec_context)s *xc,
652678Sktlim@umich.edu                                      Trace::InstRecord *traceData) const
662678Sktlim@umich.edu    {
672678Sktlim@umich.edu        panic("CompleteAcc function executed when it shouldn't be!\n");
682678Sktlim@umich.edu        return NoFault;
692292SN/A    }
702678Sktlim@umich.edu}};
712678Sktlim@umich.edu
722678Sktlim@umich.edu
732678Sktlim@umich.edudef template SwapExecute {{
742678Sktlim@umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
752678Sktlim@umich.edu                                  Trace::InstRecord *traceData) const
762678Sktlim@umich.edu    {
772698Sktlim@umich.edu        Addr EA;
782344SN/A        Fault fault = NoFault;
792678Sktlim@umich.edu
802678Sktlim@umich.edu        %(op_decl)s;
812678Sktlim@umich.edu        uint64_t memData = 0;
822820Sktlim@umich.edu        %(op_rd)s;
832678Sktlim@umich.edu        %(ea_code)s;
844032Sktlim@umich.edu
852678Sktlim@umich.edu        if (%(predicate_test)s)
862307SN/A        {
872678Sktlim@umich.edu            %(preacc_code)s;
882678Sktlim@umich.edu
892678Sktlim@umich.edu            if (fault == NoFault) {
902678Sktlim@umich.edu                fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
912678Sktlim@umich.edu                        &memData);
922678Sktlim@umich.edu            }
932678Sktlim@umich.edu
942678Sktlim@umich.edu            if (fault == NoFault) {
952344SN/A                %(postacc_code)s;
962307SN/A            }
972678Sktlim@umich.edu
984032Sktlim@umich.edu            if (fault == NoFault) {
992678Sktlim@umich.edu                %(op_wb)s;
1002292SN/A            }
1012292SN/A        } else {
1022292SN/A            xc->setPredicate(false);
1032292SN/A        }
1042678Sktlim@umich.edu
1052678Sktlim@umich.edu        return fault;
1062292SN/A    }
1072292SN/A}};
1082292SN/A
1092292SN/Adef template SwapInitiateAcc {{
1102292SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
1112292SN/A                                      Trace::InstRecord *traceData) const
1122907Sktlim@umich.edu    {
1132292SN/A        Addr EA;
1142292SN/A        Fault fault = NoFault;
1152292SN/A
1162292SN/A        %(op_decl)s;
1172307SN/A        uint64_t memData = 0;
1182307SN/A        %(op_rd)s;
1192907Sktlim@umich.edu        %(ea_code)s;
1202907Sktlim@umich.edu
1212292SN/A        if (%(predicate_test)s)
1222292SN/A        {
1232329SN/A            %(preacc_code)s;
1242329SN/A
1252329SN/A            if (fault == NoFault) {
1262292SN/A                fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
1272292SN/A                        &memData);
1282292SN/A            }
1292292SN/A        } else {
1302292SN/A            xc->setPredicate(false);
1312292SN/A        }
1322292SN/A
1332292SN/A        return fault;
1342292SN/A    }
1352292SN/A}};
1362292SN/A
1373492Sktlim@umich.edudef template SwapCompleteAcc {{
1382329SN/A    Fault %(class_name)s::completeAcc(PacketPtr pkt,
1392292SN/A                                      %(CPU_exec_context)s *xc,
1402292SN/A                                      Trace::InstRecord *traceData) const
1412292SN/A    {
1422292SN/A        Fault fault = NoFault;
1432292SN/A
1442669Sktlim@umich.edu        %(op_decl)s;
1452733Sktlim@umich.edu        %(op_rd)s;
1462669Sktlim@umich.edu
1472669Sktlim@umich.edu        if (%(predicate_test)s)
1482678Sktlim@umich.edu        {
1492733Sktlim@umich.edu            // ARM instructions will not have a pkt if the predicate is false
1502679Sktlim@umich.edu            getMem(pkt, Mem, traceData);
1512679Sktlim@umich.edu            uint64_t memData = Mem;
1522679Sktlim@umich.edu
1532733Sktlim@umich.edu            %(postacc_code)s;
1542669Sktlim@umich.edu
1552669Sktlim@umich.edu            if (fault == NoFault) {
1562669Sktlim@umich.edu                %(op_wb)s;
1572292SN/A            }
1582292SN/A        }
1592292SN/A
1602292SN/A        return fault;
1612292SN/A    }
1622292SN/A}};
1632292SN/A
1642292SN/Adef template LoadExecute {{
1652292SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
1662292SN/A                                  Trace::InstRecord *traceData) const
1672292SN/A    {
1682292SN/A        Addr EA;
1692727Sktlim@umich.edu        Fault fault = NoFault;
1702727Sktlim@umich.edu
1712727Sktlim@umich.edu        %(op_decl)s;
1722727Sktlim@umich.edu        %(op_rd)s;
1732727Sktlim@umich.edu        %(ea_code)s;
1742727Sktlim@umich.edu
1752727Sktlim@umich.edu        if (%(predicate_test)s)
1762727Sktlim@umich.edu        {
1772727Sktlim@umich.edu            if (fault == NoFault) {
1782727Sktlim@umich.edu                fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
1792727Sktlim@umich.edu                %(memacc_code)s;
1802727Sktlim@umich.edu            }
1812727Sktlim@umich.edu
1822727Sktlim@umich.edu            if (fault == NoFault) {
1832727Sktlim@umich.edu                %(op_wb)s;
1842727Sktlim@umich.edu            }
1852727Sktlim@umich.edu        } else {
1862727Sktlim@umich.edu            xc->setPredicate(false);
1872361SN/A        }
1882361SN/A
1892361SN/A        return fault;
1902361SN/A    }
1912727Sktlim@umich.edu}};
1922727Sktlim@umich.edu
1932727Sktlim@umich.edudef template NeonLoadExecute {{
1942727Sktlim@umich.edu    template <class Element>
1952727Sktlim@umich.edu    Fault %(class_name)s<Element>::execute(
1962727Sktlim@umich.edu            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
1972727Sktlim@umich.edu    {
1982727Sktlim@umich.edu        Addr EA;
1992727Sktlim@umich.edu        Fault fault = NoFault;
2002727Sktlim@umich.edu
2012727Sktlim@umich.edu        %(op_decl)s;
2022727Sktlim@umich.edu        %(mem_decl)s;
2032727Sktlim@umich.edu        %(op_rd)s;
2042727Sktlim@umich.edu        %(ea_code)s;
2052727Sktlim@umich.edu
2062727Sktlim@umich.edu        MemUnion memUnion;
2072727Sktlim@umich.edu        uint8_t *dataPtr = memUnion.bytes;
2082727Sktlim@umich.edu
2092727Sktlim@umich.edu        if (%(predicate_test)s)
2102727Sktlim@umich.edu        {
2112727Sktlim@umich.edu            if (fault == NoFault) {
2122727Sktlim@umich.edu                fault = xc->readMem(EA, dataPtr, %(size)d, memAccessFlags);
2132727Sktlim@umich.edu                %(memacc_code)s;
2142292SN/A            }
2152292SN/A
2162292SN/A            if (fault == NoFault) {
2172292SN/A                %(op_wb)s;
2182292SN/A            }
2192292SN/A        } else {
2202292SN/A            xc->setPredicate(false);
2212292SN/A        }
2222292SN/A
2232292SN/A        return fault;
2242292SN/A    }
2252292SN/A}};
2262292SN/A
2272292SN/Adef template StoreExecute {{
2282307SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2292307SN/A                                  Trace::InstRecord *traceData) const
2302307SN/A    {
2312367SN/A        Addr EA;
2322367SN/A        Fault fault = NoFault;
2332307SN/A
2342367SN/A        %(op_decl)s;
2352307SN/A        %(op_rd)s;
2362329SN/A        %(ea_code)s;
2372307SN/A
2382307SN/A        if (%(predicate_test)s)
2392307SN/A        {
2402307SN/A            if (fault == NoFault) {
2412307SN/A                %(memacc_code)s;
2422307SN/A            }
2432307SN/A
2442307SN/A            if (fault == NoFault) {
2452307SN/A                fault = writeMemAtomic(xc, traceData, Mem, EA,
2462307SN/A                        memAccessFlags, NULL);
2472307SN/A            }
2482307SN/A
2492307SN/A            if (fault == NoFault) {
2502307SN/A                %(op_wb)s;
2512307SN/A            }
2522329SN/A        } else {
2532307SN/A            xc->setPredicate(false);
2542307SN/A        }
2552307SN/A
2562307SN/A        return fault;
2572307SN/A    }
2582307SN/A}};
2592307SN/A
2602307SN/Adef template NeonStoreExecute {{
2612307SN/A    template <class Element>
2622307SN/A    Fault %(class_name)s<Element>::execute(
2632292SN/A            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
2642292SN/A    {
2652329SN/A        Addr EA;
2662329SN/A        Fault fault = NoFault;
2672292SN/A
2682329SN/A        %(op_decl)s;
2692329SN/A        %(mem_decl)s;
2702292SN/A        %(op_rd)s;
2712292SN/A        %(ea_code)s;
2722292SN/A
2732292SN/A        MemUnion memUnion;
2742292SN/A        uint8_t *dataPtr = memUnion.bytes;
2752329SN/A
2762292SN/A        if (%(predicate_test)s)
2772292SN/A        {
2782292SN/A            if (fault == NoFault) {
2792292SN/A                %(memacc_code)s;
2802292SN/A            }
2812292SN/A
2822292SN/A            if (fault == NoFault) {
2832292SN/A                fault = xc->writeMem(dataPtr, %(size)d, EA,
2842329SN/A                                     memAccessFlags, NULL);
2852329SN/A            }
2862329SN/A
2872292SN/A            if (fault == NoFault) {
2882292SN/A                %(op_wb)s;
2892292SN/A            }
2902292SN/A        } else {
2912292SN/A            xc->setPredicate(false);
2922329SN/A        }
2932292SN/A
2942292SN/A        return fault;
2952292SN/A    }
2962292SN/A}};
2972292SN/A
2982292SN/Adef template StoreExExecute {{
2992292SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
3002292SN/A                                  Trace::InstRecord *traceData) const
3012292SN/A    {
3022292SN/A        Addr EA;
3032292SN/A        Fault fault = NoFault;
3042292SN/A
3052292SN/A        %(op_decl)s;
3062292SN/A        %(op_rd)s;
3072292SN/A        %(ea_code)s;
3082292SN/A
3092292SN/A        if (%(predicate_test)s)
3102292SN/A        {
3112292SN/A            if (fault == NoFault) {
3122292SN/A                %(memacc_code)s;
3132292SN/A            }
3142292SN/A
3152292SN/A            uint64_t writeResult;
3162292SN/A
3172329SN/A            if (fault == NoFault) {
3182329SN/A                fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
3192292SN/A                        &writeResult);
3202292SN/A            }
3212292SN/A
3222292SN/A            if (fault == NoFault) {
3232292SN/A                %(postacc_code)s;
3242292SN/A            }
3252292SN/A
3262292SN/A            if (fault == NoFault) {
3272292SN/A                %(op_wb)s;
3282292SN/A            }
3292292SN/A        } else {
3302292SN/A            xc->setPredicate(false);
3312292SN/A        }
3322292SN/A
3332292SN/A        return fault;
3342292SN/A    }
3352292SN/A}};
3362292SN/A
3372292SN/Adef template StoreExInitiateAcc {{
3382292SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
3392292SN/A                                      Trace::InstRecord *traceData) const
3402292SN/A    {
3412292SN/A        Addr EA;
3422292SN/A        Fault fault = NoFault;
3432292SN/A
3442292SN/A        %(op_decl)s;
3452292SN/A        %(op_rd)s;
3462292SN/A        %(ea_code)s;
3472292SN/A
3482292SN/A        if (%(predicate_test)s)
3492292SN/A        {
3502292SN/A            if (fault == NoFault) {
3512292SN/A                %(memacc_code)s;
3522292SN/A            }
3532292SN/A
3542292SN/A            if (fault == NoFault) {
3552292SN/A                fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
3562292SN/A                        NULL);
3572292SN/A            }
3582292SN/A        } else {
3592292SN/A            xc->setPredicate(false);
3602292SN/A        }
3612292SN/A
3622292SN/A        return fault;
3632292SN/A    }
3642292SN/A}};
3652292SN/A
3662292SN/Adef template StoreInitiateAcc {{
3672292SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
3682292SN/A                                      Trace::InstRecord *traceData) const
3692292SN/A    {
3702292SN/A        Addr EA;
3712292SN/A        Fault fault = NoFault;
3722292SN/A
3732292SN/A        %(op_decl)s;
3742292SN/A        %(op_rd)s;
3752292SN/A        %(ea_code)s;
3762292SN/A
3772292SN/A        if (%(predicate_test)s)
3782292SN/A        {
3792292SN/A            if (fault == NoFault) {
3802292SN/A                %(memacc_code)s;
3812292SN/A            }
3822292SN/A
3832292SN/A            if (fault == NoFault) {
3842292SN/A                fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
3852292SN/A                        NULL);
3862292SN/A            }
3872292SN/A        } else {
3882292SN/A            xc->setPredicate(false);
3892292SN/A        }
3902292SN/A
3912292SN/A        return fault;
3922292SN/A    }
3932292SN/A}};
3942292SN/A
3952292SN/Adef template NeonStoreInitiateAcc {{
3962292SN/A    template <class Element>
3972292SN/A    Fault %(class_name)s<Element>::initiateAcc(
3982292SN/A            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
3992292SN/A    {
4002292SN/A        Addr EA;
4012292SN/A        Fault fault = NoFault;
4022292SN/A
4032292SN/A        %(op_decl)s;
4042292SN/A        %(mem_decl)s;
4052292SN/A        %(op_rd)s;
4062292SN/A        %(ea_code)s;
4072292SN/A
4084032Sktlim@umich.edu        if (%(predicate_test)s)
4092292SN/A        {
4102292SN/A            MemUnion memUnion;
4112292SN/A            if (fault == NoFault) {
4122292SN/A                %(memacc_code)s;
4132292SN/A            }
4142292SN/A
4154032Sktlim@umich.edu            if (fault == NoFault) {
4164032Sktlim@umich.edu                fault = xc->writeMem(memUnion.bytes, %(size)d, EA,
4172669Sktlim@umich.edu                                     memAccessFlags, NULL);
4182292SN/A            }
4192292SN/A        } else {
4202292SN/A            xc->setPredicate(false);
4212292SN/A        }
4222329SN/A
4232329SN/A        return fault;
4242367SN/A    }
4252367SN/A}};
4264032Sktlim@umich.edu
4273731Sktlim@umich.edudef template LoadInitiateAcc {{
4282367SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
4292367SN/A                                      Trace::InstRecord *traceData) const
4302292SN/A    {
4312292SN/A        Addr EA;
4324032Sktlim@umich.edu        Fault fault = NoFault;
4334032Sktlim@umich.edu
4344032Sktlim@umich.edu        %(op_src_decl)s;
4354032Sktlim@umich.edu        %(op_rd)s;
4364032Sktlim@umich.edu        %(ea_code)s;
4374032Sktlim@umich.edu
4384032Sktlim@umich.edu        if (%(predicate_test)s)
4394032Sktlim@umich.edu        {
4404032Sktlim@umich.edu            if (fault == NoFault) {
4414032Sktlim@umich.edu                fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
4424032Sktlim@umich.edu            }
4434032Sktlim@umich.edu        } else {
4444032Sktlim@umich.edu            xc->setPredicate(false);
4454032Sktlim@umich.edu        }
4464032Sktlim@umich.edu
4474032Sktlim@umich.edu        return fault;
4484032Sktlim@umich.edu    }
4494032Sktlim@umich.edu}};
4504032Sktlim@umich.edu
4514032Sktlim@umich.edudef template NeonLoadInitiateAcc {{
4524032Sktlim@umich.edu    template <class Element>
4534032Sktlim@umich.edu    Fault %(class_name)s<Element>::initiateAcc(
4544032Sktlim@umich.edu            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
4554032Sktlim@umich.edu    {
4564032Sktlim@umich.edu        Addr EA;
4574032Sktlim@umich.edu        Fault fault = NoFault;
4584032Sktlim@umich.edu
4594032Sktlim@umich.edu        %(op_decl)s;
4604032Sktlim@umich.edu        %(mem_decl)s;
4614032Sktlim@umich.edu        %(op_rd)s;
4624032Sktlim@umich.edu        %(ea_code)s;
4634032Sktlim@umich.edu
4642292SN/A        MemUnion memUnion;
4652292SN/A        uint8_t *dataPtr = memUnion.bytes;
4662292SN/A
4672292SN/A        if (%(predicate_test)s)
4682292SN/A        {
4692292SN/A            if (fault == NoFault) {
4702292SN/A                fault = xc->readMem(EA, dataPtr, %(size)d, memAccessFlags);
4712292SN/A            }
4722292SN/A        } else {
4732292SN/A            xc->setPredicate(false);
4742292SN/A        }
4752292SN/A
4762292SN/A        return fault;
4772292SN/A    }
4782292SN/A}};
4792292SN/A
4802292SN/Adef template LoadCompleteAcc {{
4812292SN/A    Fault %(class_name)s::completeAcc(PacketPtr pkt,
4824032Sktlim@umich.edu                                      %(CPU_exec_context)s *xc,
4834032Sktlim@umich.edu                                      Trace::InstRecord *traceData) const
4842292SN/A    {
4852292SN/A        Fault fault = NoFault;
4862292SN/A
4872292SN/A        %(op_decl)s;
4882292SN/A        %(op_rd)s;
4892292SN/A
4902329SN/A        if (%(predicate_test)s)
4912292SN/A        {
4922292SN/A            // ARM instructions will not have a pkt if the predicate is false
4932292SN/A            getMem(pkt, Mem, traceData);
4942292SN/A
4952292SN/A            if (fault == NoFault) {
4962292SN/A                %(memacc_code)s;
4972292SN/A            }
4982292SN/A
4992336SN/A            if (fault == NoFault) {
5002336SN/A                %(op_wb)s;
5012336SN/A            }
5022329SN/A        }
5032292SN/A
5042329SN/A        return fault;
5052292SN/A    }
5062292SN/A}};
5074032Sktlim@umich.edu
5084032Sktlim@umich.edudef template NeonLoadCompleteAcc {{
5094032Sktlim@umich.edu    template <class Element>
5104032Sktlim@umich.edu    Fault %(class_name)s<Element>::completeAcc(
5114032Sktlim@umich.edu            PacketPtr pkt, %(CPU_exec_context)s *xc,
5122292SN/A            Trace::InstRecord *traceData) const
5134032Sktlim@umich.edu    {
5144032Sktlim@umich.edu        Fault fault = NoFault;
5154032Sktlim@umich.edu
5162329SN/A        %(mem_decl)s;
5174032Sktlim@umich.edu        %(op_decl)s;
5184032Sktlim@umich.edu        %(op_rd)s;
5194032Sktlim@umich.edu
5204032Sktlim@umich.edu        if (%(predicate_test)s)
5214032Sktlim@umich.edu        {
5224032Sktlim@umich.edu            // ARM instructions will not have a pkt if the predicate is false
5234032Sktlim@umich.edu            MemUnion &memUnion = *(MemUnion *)pkt->getPtr<uint8_t>();
5244032Sktlim@umich.edu
5254032Sktlim@umich.edu            if (fault == NoFault) {
5264032Sktlim@umich.edu                %(memacc_code)s;
5274032Sktlim@umich.edu            }
5284032Sktlim@umich.edu
5292292SN/A            if (fault == NoFault) {
5302292SN/A                %(op_wb)s;
5314032Sktlim@umich.edu            }
5324032Sktlim@umich.edu        }
5334032Sktlim@umich.edu
5342292SN/A        return fault;
5352292SN/A    }
5364032Sktlim@umich.edu}};
5372292SN/A
5382292SN/Adef template StoreCompleteAcc {{
5392292SN/A    Fault %(class_name)s::completeAcc(PacketPtr pkt,
5402292SN/A                                      %(CPU_exec_context)s *xc,
5412292SN/A                                      Trace::InstRecord *traceData) const
5422292SN/A    {
5432292SN/A        return NoFault;
5442292SN/A    }
5452292SN/A}};
5462292SN/A
5472292SN/Adef template NeonStoreCompleteAcc {{
5482292SN/A    template <class Element>
5492292SN/A    Fault %(class_name)s<Element>::completeAcc(
5502292SN/A            PacketPtr pkt, %(CPU_exec_context)s *xc,
5512292SN/A            Trace::InstRecord *traceData) const
5522292SN/A    {
5532292SN/A        return NoFault;
5542292SN/A    }
5552292SN/A}};
5562292SN/A
5572292SN/Adef template StoreExCompleteAcc {{
5582292SN/A    Fault %(class_name)s::completeAcc(PacketPtr pkt,
5592292SN/A                                      %(CPU_exec_context)s *xc,
5602292SN/A                                      Trace::InstRecord *traceData) const
5612292SN/A    {
5622292SN/A        Fault fault = NoFault;
5632292SN/A
5642292SN/A        %(op_decl)s;
5652292SN/A        %(op_rd)s;
5662292SN/A
5672292SN/A        if (%(predicate_test)s)
5682292SN/A        {
5692292SN/A            uint64_t writeResult = pkt->req->getExtraData();
5702292SN/A            %(postacc_code)s;
5712292SN/A
5722292SN/A            if (fault == NoFault) {
5732292SN/A                %(op_wb)s;
5742292SN/A            }
5752292SN/A        }
5762292SN/A
5772292SN/A        return fault;
5782292SN/A    }
5792329SN/A}};
5802329SN/A
5812292SN/Adef template RfeDeclare {{
5822292SN/A    /**
5832292SN/A     * Static instruction class for "%(mnemonic)s".
5842292SN/A     */
5852292SN/A    class %(class_name)s : public %(base_class)s
5862292SN/A    {
5872292SN/A      public:
5882292SN/A
5892292SN/A        /// Constructor.
5902292SN/A        %(class_name)s(ExtMachInst machInst,
5912292SN/A                uint32_t _base, int _mode, bool _wb);
5922292SN/A
5932292SN/A        %(BasicExecDeclare)s
5942292SN/A
5952292SN/A        %(InitiateAccDeclare)s
5962292SN/A
5972292SN/A        %(CompleteAccDeclare)s
5982292SN/A    };
5992292SN/A}};
6002292SN/A
6012292SN/Adef template SrsDeclare {{
6022292SN/A    /**
6032292SN/A     * Static instruction class for "%(mnemonic)s".
6042292SN/A     */
6052292SN/A    class %(class_name)s : public %(base_class)s
6062292SN/A    {
6072292SN/A      public:
6082292SN/A
6092907Sktlim@umich.edu        /// Constructor.
6102678Sktlim@umich.edu        %(class_name)s(ExtMachInst machInst,
6112678Sktlim@umich.edu                uint32_t _regMode, int _mode, bool _wb);
6122678Sktlim@umich.edu
6132678Sktlim@umich.edu        %(BasicExecDeclare)s
6142678Sktlim@umich.edu
6152329SN/A        %(InitiateAccDeclare)s
6162329SN/A
6172292SN/A        %(CompleteAccDeclare)s
6182292SN/A    };
6192292SN/A}};
6202292SN/A
6212292SN/Adef template SwapDeclare {{
6222292SN/A    /**
6232292SN/A     * Static instruction class for "%(mnemonic)s".
6242678Sktlim@umich.edu     */
6252292SN/A    class %(class_name)s : public %(base_class)s
6262292SN/A    {
6272292SN/A      public:
6282292SN/A
6292292SN/A        /// Constructor.
6302292SN/A        %(class_name)s(ExtMachInst machInst,
6312292SN/A                uint32_t _dest, uint32_t _op1, uint32_t _base);
6322292SN/A
6332292SN/A        %(BasicExecDeclare)s
6342292SN/A
6352292SN/A        %(InitiateAccDeclare)s
6362669Sktlim@umich.edu
6372669Sktlim@umich.edu        %(CompleteAccDeclare)s
6382669Sktlim@umich.edu    };
6392292SN/A}};
6402292SN/A
6412669Sktlim@umich.edudef template LoadStoreDImmDeclare {{
6422669Sktlim@umich.edu    /**
6433772Sgblack@eecs.umich.edu     * Static instruction class for "%(mnemonic)s".
6443772Sgblack@eecs.umich.edu     */
6453772Sgblack@eecs.umich.edu    class %(class_name)s : public %(base_class)s
6463772Sgblack@eecs.umich.edu    {
6473797Sgblack@eecs.umich.edu      public:
6483797Sgblack@eecs.umich.edu
6493797Sgblack@eecs.umich.edu        /// Constructor.
6503797Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst machInst,
6513797Sgblack@eecs.umich.edu                uint32_t _dest, uint32_t _dest2,
6523797Sgblack@eecs.umich.edu                uint32_t _base, bool _add, int32_t _imm);
6533797Sgblack@eecs.umich.edu
6543797Sgblack@eecs.umich.edu        %(BasicExecDeclare)s
6553797Sgblack@eecs.umich.edu
6563797Sgblack@eecs.umich.edu        %(InitiateAccDeclare)s
6573797Sgblack@eecs.umich.edu
6582669Sktlim@umich.edu        %(CompleteAccDeclare)s
6592669Sktlim@umich.edu    };
6602669Sktlim@umich.edu}};
6612292SN/A
6622678Sktlim@umich.edudef template StoreExDImmDeclare {{
6632678Sktlim@umich.edu    /**
6642678Sktlim@umich.edu     * Static instruction class for "%(mnemonic)s".
6652678Sktlim@umich.edu     */
6662678Sktlim@umich.edu    class %(class_name)s : public %(base_class)s
6672678Sktlim@umich.edu    {
6682292SN/A      public:
6692292SN/A
6703221Sktlim@umich.edu        /// Constructor.
6713797Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst machInst,
6723221Sktlim@umich.edu                uint32_t _result, uint32_t _dest, uint32_t _dest2,
6732292SN/A                uint32_t _base, bool _add, int32_t _imm);
6742693Sktlim@umich.edu
6753172Sstever@eecs.umich.edu        %(BasicExecDeclare)s
6763326Sktlim@umich.edu
6773326Sktlim@umich.edu        %(InitiateAccDeclare)s
6783326Sktlim@umich.edu
6793326Sktlim@umich.edu        %(CompleteAccDeclare)s
6803326Sktlim@umich.edu    };
6813326Sktlim@umich.edu}};
6823326Sktlim@umich.edu
6833326Sktlim@umich.edudef template LoadStoreImmDeclare {{
6843326Sktlim@umich.edu    /**
6853326Sktlim@umich.edu     * Static instruction class for "%(mnemonic)s".
6863326Sktlim@umich.edu     */
6873326Sktlim@umich.edu    class %(class_name)s : public %(base_class)s
6883326Sktlim@umich.edu    {
6893326Sktlim@umich.edu      public:
6903326Sktlim@umich.edu
6913326Sktlim@umich.edu        /// Constructor.
6923326Sktlim@umich.edu        %(class_name)s(ExtMachInst machInst,
6933326Sktlim@umich.edu                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
6942693Sktlim@umich.edu
6952693Sktlim@umich.edu        %(BasicExecDeclare)s
6962693Sktlim@umich.edu
6972693Sktlim@umich.edu        %(InitiateAccDeclare)s
6982693Sktlim@umich.edu
6992693Sktlim@umich.edu        %(CompleteAccDeclare)s
7002669Sktlim@umich.edu
7013221Sktlim@umich.edu        virtual void
7023221Sktlim@umich.edu        annotateFault(ArmFault *fault) {
7033221Sktlim@umich.edu            %(fa_code)s
7042669Sktlim@umich.edu        }
7054032Sktlim@umich.edu    };
7063221Sktlim@umich.edu}};
7073221Sktlim@umich.edu
7082678Sktlim@umich.edudef template StoreExImmDeclare {{
7092727Sktlim@umich.edu    /**
7102698Sktlim@umich.edu     * Static instruction class for "%(mnemonic)s".
7112698Sktlim@umich.edu     */
7123014Srdreslin@umich.edu    class %(class_name)s : public %(base_class)s
7132669Sktlim@umich.edu    {
7142693Sktlim@umich.edu      public:
7152292SN/A
7162292SN/A        /// Constructor.
7172292SN/A        %(class_name)s(ExtMachInst machInst,
7182292SN/A                uint32_t _result, uint32_t _dest, uint32_t _base,
7192292SN/A                bool _add, int32_t _imm);
7202292SN/A
7212292SN/A        %(BasicExecDeclare)s
7222292SN/A
7232292SN/A        %(InitiateAccDeclare)s
7242292SN/A
7252292SN/A        %(CompleteAccDeclare)s
7262292SN/A    };
7272292SN/A}};
7282292SN/A
7292292SN/Adef template StoreDRegDeclare {{
7302292SN/A    /**
7312292SN/A     * Static instruction class for "%(mnemonic)s".
7322292SN/A     */
7332292SN/A    class %(class_name)s : public %(base_class)s
7342292SN/A    {
7352292SN/A      public:
7362292SN/A
7372292SN/A        /// Constructor.
7382292SN/A        %(class_name)s(ExtMachInst machInst,
7392292SN/A                uint32_t _dest, uint32_t _dest2,
7402292SN/A                uint32_t _base, bool _add,
7412292SN/A                int32_t _shiftAmt, uint32_t _shiftType,
7422292SN/A                uint32_t _index);
7432329SN/A
7442292SN/A        %(BasicExecDeclare)s
7452292SN/A
7462292SN/A        %(InitiateAccDeclare)s
7472292SN/A
7482292SN/A        %(CompleteAccDeclare)s
7492292SN/A    };
7502292SN/A}};
7512292SN/A
7522292SN/Adef template StoreRegDeclare {{
7532292SN/A    /**
7542292SN/A     * Static instruction class for "%(mnemonic)s".
7552292SN/A     */
7562292SN/A    class %(class_name)s : public %(base_class)s
7572292SN/A    {
7582292SN/A      public:
7592292SN/A
7602329SN/A        /// Constructor.
7612731Sktlim@umich.edu        %(class_name)s(ExtMachInst machInst,
7622292SN/A                uint32_t _dest, uint32_t _base, bool _add,
7632292SN/A                int32_t _shiftAmt, uint32_t _shiftType,
7642292SN/A                uint32_t _index);
7652292SN/A
7662292SN/A        %(BasicExecDeclare)s
7672292SN/A
7682292SN/A        %(InitiateAccDeclare)s
7692727Sktlim@umich.edu
7702292SN/A        %(CompleteAccDeclare)s
7712292SN/A
7722292SN/A        virtual void
7732292SN/A        annotateFault(ArmFault *fault) {
7742292SN/A            %(fa_code)s
7752292SN/A        }
7762292SN/A    };
7772292SN/A}};
7782292SN/A
7792292SN/Adef template LoadDRegDeclare {{
7804032Sktlim@umich.edu    /**
7814032Sktlim@umich.edu     * Static instruction class for "%(mnemonic)s".
7824032Sktlim@umich.edu     */
7834032Sktlim@umich.edu    class %(class_name)s : public %(base_class)s
7842292SN/A    {
7852292SN/A      public:
7862292SN/A
7872292SN/A        /// Constructor.
7882292SN/A        %(class_name)s(ExtMachInst machInst,
7892329SN/A                uint32_t _dest, uint32_t _dest2,
7902292SN/A                uint32_t _base, bool _add,
7912292SN/A                int32_t _shiftAmt, uint32_t _shiftType,
7922292SN/A                uint32_t _index);
7932292SN/A
7942292SN/A        %(BasicExecDeclare)s
7952292SN/A
7962292SN/A        %(InitiateAccDeclare)s
7972292SN/A
7982292SN/A        %(CompleteAccDeclare)s
7992329SN/A    };
8002329SN/A}};
8012292SN/A
8022292SN/Adef template LoadRegDeclare {{
8032292SN/A    /**
8042292SN/A     * Static instruction class for "%(mnemonic)s".
8052292SN/A     */
8062292SN/A    class %(class_name)s : public %(base_class)s
8072292SN/A    {
8082329SN/A      public:
8092731Sktlim@umich.edu
8102292SN/A        /// Constructor.
8112292SN/A        %(class_name)s(ExtMachInst machInst,
8122292SN/A                uint32_t _dest, uint32_t _base, bool _add,
8134032Sktlim@umich.edu                int32_t _shiftAmt, uint32_t _shiftType,
8144032Sktlim@umich.edu                uint32_t _index);
8154032Sktlim@umich.edu
8164032Sktlim@umich.edu        %(BasicExecDeclare)s
8174032Sktlim@umich.edu
8182292SN/A        %(InitiateAccDeclare)s
8192292SN/A
8202292SN/A        %(CompleteAccDeclare)s
8212292SN/A
8222292SN/A        virtual void
8232292SN/A        annotateFault(ArmFault *fault) {
8242292SN/A            %(fa_code)s
8252727Sktlim@umich.edu        }
8262292SN/A    };
8272292SN/A}};
8282292SN/A
8292292SN/Adef template LoadImmDeclare {{
8302292SN/A    /**
8313349Sbinkertn@umich.edu     * Static instruction class for "%(mnemonic)s".
8322693Sktlim@umich.edu     */
8332693Sktlim@umich.edu    class %(class_name)s : public %(base_class)s
8342693Sktlim@umich.edu    {
8352693Sktlim@umich.edu      public:
8362693Sktlim@umich.edu
8372693Sktlim@umich.edu        /// Constructor.
8382693Sktlim@umich.edu        %(class_name)s(ExtMachInst machInst,
8392693Sktlim@umich.edu                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
8402693Sktlim@umich.edu
8412693Sktlim@umich.edu        %(BasicExecDeclare)s
8422693Sktlim@umich.edu
8432693Sktlim@umich.edu        %(InitiateAccDeclare)s
8442693Sktlim@umich.edu
8452693Sktlim@umich.edu        %(CompleteAccDeclare)s
8462693Sktlim@umich.edu
8472693Sktlim@umich.edu        virtual void
8482733Sktlim@umich.edu        annotateFault(ArmFault *fault) {
8492693Sktlim@umich.edu            %(fa_code)s
8502732Sktlim@umich.edu        }
8512693Sktlim@umich.edu    };
8522733Sktlim@umich.edu}};
8532693Sktlim@umich.edu
8542693Sktlim@umich.edudef template InitiateAccDeclare {{
8552693Sktlim@umich.edu    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
8562693Sktlim@umich.edu}};
8572693Sktlim@umich.edu
8582693Sktlim@umich.edudef template CompleteAccDeclare {{
8592693Sktlim@umich.edu    Fault completeAcc(PacketPtr,  %(CPU_exec_context)s *, Trace::InstRecord *) const;
8602693Sktlim@umich.edu}};
8612693Sktlim@umich.edu
8622693Sktlim@umich.edudef template RfeConstructor {{
8632693Sktlim@umich.edu    %(class_name)s::%(class_name)s(ExtMachInst machInst,
8642693Sktlim@umich.edu                                          uint32_t _base, int _mode, bool _wb)
8652693Sktlim@umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
8662693Sktlim@umich.edu                         (IntRegIndex)_base, (AddrMode)_mode, _wb)
8672693Sktlim@umich.edu    {
8682693Sktlim@umich.edu        %(constructor)s;
8692693Sktlim@umich.edu        if (!(condCode == COND_AL || condCode == COND_UC)) {
8702693Sktlim@umich.edu            for (int x = 0; x < _numDestRegs; x++) {
8712693Sktlim@umich.edu                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
8722693Sktlim@umich.edu            }
8732693Sktlim@umich.edu        }
8742693Sktlim@umich.edu#if %(use_uops)d
8752693Sktlim@umich.edu        uops = new StaticInstPtr[1 + %(use_wb)d + %(use_pc)d];
8762693Sktlim@umich.edu        int uopIdx = 0;
8772693Sktlim@umich.edu        uops[uopIdx] = new %(acc_name)s(machInst, _base, _mode, _wb);
8782693Sktlim@umich.edu        uops[uopIdx]->setDelayedCommit();
8792693Sktlim@umich.edu#if %(use_wb)d
8802678Sktlim@umich.edu        uops[++uopIdx] = new %(wb_decl)s;
8812678Sktlim@umich.edu        uops[uopIdx]->setDelayedCommit();
8822678Sktlim@umich.edu#endif
8832678Sktlim@umich.edu#if %(use_pc)d
8842678Sktlim@umich.edu        uops[++uopIdx] = new %(pc_decl)s;
8852678Sktlim@umich.edu#endif
8862927Sktlim@umich.edu        uops[uopIdx]->setLastMicroop();
8872678Sktlim@umich.edu#endif
8882727Sktlim@umich.edu    }
8892678Sktlim@umich.edu}};
8902678Sktlim@umich.edu
8912678Sktlim@umich.edudef template SrsConstructor {{
8922678Sktlim@umich.edu    %(class_name)s::%(class_name)s(ExtMachInst machInst,
8932678Sktlim@umich.edu            uint32_t _regMode, int _mode, bool _wb)
8942678Sktlim@umich.edu         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
8952678Sktlim@umich.edu                 (OperatingMode)_regMode, (AddrMode)_mode, _wb)
8962678Sktlim@umich.edu    {
8972678Sktlim@umich.edu        %(constructor)s;
8982678Sktlim@umich.edu        if (!(condCode == COND_AL || condCode == COND_UC)) {
8992678Sktlim@umich.edu            for (int x = 0; x < _numDestRegs; x++) {
9002678Sktlim@umich.edu                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
9012678Sktlim@umich.edu            }
9022678Sktlim@umich.edu        }
9032678Sktlim@umich.edu#if %(use_uops)d
9042678Sktlim@umich.edu        assert(numMicroops >= 2);
9052678Sktlim@umich.edu        uops = new StaticInstPtr[numMicroops];
9062678Sktlim@umich.edu        uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb);
9072292SN/A        uops[0]->setDelayedCommit();
9082292SN/A        uops[1] = new %(wb_decl)s;
9092292SN/A        uops[1]->setLastMicroop();
9102292SN/A#endif
9112292SN/A    }
9122292SN/A}};
9132292SN/A
9142292SN/Adef template SwapConstructor {{
9153126Sktlim@umich.edu    %(class_name)s::%(class_name)s(ExtMachInst machInst,
9162292SN/A            uint32_t _dest, uint32_t _op1, uint32_t _base)
9172292SN/A         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
9182292SN/A                 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
9192292SN/A    {
9202292SN/A        %(constructor)s;
9212292SN/A        if (!(condCode == COND_AL || condCode == COND_UC)) {
9222292SN/A            for (int x = 0; x < _numDestRegs; x++) {
9232292SN/A                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
9242292SN/A            }
9252292SN/A        }
9262292SN/A    }
9272292SN/A}};
9282292SN/A
9292329SN/Adef template LoadStoreDImmConstructor {{
9302329SN/A    %(class_name)s::%(class_name)s(ExtMachInst machInst,
9312329SN/A            uint32_t _dest, uint32_t _dest2,
9322292SN/A            uint32_t _base, bool _add, int32_t _imm)
9332292SN/A         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
9342292SN/A                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
9352292SN/A                 (IntRegIndex)_base, _add, _imm)
9362292SN/A    {
9372292SN/A        %(constructor)s;
9382292SN/A        if (!(condCode == COND_AL || condCode == COND_UC)) {
9392292SN/A            for (int x = 0; x < _numDestRegs; x++) {
9402292SN/A                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
9412292SN/A            }
9422316SN/A        }
9432316SN/A#if %(use_uops)d
9442329SN/A        assert(numMicroops >= 2);
9452329SN/A        uops = new StaticInstPtr[numMicroops];
9462329SN/A        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm);
9472329SN/A        uops[0]->setDelayedCommit();
9482733Sktlim@umich.edu        uops[1] = new %(wb_decl)s;
9492316SN/A        uops[1]->setLastMicroop();
9502732Sktlim@umich.edu#endif
9512316SN/A    }
9522733Sktlim@umich.edu}};
9532292SN/A
9542292SN/Adef template StoreExDImmConstructor {{
9552292SN/A    %(class_name)s::%(class_name)s(ExtMachInst machInst,
9562693Sktlim@umich.edu            uint32_t _result, uint32_t _dest, uint32_t _dest2,
9572693Sktlim@umich.edu            uint32_t _base, bool _add, int32_t _imm)
9582693Sktlim@umich.edu         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
9592698Sktlim@umich.edu                 (IntRegIndex)_result,
9602698Sktlim@umich.edu                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
9612693Sktlim@umich.edu                 (IntRegIndex)_base, _add, _imm)
9622698Sktlim@umich.edu    {
9633221Sktlim@umich.edu        %(constructor)s;
9643221Sktlim@umich.edu        if (!(condCode == COND_AL || condCode == COND_UC)) {
9653221Sktlim@umich.edu            for (int x = 0; x < _numDestRegs; x++) {
9662698Sktlim@umich.edu                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
9672699Sktlim@umich.edu            }
9682693Sktlim@umich.edu        }
9693014Srdreslin@umich.edu#if %(use_uops)d
9702693Sktlim@umich.edu        assert(numMicroops >= 2);
9712693Sktlim@umich.edu        uops = new StaticInstPtr[numMicroops];
9722727Sktlim@umich.edu        uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2,
9732907Sktlim@umich.edu                                   _base, _add, _imm);
9742693Sktlim@umich.edu        uops[0]->setDelayedCommit();
9752693Sktlim@umich.edu        uops[1] = new %(wb_decl)s;
9762693Sktlim@umich.edu        uops[1]->setLastMicroop();
9772693Sktlim@umich.edu#endif
9782693Sktlim@umich.edu    }
9792693Sktlim@umich.edu}};
9802693Sktlim@umich.edu
9812693Sktlim@umich.edudef template LoadStoreImmConstructor {{
9822693Sktlim@umich.edu    %(class_name)s::%(class_name)s(ExtMachInst machInst,
9832693Sktlim@umich.edu            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
9842292SN/A         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
9852292SN/A                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
9862292SN/A    {
9872292SN/A        %(constructor)s;
9882292SN/A        if (!(condCode == COND_AL || condCode == COND_UC)) {
9892292SN/A            for (int x = 0; x < _numDestRegs; x++) {
9902292SN/A                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
9912292SN/A            }
9922292SN/A        }
9932292SN/A#if %(use_uops)d
9942292SN/A        assert(numMicroops >= 2);
9952292SN/A        uops = new StaticInstPtr[numMicroops];
9962292SN/A        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
9972292SN/A        uops[0]->setDelayedCommit();
9982292SN/A        uops[1] = new %(wb_decl)s;
9992292SN/A        uops[1]->setLastMicroop();
10002292SN/A#endif
10012292SN/A    }
10022292SN/A}};
10032292SN/A
10042292SN/Adef template StoreExImmConstructor {{
10052292SN/A    %(class_name)s::%(class_name)s(ExtMachInst machInst,
10062292SN/A            uint32_t _result, uint32_t _dest, uint32_t _base,
10072292SN/A            bool _add, int32_t _imm)
10082292SN/A         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
10092292SN/A                 (IntRegIndex)_result, (IntRegIndex)_dest,
10102292SN/A                 (IntRegIndex)_base, _add, _imm)
10112292SN/A    {
10122292SN/A        %(constructor)s;
10132292SN/A        if (!(condCode == COND_AL || condCode == COND_UC)) {
10142329SN/A            for (int x = 0; x < _numDestRegs; x++) {
10152329SN/A                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
10162329SN/A            }
10172329SN/A        }
10182329SN/A#if %(use_uops)d
10192329SN/A        assert(numMicroops >= 2);
10202329SN/A        uops = new StaticInstPtr[numMicroops];
10212329SN/A        uops[0] = new %(acc_name)s(machInst, _result, _dest,
10222329SN/A                                   _base, _add, _imm);
10232329SN/A        uops[0]->setDelayedCommit();
10242329SN/A        uops[1] = new %(wb_decl)s;
10252329SN/A        uops[1]->setLastMicroop();
10262329SN/A#endif
10272329SN/A    }
10282329SN/A}};
10292329SN/A
10302329SN/Adef template StoreDRegConstructor {{
10312329SN/A    %(class_name)s::%(class_name)s(ExtMachInst machInst,
10322329SN/A            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
10332329SN/A            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
10342329SN/A         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
10352329SN/A                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
10362329SN/A                 (IntRegIndex)_base, _add,
10372329SN/A                 _shiftAmt, (ArmShiftType)_shiftType,
10382329SN/A                 (IntRegIndex)_index)
10392329SN/A    {
10402329SN/A        %(constructor)s;
10412329SN/A        if (!(condCode == COND_AL || condCode == COND_UC)) {
10422329SN/A            for (int x = 0; x < _numDestRegs; x++) {
10432329SN/A                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1044            }
1045        }
1046#if %(use_uops)d
1047        assert(numMicroops >= 2);
1048        uops = new StaticInstPtr[numMicroops];
1049        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1050                                   _shiftAmt, _shiftType, _index);
1051        uops[0]->setDelayedCommit();
1052        uops[1] = new %(wb_decl)s;
1053        uops[1]->setLastMicroop();
1054#endif
1055    }
1056}};
1057
1058def template StoreRegConstructor {{
1059    %(class_name)s::%(class_name)s(ExtMachInst machInst,
1060            uint32_t _dest, uint32_t _base, bool _add,
1061            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1062         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1063                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1064                 _shiftAmt, (ArmShiftType)_shiftType,
1065                 (IntRegIndex)_index)
1066    {
1067        %(constructor)s;
1068        if (!(condCode == COND_AL || condCode == COND_UC)) {
1069            for (int x = 0; x < _numDestRegs; x++) {
1070                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1071            }
1072        }
1073#if %(use_uops)d
1074        assert(numMicroops >= 2);
1075        uops = new StaticInstPtr[numMicroops];
1076        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1077                                   _shiftAmt, _shiftType, _index);
1078        uops[0]->setDelayedCommit();
1079        uops[1] = new %(wb_decl)s;
1080        uops[1]->setLastMicroop();
1081#endif
1082    }
1083}};
1084
1085def template LoadDRegConstructor {{
1086    %(class_name)s::%(class_name)s(ExtMachInst machInst,
1087            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1088            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1089         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1090                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1091                 (IntRegIndex)_base, _add,
1092                 _shiftAmt, (ArmShiftType)_shiftType,
1093                 (IntRegIndex)_index)
1094    {
1095        %(constructor)s;
1096        if (!(condCode == COND_AL || condCode == COND_UC)) {
1097            for (int x = 0; x < _numDestRegs; x++) {
1098                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1099            }
1100        }
1101#if %(use_uops)d
1102        assert(numMicroops >= 2);
1103        uops = new StaticInstPtr[numMicroops];
1104        if ((_dest == _index) || (_dest2 == _index)) {
1105            IntRegIndex wbIndexReg = INTREG_UREG0;
1106            uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1107            uops[0]->setDelayedCommit();
1108            uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1109                                       _shiftAmt, _shiftType, _index);
1110            uops[1]->setDelayedCommit();
1111            uops[2] = new %(wb_decl)s;
1112            uops[2]->setLastMicroop();
1113        } else {
1114            IntRegIndex wbIndexReg = index;
1115            uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1116                                       _shiftAmt, _shiftType, _index);
1117            uops[0]->setDelayedCommit();
1118            uops[1] = new %(wb_decl)s;
1119            uops[1]->setLastMicroop();
1120        }
1121#endif
1122    }
1123}};
1124
1125def template LoadRegConstructor {{
1126    %(class_name)s::%(class_name)s(ExtMachInst machInst,
1127            uint32_t _dest, uint32_t _base, bool _add,
1128            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1129         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1130                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1131                 _shiftAmt, (ArmShiftType)_shiftType,
1132                 (IntRegIndex)_index)
1133    {
1134        %(constructor)s;
1135        bool conditional M5_VAR_USED = false;
1136        if (!(condCode == COND_AL || condCode == COND_UC)) {
1137            conditional = true;
1138            for (int x = 0; x < _numDestRegs; x++) {
1139                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1140            }
1141        }
1142#if %(use_uops)d
1143        assert(numMicroops >= 2);
1144        uops = new StaticInstPtr[numMicroops];
1145        if (_dest == INTREG_PC && !isFloating()) {
1146            IntRegIndex wbIndexReg = index;
1147            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1148                                       _shiftAmt, _shiftType, _index);
1149            uops[0]->setDelayedCommit();
1150            uops[1] = new %(wb_decl)s;
1151            uops[1]->setDelayedCommit();
1152            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1153            uops[2]->setFlag(StaticInst::IsControl);
1154            uops[2]->setFlag(StaticInst::IsIndirectControl);
1155            if (conditional)
1156                uops[2]->setFlag(StaticInst::IsCondControl);
1157            else
1158                uops[2]->setFlag(StaticInst::IsUncondControl);
1159            uops[2]->setLastMicroop();
1160        } else if(_dest == _index) {
1161            IntRegIndex wbIndexReg = INTREG_UREG0;
1162            uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1163            uops[0]->setDelayedCommit();
1164            uops[1] = new %(acc_name)s(machInst, _dest, _base, _add,
1165                                      _shiftAmt, _shiftType, _index);
1166            uops[1]->setDelayedCommit();
1167            uops[2] = new %(wb_decl)s;
1168            uops[2]->setLastMicroop();
1169        } else {
1170            IntRegIndex wbIndexReg = index;
1171            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1172                                      _shiftAmt, _shiftType, _index);
1173            uops[0]->setDelayedCommit();
1174            uops[1] = new %(wb_decl)s;
1175            uops[1]->setLastMicroop();
1176
1177        }
1178#else
1179        if (_dest == INTREG_PC && !isFloating()) {
1180            flags[IsControl] = true;
1181            flags[IsIndirectControl] = true;
1182            if (conditional)
1183                flags[IsCondControl] = true;
1184            else
1185                flags[IsUncondControl] = true;
1186        }
1187#endif
1188    }
1189}};
1190
1191def template LoadImmConstructor {{
1192    %(class_name)s::%(class_name)s(ExtMachInst machInst,
1193            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
1194         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1195                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
1196    {
1197        %(constructor)s;
1198        bool conditional M5_VAR_USED = false;
1199        if (!(condCode == COND_AL || condCode == COND_UC)) {
1200            conditional = true;
1201            for (int x = 0; x < _numDestRegs; x++) {
1202                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1203            }
1204        }
1205#if %(use_uops)d
1206        assert(numMicroops >= 2);
1207        uops = new StaticInstPtr[numMicroops];
1208        if (_dest == INTREG_PC && !isFloating()) {
1209            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1210                                   _imm);
1211            uops[0]->setDelayedCommit();
1212            uops[1] = new %(wb_decl)s;
1213            uops[1]->setDelayedCommit();
1214            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1215            uops[2]->setFlag(StaticInst::IsControl);
1216            uops[2]->setFlag(StaticInst::IsIndirectControl);
1217            if (conditional)
1218                uops[2]->setFlag(StaticInst::IsCondControl);
1219            else
1220                uops[2]->setFlag(StaticInst::IsUncondControl);
1221            if (_base == INTREG_SP && _add && _imm == 4 && %(is_ras_pop)s)
1222                uops[2]->setFlag(StaticInst::IsReturn);
1223            uops[2]->setLastMicroop();
1224        } else {
1225            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
1226            uops[0]->setDelayedCommit();
1227            uops[1] = new %(wb_decl)s;
1228            uops[1]->setLastMicroop();
1229        }
1230#else
1231        if (_dest == INTREG_PC && !isFloating()) {
1232            flags[IsControl] = true;
1233            flags[IsIndirectControl] = true;
1234            if (conditional)
1235                flags[IsCondControl] = true;
1236            else
1237                flags[IsUncondControl] = true;
1238        }
1239#endif
1240    }
1241}};
1242
1243