mem.isa revision 8607
12292SN/A// -*- mode:c++ -*-
22727Sktlim@umich.edu
32292SN/A// Copyright (c) 2010 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//
292292SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
302292SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
312329SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
322980Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
332329SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
342329SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
352292SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
366221Snate@binkert.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
372292SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
386221Snate@binkert.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
395529Snate@binkert.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
404192Sktlim@umich.edu//
414192Sktlim@umich.edu// Authors: Stephen Hines
424192Sktlim@umich.edu
434192Sktlim@umich.edu
444192Sktlim@umich.edudef template PanicExecute {{
454192Sktlim@umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
464192Sktlim@umich.edu                                  Trace::InstRecord *traceData) const
474192Sktlim@umich.edu    {
484192Sktlim@umich.edu        panic("Execute function executed when it shouldn't be!\n");
494192Sktlim@umich.edu        return NoFault;
504192Sktlim@umich.edu    }
514192Sktlim@umich.edu}};
524192Sktlim@umich.edu
532292SN/Adef template PanicInitiateAcc {{
542907Sktlim@umich.edu    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
552907Sktlim@umich.edu                                      Trace::InstRecord *traceData) const
562907Sktlim@umich.edu    {
572907Sktlim@umich.edu        panic("InitiateAcc function executed when it shouldn't be!\n");
587823Ssteve.reinhardt@amd.com        return NoFault;
592907Sktlim@umich.edu    }
602907Sktlim@umich.edu}};
612907Sktlim@umich.edu
622907Sktlim@umich.edudef template PanicCompleteAcc {{
632907Sktlim@umich.edu    Fault %(class_name)s::completeAcc(PacketPtr pkt,
642907Sktlim@umich.edu                                      %(CPU_exec_context)s *xc,
653639Sktlim@umich.edu                                      Trace::InstRecord *traceData) const
662907Sktlim@umich.edu    {
672907Sktlim@umich.edu        panic("CompleteAcc function executed when it shouldn't be!\n");
682907Sktlim@umich.edu        return NoFault;
692907Sktlim@umich.edu    }
702907Sktlim@umich.edu}};
712907Sktlim@umich.edu
723647Srdreslin@umich.edu
733647Srdreslin@umich.edudef template SwapExecute {{
743647Srdreslin@umich.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
753647Srdreslin@umich.edu                                  Trace::InstRecord *traceData) const
763647Srdreslin@umich.edu    {
772907Sktlim@umich.edu        Addr EA;
783647Srdreslin@umich.edu        Fault fault = NoFault;
792907Sktlim@umich.edu
802907Sktlim@umich.edu        %(op_decl)s;
812907Sktlim@umich.edu        uint64_t memData = 0;
822907Sktlim@umich.edu        %(op_rd)s;
832907Sktlim@umich.edu        %(ea_code)s;
842907Sktlim@umich.edu
852907Sktlim@umich.edu        if (%(predicate_test)s)
864986Ssaidi@eecs.umich.edu        {
874986Ssaidi@eecs.umich.edu            %(preacc_code)s;
883310Srdreslin@umich.edu
895714Shsul@eecs.umich.edu            if (fault == NoFault) {
903310Srdreslin@umich.edu                fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
913310Srdreslin@umich.edu                        &memData);
924895Sstever@eecs.umich.edu            }
934895Sstever@eecs.umich.edu
944895Sstever@eecs.umich.edu            if (fault == NoFault) {
954895Sstever@eecs.umich.edu                %(postacc_code)s;
963310Srdreslin@umich.edu            }
972907Sktlim@umich.edu
982907Sktlim@umich.edu            if (fault == NoFault) {
992907Sktlim@umich.edu                %(op_wb)s;
1002907Sktlim@umich.edu            }
1012907Sktlim@umich.edu        } else {
1022907Sktlim@umich.edu            xc->setPredicate(false);
1032907Sktlim@umich.edu        }
1043014Srdreslin@umich.edu
1053014Srdreslin@umich.edu        return fault;
1063014Srdreslin@umich.edu    }
1073014Srdreslin@umich.edu}};
1083014Srdreslin@umich.edu
1094985Sktlim@umich.edudef template SwapInitiateAcc {{
1102907Sktlim@umich.edu    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
1112907Sktlim@umich.edu                                      Trace::InstRecord *traceData) const
1122907Sktlim@umich.edu    {
1134985Sktlim@umich.edu        Addr EA;
1142907Sktlim@umich.edu        Fault fault = NoFault;
1152907Sktlim@umich.edu
1162907Sktlim@umich.edu        %(op_decl)s;
1175529Snate@binkert.org        uint64_t memData = 0;
1185494Sstever@gmail.com        %(op_rd)s;
1194329Sktlim@umich.edu        %(ea_code)s;
1204329Sktlim@umich.edu
1215529Snate@binkert.org        if (%(predicate_test)s)
1222907Sktlim@umich.edu        {
1232292SN/A            %(preacc_code)s;
1243647Srdreslin@umich.edu
1253647Srdreslin@umich.edu            if (fault == NoFault) {
1262292SN/A                fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
1272292SN/A                        &memData);
1282292SN/A            }
1292980Sgblack@eecs.umich.edu        } else {
1302292SN/A            xc->setPredicate(false);
1312292SN/A        }
1322292SN/A
1332292SN/A        return fault;
1342292SN/A    }
1352292SN/A}};
1362292SN/A
1372292SN/Adef template SwapCompleteAcc {{
1382292SN/A    Fault %(class_name)s::completeAcc(PacketPtr pkt,
1392292SN/A                                      %(CPU_exec_context)s *xc,
1402292SN/A                                      Trace::InstRecord *traceData) const
1414329Sktlim@umich.edu    {
1422292SN/A        Fault fault = NoFault;
1432292SN/A
1442292SN/A        %(op_decl)s;
1452292SN/A        %(op_rd)s;
1462292SN/A
1472292SN/A        if (%(predicate_test)s)
1482292SN/A        {
1494329Sktlim@umich.edu            // ARM instructions will not have a pkt if the predicate is false
1502292SN/A            getMem(pkt, Mem, traceData);
1512292SN/A            uint64_t memData = Mem;
1522292SN/A
1532292SN/A            %(postacc_code)s;
1542292SN/A
1552292SN/A            if (fault == NoFault) {
1562292SN/A                %(op_wb)s;
1572292SN/A            }
1582292SN/A        }
1592292SN/A
1602292SN/A        return fault;
1612292SN/A    }
1622292SN/A}};
1632292SN/A
1644329Sktlim@umich.edudef 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;
1692292SN/A        Fault fault = NoFault;
1702292SN/A
1712292SN/A        %(op_decl)s;
1722292SN/A        %(op_rd)s;
1732292SN/A        %(ea_code)s;
1746221Snate@binkert.org
1754329Sktlim@umich.edu        if (%(predicate_test)s)
1764329Sktlim@umich.edu        {
1772907Sktlim@umich.edu            if (fault == NoFault) {
1782292SN/A                fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
1792292SN/A                %(memacc_code)s;
1802292SN/A            }
1812292SN/A
1822292SN/A            if (fault == NoFault) {
1832292SN/A                %(op_wb)s;
1842292SN/A            }
1852292SN/A        } else {
1862292SN/A            xc->setPredicate(false);
1872292SN/A        }
1882292SN/A
1892292SN/A        return fault;
1902292SN/A    }
1912727Sktlim@umich.edu}};
1922727Sktlim@umich.edu
1932727Sktlim@umich.edudef template NeonLoadExecute {{
1946221Snate@binkert.org    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
2016221Snate@binkert.org        %(op_decl)s;
2022292SN/A        %(mem_decl)s;
2032292SN/A        %(op_rd)s;
2042292SN/A        %(ea_code)s;
2052292SN/A
2062292SN/A        MemUnion memUnion;
2072292SN/A        uint8_t *dataPtr = memUnion.bytes;
2082307SN/A
2092307SN/A        if (%(predicate_test)s)
2102307SN/A        {
2116221Snate@binkert.org            if (fault == NoFault) {
2122307SN/A                fault = xc->readMem(EA, dataPtr, %(size)d, memAccessFlags);
2132307SN/A                %(memacc_code)s;
2142307SN/A            }
2152307SN/A
2162307SN/A            if (fault == NoFault) {
2172307SN/A                %(op_wb)s;
2182307SN/A            }
2192307SN/A        } else {
2206221Snate@binkert.org            xc->setPredicate(false);
2212307SN/A        }
2222307SN/A
2232307SN/A        return fault;
2242307SN/A    }
2252307SN/A}};
2262292SN/A
2276221Snate@binkert.orgdef template StoreExecute {{
2282292SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
2292292SN/A                                  Trace::InstRecord *traceData) const
2302292SN/A    {
2312292SN/A        Addr EA;
2322292SN/A        Fault fault = NoFault;
2332292SN/A
2342292SN/A        %(op_decl)s;
2352292SN/A        %(op_rd)s;
2362292SN/A        %(ea_code)s;
2372292SN/A
2382292SN/A        if (%(predicate_test)s)
2392292SN/A        {
2402292SN/A            if (fault == NoFault) {
2413867Sbinkertn@umich.edu                %(memacc_code)s;
2422292SN/A            }
2432292SN/A
2442292SN/A            if (fault == NoFault) {
2452292SN/A                fault = writeMemAtomic(xc, traceData, Mem, EA,
2462292SN/A                        memAccessFlags, NULL);
2472292SN/A            }
2482292SN/A
2492292SN/A            if (fault == NoFault) {
2502292SN/A                %(op_wb)s;
2512292SN/A            }
2522292SN/A        } else {
2536221Snate@binkert.org            xc->setPredicate(false);
2546221Snate@binkert.org        }
2553867Sbinkertn@umich.edu
2563867Sbinkertn@umich.edu        return fault;
2576221Snate@binkert.org    }
2583867Sbinkertn@umich.edu}};
2593867Sbinkertn@umich.edu
2602292SN/Adef template NeonStoreExecute {{
2612292SN/A    template <class Element>
2622292SN/A    Fault %(class_name)s<Element>::execute(
2632292SN/A            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
2642292SN/A    {
2652292SN/A        Addr EA;
2666221Snate@binkert.org        Fault fault = NoFault;
2672292SN/A
2682292SN/A        %(op_decl)s;
2692292SN/A        %(mem_decl)s;
2702292SN/A        %(op_rd)s;
2712292SN/A        %(ea_code)s;
2722292SN/A
2732292SN/A        MemUnion memUnion;
2746221Snate@binkert.org        uint8_t *dataPtr = memUnion.bytes;
2752292SN/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,
2846221Snate@binkert.org                                     memAccessFlags, NULL);
2856221Snate@binkert.org            }
2862292SN/A
2873867Sbinkertn@umich.edu            if (fault == NoFault) {
2886221Snate@binkert.org                %(op_wb)s;
2892292SN/A            }
2902292SN/A        } else {
2912292SN/A            xc->setPredicate(false);
2922292SN/A        }
2932292SN/A
2942292SN/A        return fault;
2952292SN/A    }
2962292SN/A}};
2972292SN/A
2986221Snate@binkert.orgdef 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;
3076221Snate@binkert.org        %(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;
3166221Snate@binkert.org
3172292SN/A            if (fault == NoFault) {
3182292SN/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            }
3256221Snate@binkert.org
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;
3346221Snate@binkert.org    }
3356221Snate@binkert.org}};
3362292SN/A
3373867Sbinkertn@umich.edudef template StoreExInitiateAcc {{
3386221Snate@binkert.org    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
3392292SN/A                                      Trace::InstRecord *traceData) const
3402292SN/A    {
3412329SN/A        Addr EA;
3422329SN/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
3546221Snate@binkert.org            if (fault == NoFault) {
3556221Snate@binkert.org                fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
3562292SN/A                        NULL);
3573867Sbinkertn@umich.edu            }
3586221Snate@binkert.org        } else {
3593867Sbinkertn@umich.edu            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
3736221Snate@binkert.org        %(op_decl)s;
3746221Snate@binkert.org        %(op_rd)s;
3752292SN/A        %(ea_code)s;
3763867Sbinkertn@umich.edu
3776221Snate@binkert.org        if (%(predicate_test)s)
3783867Sbinkertn@umich.edu        {
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
3916221Snate@binkert.org        return fault;
3926221Snate@binkert.org    }
3932292SN/A}};
3943867Sbinkertn@umich.edu
3956221Snate@binkert.orgdef template NeonStoreInitiateAcc {{
3963867Sbinkertn@umich.edu    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
4082292SN/A        if (%(predicate_test)s)
4096221Snate@binkert.org        {
4106221Snate@binkert.org            MemUnion memUnion;
4112292SN/A            if (fault == NoFault) {
4123867Sbinkertn@umich.edu                %(memacc_code)s;
4136221Snate@binkert.org            }
4143867Sbinkertn@umich.edu
4152292SN/A            if (fault == NoFault) {
4162292SN/A                fault = xc->writeMem(memUnion.bytes, %(size)d, EA,
4172292SN/A                                     memAccessFlags, NULL);
4182292SN/A            }
4192292SN/A        } else {
4202292SN/A            xc->setPredicate(false);
4212292SN/A        }
4222292SN/A
4232292SN/A        return fault;
4242292SN/A    }
4252292SN/A}};
4262292SN/A
4276221Snate@binkert.orgdef template LoadInitiateAcc {{
4286221Snate@binkert.org    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
4292292SN/A                                      Trace::InstRecord *traceData) const
4303867Sbinkertn@umich.edu    {
4316221Snate@binkert.org        Addr EA;
4323867Sbinkertn@umich.edu        Fault fault = NoFault;
4332292SN/A
4342292SN/A        %(op_src_decl)s;
4352292SN/A        %(op_rd)s;
4362292SN/A        %(ea_code)s;
4372292SN/A
4382292SN/A        if (%(predicate_test)s)
4392292SN/A        {
4402292SN/A            if (fault == NoFault) {
4412292SN/A                fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
4422292SN/A            }
4432292SN/A        } else {
4442292SN/A            xc->setPredicate(false);
4456221Snate@binkert.org        }
4466221Snate@binkert.org
4472292SN/A        return fault;
4483867Sbinkertn@umich.edu    }
4496221Snate@binkert.org}};
4503867Sbinkertn@umich.edu
4512292SN/Adef template NeonLoadInitiateAcc {{
4522292SN/A    template <class Element>
4532292SN/A    Fault %(class_name)s<Element>::initiateAcc(
4542292SN/A            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
4552292SN/A    {
4562292SN/A        Addr EA;
4572292SN/A        Fault fault = NoFault;
4582292SN/A
4596221Snate@binkert.org        %(op_decl)s;
4602292SN/A        %(mem_decl)s;
4613870Sbinkertn@umich.edu        %(op_rd)s;
4622292SN/A        %(ea_code)s;
4632292SN/A
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);
4716221Snate@binkert.org            }
4726221Snate@binkert.org        } else {
4732292SN/A            xc->setPredicate(false);
4743867Sbinkertn@umich.edu        }
4756221Snate@binkert.org
4763867Sbinkertn@umich.edu        return fault;
4773867Sbinkertn@umich.edu    }
4782292SN/A}};
4792292SN/A
4802292SN/Adef template LoadCompleteAcc {{
4812292SN/A    Fault %(class_name)s::completeAcc(PacketPtr pkt,
4822292SN/A                                      %(CPU_exec_context)s *xc,
4832292SN/A                                      Trace::InstRecord *traceData) const
4842292SN/A    {
4852292SN/A        Fault fault = NoFault;
4866221Snate@binkert.org
4872292SN/A        %(op_decl)s;
4882292SN/A        %(op_rd)s;
4892292SN/A
4903867Sbinkertn@umich.edu        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
4992292SN/A            if (fault == NoFault) {
5006221Snate@binkert.org                %(op_wb)s;
5016221Snate@binkert.org            }
5022292SN/A        }
5033867Sbinkertn@umich.edu
5046221Snate@binkert.org        return fault;
5053867Sbinkertn@umich.edu    }
5062292SN/A}};
5072292SN/A
5082292SN/Adef template NeonLoadCompleteAcc {{
5092292SN/A    template <class Element>
5102292SN/A    Fault %(class_name)s<Element>::completeAcc(
5112292SN/A            PacketPtr pkt, %(CPU_exec_context)s *xc,
5122292SN/A            Trace::InstRecord *traceData) const
5132292SN/A    {
5142292SN/A        Fault fault = NoFault;
5156221Snate@binkert.org
5162292SN/A        %(mem_decl)s;
5172292SN/A        %(op_decl)s;
5182292SN/A        %(op_rd)s;
5193870Sbinkertn@umich.edu
5202292SN/A        if (%(predicate_test)s)
5212292SN/A        {
5222292SN/A            // ARM instructions will not have a pkt if the predicate is false
5232292SN/A            MemUnion &memUnion = *(MemUnion *)pkt->getPtr<uint8_t>();
5242292SN/A
5252292SN/A            if (fault == NoFault) {
5262292SN/A                %(memacc_code)s;
5272292SN/A            }
5282292SN/A
5296221Snate@binkert.org            if (fault == NoFault) {
5306221Snate@binkert.org                %(op_wb)s;
5312292SN/A            }
5323867Sbinkertn@umich.edu        }
5336221Snate@binkert.org
5343867Sbinkertn@umich.edu        return fault;
5352292SN/A    }
5362292SN/A}};
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;
5446221Snate@binkert.org    }
5452292SN/A}};
5462292SN/A
5472292SN/Adef template NeonStoreCompleteAcc {{
5483870Sbinkertn@umich.edu    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 {{
5586221Snate@binkert.org    Fault %(class_name)s::completeAcc(PacketPtr pkt,
5596221Snate@binkert.org                                      %(CPU_exec_context)s *xc,
5602292SN/A                                      Trace::InstRecord *traceData) const
5613867Sbinkertn@umich.edu    {
5626221Snate@binkert.org        Fault fault = NoFault;
5633867Sbinkertn@umich.edu
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) {
5736221Snate@binkert.org                %(op_wb)s;
5742292SN/A            }
5753870Sbinkertn@umich.edu        }
5762292SN/A
5772292SN/A        return fault;
5782292SN/A    }
5792292SN/A}};
5802292SN/A
5812292SN/Adef template RfeDeclare {{
5822292SN/A    /**
5832292SN/A     * Static instruction class for "%(mnemonic)s".
5842292SN/A     */
5856221Snate@binkert.org    class %(class_name)s : public %(base_class)s
5866221Snate@binkert.org    {
5872292SN/A      public:
5883867Sbinkertn@umich.edu
5896221Snate@binkert.org        /// Constructor.
5903867Sbinkertn@umich.edu        %(class_name)s(ExtMachInst machInst,
5915557Sktlim@umich.edu                uint32_t _base, int _mode, bool _wb);
5925557Sktlim@umich.edu
5932292SN/A        %(BasicExecDeclare)s
5942292SN/A
5955557Sktlim@umich.edu        %(InitiateAccDeclare)s
5962292SN/A
5972292SN/A        %(CompleteAccDeclare)s
5982292SN/A    };
5992292SN/A}};
6002292SN/A
6012292SN/Adef template SrsDeclare {{
6026221Snate@binkert.org    /**
6036221Snate@binkert.org     * Static instruction class for "%(mnemonic)s".
6042292SN/A     */
6053867Sbinkertn@umich.edu    class %(class_name)s : public %(base_class)s
6066221Snate@binkert.org    {
6073867Sbinkertn@umich.edu      public:
6085557Sktlim@umich.edu
6095557Sktlim@umich.edu        /// Constructor.
6102292SN/A        %(class_name)s(ExtMachInst machInst,
6112292SN/A                uint32_t _regMode, int _mode, bool _wb);
6125557Sktlim@umich.edu
6132292SN/A        %(BasicExecDeclare)s
6142292SN/A
6152292SN/A        %(InitiateAccDeclare)s
6162292SN/A
6172292SN/A        %(CompleteAccDeclare)s
6182292SN/A    };
6196221Snate@binkert.org}};
6206221Snate@binkert.org
6212292SN/Adef template SwapDeclare {{
6223867Sbinkertn@umich.edu    /**
6236221Snate@binkert.org     * Static instruction class for "%(mnemonic)s".
6243867Sbinkertn@umich.edu     */
6252292SN/A    class %(class_name)s : public %(base_class)s
6262292SN/A    {
6272292SN/A      public:
628
629        /// Constructor.
630        %(class_name)s(ExtMachInst machInst,
631                uint32_t _dest, uint32_t _op1, uint32_t _base);
632
633        %(BasicExecDeclare)s
634
635        %(InitiateAccDeclare)s
636
637        %(CompleteAccDeclare)s
638    };
639}};
640
641def template LoadStoreDImmDeclare {{
642    /**
643     * Static instruction class for "%(mnemonic)s".
644     */
645    class %(class_name)s : public %(base_class)s
646    {
647      public:
648
649        /// Constructor.
650        %(class_name)s(ExtMachInst machInst,
651                uint32_t _dest, uint32_t _dest2,
652                uint32_t _base, bool _add, int32_t _imm);
653
654        %(BasicExecDeclare)s
655
656        %(InitiateAccDeclare)s
657
658        %(CompleteAccDeclare)s
659    };
660}};
661
662def template StoreExDImmDeclare {{
663    /**
664     * Static instruction class for "%(mnemonic)s".
665     */
666    class %(class_name)s : public %(base_class)s
667    {
668      public:
669
670        /// Constructor.
671        %(class_name)s(ExtMachInst machInst,
672                uint32_t _result, uint32_t _dest, uint32_t _dest2,
673                uint32_t _base, bool _add, int32_t _imm);
674
675        %(BasicExecDeclare)s
676
677        %(InitiateAccDeclare)s
678
679        %(CompleteAccDeclare)s
680    };
681}};
682
683def template LoadStoreImmDeclare {{
684    /**
685     * Static instruction class for "%(mnemonic)s".
686     */
687    class %(class_name)s : public %(base_class)s
688    {
689      public:
690
691        /// Constructor.
692        %(class_name)s(ExtMachInst machInst,
693                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
694
695        %(BasicExecDeclare)s
696
697        %(InitiateAccDeclare)s
698
699        %(CompleteAccDeclare)s
700    };
701}};
702
703def template StoreExImmDeclare {{
704    /**
705     * Static instruction class for "%(mnemonic)s".
706     */
707    class %(class_name)s : public %(base_class)s
708    {
709      public:
710
711        /// Constructor.
712        %(class_name)s(ExtMachInst machInst,
713                uint32_t _result, uint32_t _dest, uint32_t _base,
714                bool _add, int32_t _imm);
715
716        %(BasicExecDeclare)s
717
718        %(InitiateAccDeclare)s
719
720        %(CompleteAccDeclare)s
721    };
722}};
723
724def template StoreDRegDeclare {{
725    /**
726     * Static instruction class for "%(mnemonic)s".
727     */
728    class %(class_name)s : public %(base_class)s
729    {
730      public:
731
732        /// Constructor.
733        %(class_name)s(ExtMachInst machInst,
734                uint32_t _dest, uint32_t _dest2,
735                uint32_t _base, bool _add,
736                int32_t _shiftAmt, uint32_t _shiftType,
737                uint32_t _index);
738
739        %(BasicExecDeclare)s
740
741        %(InitiateAccDeclare)s
742
743        %(CompleteAccDeclare)s
744    };
745}};
746
747def template StoreRegDeclare {{
748    /**
749     * Static instruction class for "%(mnemonic)s".
750     */
751    class %(class_name)s : public %(base_class)s
752    {
753      public:
754
755        /// Constructor.
756        %(class_name)s(ExtMachInst machInst,
757                uint32_t _dest, uint32_t _base, bool _add,
758                int32_t _shiftAmt, uint32_t _shiftType,
759                uint32_t _index);
760
761        %(BasicExecDeclare)s
762
763        %(InitiateAccDeclare)s
764
765        %(CompleteAccDeclare)s
766    };
767}};
768
769def template LoadDRegDeclare {{
770    /**
771     * Static instruction class for "%(mnemonic)s".
772     */
773    class %(class_name)s : public %(base_class)s
774    {
775      public:
776
777        /// Constructor.
778        %(class_name)s(ExtMachInst machInst,
779                uint32_t _dest, uint32_t _dest2,
780                uint32_t _base, bool _add,
781                int32_t _shiftAmt, uint32_t _shiftType,
782                uint32_t _index);
783
784        %(BasicExecDeclare)s
785
786        %(InitiateAccDeclare)s
787
788        %(CompleteAccDeclare)s
789    };
790}};
791
792def template LoadRegDeclare {{
793    /**
794     * Static instruction class for "%(mnemonic)s".
795     */
796    class %(class_name)s : public %(base_class)s
797    {
798      public:
799
800        /// Constructor.
801        %(class_name)s(ExtMachInst machInst,
802                uint32_t _dest, uint32_t _base, bool _add,
803                int32_t _shiftAmt, uint32_t _shiftType,
804                uint32_t _index);
805
806        %(BasicExecDeclare)s
807
808        %(InitiateAccDeclare)s
809
810        %(CompleteAccDeclare)s
811    };
812}};
813
814def template LoadImmDeclare {{
815    /**
816     * Static instruction class for "%(mnemonic)s".
817     */
818    class %(class_name)s : public %(base_class)s
819    {
820      public:
821
822        /// Constructor.
823        %(class_name)s(ExtMachInst machInst,
824                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
825
826        %(BasicExecDeclare)s
827
828        %(InitiateAccDeclare)s
829
830        %(CompleteAccDeclare)s
831    };
832}};
833
834def template InitiateAccDeclare {{
835    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
836}};
837
838def template CompleteAccDeclare {{
839    Fault completeAcc(PacketPtr,  %(CPU_exec_context)s *, Trace::InstRecord *) const;
840}};
841
842def template RfeConstructor {{
843    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
844                                          uint32_t _base, int _mode, bool _wb)
845        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
846                         (IntRegIndex)_base, (AddrMode)_mode, _wb)
847    {
848        %(constructor)s;
849        if (!(condCode == COND_AL || condCode == COND_UC)) {
850            for (int x = 0; x < _numDestRegs; x++) {
851                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
852            }
853        }
854#if %(use_uops)d
855        uops = new StaticInstPtr[1 + %(use_wb)d + %(use_pc)d];
856        int uopIdx = 0;
857        uops[uopIdx] = new %(acc_name)s(machInst, _base, _mode, _wb);
858        uops[uopIdx]->setDelayedCommit();
859#if %(use_wb)d
860        uops[++uopIdx] = new %(wb_decl)s;
861        uops[uopIdx]->setDelayedCommit();
862#endif
863#if %(use_pc)d
864        uops[++uopIdx] = new %(pc_decl)s;
865#endif
866        uops[uopIdx]->setLastMicroop();
867#endif
868    }
869}};
870
871def template SrsConstructor {{
872    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
873            uint32_t _regMode, int _mode, bool _wb)
874         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
875                 (OperatingMode)_regMode, (AddrMode)_mode, _wb)
876    {
877        %(constructor)s;
878        if (!(condCode == COND_AL || condCode == COND_UC)) {
879            for (int x = 0; x < _numDestRegs; x++) {
880                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
881            }
882        }
883#if %(use_uops)d
884        assert(numMicroops >= 2);
885        uops = new StaticInstPtr[numMicroops];
886        uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb);
887        uops[0]->setDelayedCommit();
888        uops[1] = new %(wb_decl)s;
889        uops[1]->setLastMicroop();
890#endif
891    }
892}};
893
894def template SwapConstructor {{
895    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
896            uint32_t _dest, uint32_t _op1, uint32_t _base)
897         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
898                 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
899    {
900        %(constructor)s;
901        if (!(condCode == COND_AL || condCode == COND_UC)) {
902            for (int x = 0; x < _numDestRegs; x++) {
903                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
904            }
905        }
906    }
907}};
908
909def template LoadStoreDImmConstructor {{
910    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
911            uint32_t _dest, uint32_t _dest2,
912            uint32_t _base, bool _add, int32_t _imm)
913         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
914                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
915                 (IntRegIndex)_base, _add, _imm)
916    {
917        %(constructor)s;
918        if (!(condCode == COND_AL || condCode == COND_UC)) {
919            for (int x = 0; x < _numDestRegs; x++) {
920                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
921            }
922        }
923#if %(use_uops)d
924        assert(numMicroops >= 2);
925        uops = new StaticInstPtr[numMicroops];
926        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm);
927        uops[0]->setDelayedCommit();
928        uops[1] = new %(wb_decl)s;
929        uops[1]->setLastMicroop();
930#endif
931    }
932}};
933
934def template StoreExDImmConstructor {{
935    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
936            uint32_t _result, uint32_t _dest, uint32_t _dest2,
937            uint32_t _base, bool _add, int32_t _imm)
938         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
939                 (IntRegIndex)_result,
940                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
941                 (IntRegIndex)_base, _add, _imm)
942    {
943        %(constructor)s;
944        if (!(condCode == COND_AL || condCode == COND_UC)) {
945            for (int x = 0; x < _numDestRegs; x++) {
946                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
947            }
948        }
949#if %(use_uops)d
950        assert(numMicroops >= 2);
951        uops = new StaticInstPtr[numMicroops];
952        uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2,
953                                   _base, _add, _imm);
954        uops[0]->setDelayedCommit();
955        uops[1] = new %(wb_decl)s;
956        uops[1]->setLastMicroop();
957#endif
958    }
959}};
960
961def template LoadStoreImmConstructor {{
962    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
963            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
964         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
965                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
966    {
967        %(constructor)s;
968        if (!(condCode == COND_AL || condCode == COND_UC)) {
969            for (int x = 0; x < _numDestRegs; x++) {
970                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
971            }
972        }
973#if %(use_uops)d
974        assert(numMicroops >= 2);
975        uops = new StaticInstPtr[numMicroops];
976        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
977        uops[0]->setDelayedCommit();
978        uops[1] = new %(wb_decl)s;
979        uops[1]->setLastMicroop();
980#endif
981    }
982}};
983
984def template StoreExImmConstructor {{
985    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
986            uint32_t _result, uint32_t _dest, uint32_t _base,
987            bool _add, int32_t _imm)
988         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
989                 (IntRegIndex)_result, (IntRegIndex)_dest,
990                 (IntRegIndex)_base, _add, _imm)
991    {
992        %(constructor)s;
993        if (!(condCode == COND_AL || condCode == COND_UC)) {
994            for (int x = 0; x < _numDestRegs; x++) {
995                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
996            }
997        }
998#if %(use_uops)d
999        assert(numMicroops >= 2);
1000        uops = new StaticInstPtr[numMicroops];
1001        uops[0] = new %(acc_name)s(machInst, _result, _dest,
1002                                   _base, _add, _imm);
1003        uops[0]->setDelayedCommit();
1004        uops[1] = new %(wb_decl)s;
1005        uops[1]->setLastMicroop();
1006#endif
1007    }
1008}};
1009
1010def template StoreDRegConstructor {{
1011    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1012            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1013            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1014         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1015                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1016                 (IntRegIndex)_base, _add,
1017                 _shiftAmt, (ArmShiftType)_shiftType,
1018                 (IntRegIndex)_index)
1019    {
1020        %(constructor)s;
1021        if (!(condCode == COND_AL || condCode == COND_UC)) {
1022            for (int x = 0; x < _numDestRegs; x++) {
1023                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1024            }
1025        }
1026#if %(use_uops)d
1027        assert(numMicroops >= 2);
1028        uops = new StaticInstPtr[numMicroops];
1029        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1030                                   _shiftAmt, _shiftType, _index);
1031        uops[0]->setDelayedCommit();
1032        uops[1] = new %(wb_decl)s;
1033        uops[1]->setLastMicroop();
1034#endif
1035    }
1036}};
1037
1038def template StoreRegConstructor {{
1039    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1040            uint32_t _dest, uint32_t _base, bool _add,
1041            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1042         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1043                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1044                 _shiftAmt, (ArmShiftType)_shiftType,
1045                 (IntRegIndex)_index)
1046    {
1047        %(constructor)s;
1048        if (!(condCode == COND_AL || condCode == COND_UC)) {
1049            for (int x = 0; x < _numDestRegs; x++) {
1050                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1051            }
1052        }
1053#if %(use_uops)d
1054        assert(numMicroops >= 2);
1055        uops = new StaticInstPtr[numMicroops];
1056        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1057                                   _shiftAmt, _shiftType, _index);
1058        uops[0]->setDelayedCommit();
1059        uops[1] = new %(wb_decl)s;
1060        uops[1]->setLastMicroop();
1061#endif
1062    }
1063}};
1064
1065def template LoadDRegConstructor {{
1066    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1067            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1068            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1069         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1070                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1071                 (IntRegIndex)_base, _add,
1072                 _shiftAmt, (ArmShiftType)_shiftType,
1073                 (IntRegIndex)_index)
1074    {
1075        %(constructor)s;
1076        if (!(condCode == COND_AL || condCode == COND_UC)) {
1077            for (int x = 0; x < _numDestRegs; x++) {
1078                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1079            }
1080        }
1081#if %(use_uops)d
1082        assert(numMicroops >= 2);
1083        uops = new StaticInstPtr[numMicroops];
1084        if ((_dest == _index) || (_dest2 == _index)) {
1085            IntRegIndex wbIndexReg = INTREG_UREG0;
1086            uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1087            uops[0]->setDelayedCommit();
1088            uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1089                                       _shiftAmt, _shiftType, _index);
1090            uops[1]->setDelayedCommit();
1091            uops[2] = new %(wb_decl)s;
1092            uops[2]->setLastMicroop();
1093        } else {
1094            IntRegIndex wbIndexReg = index;
1095            uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1096                                       _shiftAmt, _shiftType, _index);
1097            uops[0]->setDelayedCommit();
1098            uops[1] = new %(wb_decl)s;
1099            uops[1]->setLastMicroop();
1100        }
1101#endif
1102    }
1103}};
1104
1105def template LoadRegConstructor {{
1106    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1107            uint32_t _dest, uint32_t _base, bool _add,
1108            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1109         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1110                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1111                 _shiftAmt, (ArmShiftType)_shiftType,
1112                 (IntRegIndex)_index)
1113    {
1114        %(constructor)s;
1115        bool conditional M5_VAR_USED = false;
1116        if (!(condCode == COND_AL || condCode == COND_UC)) {
1117            conditional = true;
1118            for (int x = 0; x < _numDestRegs; x++) {
1119                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1120            }
1121        }
1122#if %(use_uops)d
1123        assert(numMicroops >= 2);
1124        uops = new StaticInstPtr[numMicroops];
1125        if (_dest == INTREG_PC) {
1126            IntRegIndex wbIndexReg = index;
1127            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1128                                       _shiftAmt, _shiftType, _index);
1129            uops[0]->setDelayedCommit();
1130            uops[1] = new %(wb_decl)s;
1131            uops[1]->setDelayedCommit();
1132            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1133            uops[2]->setFlag(StaticInst::IsControl);
1134            uops[2]->setFlag(StaticInst::IsIndirectControl);
1135            if (conditional)
1136                uops[2]->setFlag(StaticInst::IsCondControl);
1137            else
1138                uops[2]->setFlag(StaticInst::IsUncondControl);
1139            uops[2]->setLastMicroop();
1140        } else if(_dest == _index) {
1141            IntRegIndex wbIndexReg = INTREG_UREG0;
1142            uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1143            uops[0]->setDelayedCommit();
1144            uops[1] = new %(acc_name)s(machInst, _dest, _base, _add,
1145                                      _shiftAmt, _shiftType, _index);
1146            uops[1]->setDelayedCommit();
1147            uops[2] = new %(wb_decl)s;
1148            uops[2]->setLastMicroop();
1149        } else {
1150            IntRegIndex wbIndexReg = index;
1151            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1152                                      _shiftAmt, _shiftType, _index);
1153            uops[0]->setDelayedCommit();
1154            uops[1] = new %(wb_decl)s;
1155            uops[1]->setLastMicroop();
1156
1157        }
1158#endif
1159    }
1160}};
1161
1162def template LoadImmConstructor {{
1163    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1164            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
1165         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1166                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
1167    {
1168        %(constructor)s;
1169        bool conditional M5_VAR_USED = false;
1170        if (!(condCode == COND_AL || condCode == COND_UC)) {
1171            conditional = true;
1172            for (int x = 0; x < _numDestRegs; x++) {
1173                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1174            }
1175        }
1176#if %(use_uops)d
1177        assert(numMicroops >= 2);
1178        uops = new StaticInstPtr[numMicroops];
1179        if (_dest == INTREG_PC) {
1180            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1181                                   _imm);
1182            uops[0]->setDelayedCommit();
1183            uops[1] = new %(wb_decl)s;
1184            uops[1]->setDelayedCommit();
1185            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1186            uops[2]->setFlag(StaticInst::IsControl);
1187            uops[2]->setFlag(StaticInst::IsIndirectControl);
1188            if (conditional)
1189                uops[2]->setFlag(StaticInst::IsCondControl);
1190            else
1191                uops[2]->setFlag(StaticInst::IsUncondControl);
1192            if (_base == INTREG_SP && _add && _imm == 4 && %(is_ras_pop)s)
1193                uops[2]->setFlag(StaticInst::IsReturn);
1194            uops[2]->setLastMicroop();
1195        } else {
1196            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
1197            uops[0]->setDelayedCommit();
1198            uops[1] = new %(wb_decl)s;
1199            uops[1]->setLastMicroop();
1200        }
1201#endif
1202    }
1203}};
1204
1205