mem.isa revision 8140
110037SARM gem5 Developers// -*- mode:c++ -*-
210037SARM gem5 Developers
310037SARM gem5 Developers// Copyright (c) 2010 ARM Limited
410037SARM gem5 Developers// All rights reserved
510037SARM gem5 Developers//
610037SARM gem5 Developers// The license below extends only to copyright in the software and shall
710037SARM gem5 Developers// not be construed as granting a license to any other intellectual
810037SARM gem5 Developers// property including but not limited to intellectual property relating
910037SARM gem5 Developers// to a hardware implementation of the functionality of the software
1010037SARM gem5 Developers// licensed hereunder.  You may use the software subject to the license
1110037SARM gem5 Developers// terms below provided that you ensure that this notice is replicated
1210037SARM gem5 Developers// unmodified and in its entirety in all distributions of the software,
1310037SARM gem5 Developers// modified or unmodified, in source code or in binary form.
1410037SARM gem5 Developers//
1510037SARM gem5 Developers// Copyright (c) 2007-2008 The Florida State University
1610037SARM gem5 Developers// All rights reserved.
1710037SARM gem5 Developers//
1810037SARM gem5 Developers// Redistribution and use in source and binary forms, with or without
1910037SARM gem5 Developers// modification, are permitted provided that the following conditions are
2010037SARM gem5 Developers// met: redistributions of source code must retain the above copyright
2110037SARM gem5 Developers// notice, this list of conditions and the following disclaimer;
2210037SARM gem5 Developers// redistributions in binary form must reproduce the above copyright
2310037SARM gem5 Developers// notice, this list of conditions and the following disclaimer in the
2410037SARM gem5 Developers// documentation and/or other materials provided with the distribution;
2510037SARM gem5 Developers// neither the name of the copyright holders nor the names of its
2610037SARM gem5 Developers// contributors may be used to endorse or promote products derived from
2710037SARM gem5 Developers// this software without specific prior written permission.
2810037SARM gem5 Developers//
2910037SARM gem5 Developers// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3010037SARM gem5 Developers// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3110037SARM gem5 Developers// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3210037SARM gem5 Developers// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3310037SARM gem5 Developers// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3410037SARM gem5 Developers// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3510037SARM gem5 Developers// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3610037SARM gem5 Developers// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3710037SARM gem5 Developers// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3810037SARM gem5 Developers// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3910037SARM gem5 Developers// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4010037SARM gem5 Developers//
4110037SARM gem5 Developers// Authors: Stephen Hines
4210037SARM gem5 Developers
4310037SARM gem5 Developers
4410037SARM gem5 Developersdef template PanicExecute {{
4510037SARM gem5 Developers    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
4610037SARM gem5 Developers                                  Trace::InstRecord *traceData) const
4710037SARM gem5 Developers    {
4810037SARM gem5 Developers        panic("Execute function executed when it shouldn't be!\n");
4910037SARM gem5 Developers        return NoFault;
5010037SARM gem5 Developers    }
5110037SARM gem5 Developers}};
5210037SARM gem5 Developers
5310037SARM gem5 Developersdef template PanicInitiateAcc {{
5410037SARM gem5 Developers    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
5510905Sandreas.sandberg@arm.com                                      Trace::InstRecord *traceData) const
5610905Sandreas.sandberg@arm.com    {
5710905Sandreas.sandberg@arm.com        panic("InitiateAcc function executed when it shouldn't be!\n");
5810037SARM gem5 Developers        return NoFault;
5910037SARM gem5 Developers    }
6010037SARM gem5 Developers}};
6110037SARM gem5 Developers
6210037SARM gem5 Developersdef template PanicCompleteAcc {{
6310037SARM gem5 Developers    Fault %(class_name)s::completeAcc(PacketPtr pkt,
6410037SARM gem5 Developers                                      %(CPU_exec_context)s *xc,
6510037SARM gem5 Developers                                      Trace::InstRecord *traceData) const
6610037SARM gem5 Developers    {
6710037SARM gem5 Developers        panic("CompleteAcc function executed when it shouldn't be!\n");
6810037SARM gem5 Developers        return NoFault;
6910037SARM gem5 Developers    }
7010037SARM gem5 Developers}};
7110037SARM gem5 Developers
7210037SARM gem5 Developers
7310037SARM gem5 Developersdef template SwapExecute {{
7410037SARM gem5 Developers    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
7510037SARM gem5 Developers                                  Trace::InstRecord *traceData) const
7610037SARM gem5 Developers    {
7710037SARM gem5 Developers        Addr EA;
7810037SARM gem5 Developers        Fault fault = NoFault;
7910037SARM gem5 Developers
8010037SARM gem5 Developers        %(op_decl)s;
8110037SARM gem5 Developers        uint64_t memData = 0;
8210037SARM gem5 Developers        %(op_rd)s;
8310037SARM gem5 Developers        %(ea_code)s;
8410037SARM gem5 Developers
8510037SARM gem5 Developers        if (%(predicate_test)s)
8610037SARM gem5 Developers        {
8710037SARM gem5 Developers            %(preacc_code)s;
8810037SARM gem5 Developers
8910037SARM gem5 Developers            if (fault == NoFault) {
9010037SARM gem5 Developers                fault = xc->write((uint%(mem_acc_size)d_t&)Mem,
9110037SARM gem5 Developers                        EA, memAccessFlags, &memData);
9210037SARM gem5 Developers            }
9310037SARM gem5 Developers
9410037SARM gem5 Developers            if (fault == NoFault) {
9510037SARM gem5 Developers                %(postacc_code)s;
9610037SARM gem5 Developers            }
9710037SARM gem5 Developers
9810037SARM gem5 Developers            if (fault == NoFault) {
9910037SARM gem5 Developers                %(op_wb)s;
10010037SARM gem5 Developers            }
10110037SARM gem5 Developers        } else {
10210037SARM gem5 Developers            xc->setPredicate(false);
10310037SARM gem5 Developers        }
10410037SARM gem5 Developers
10510037SARM gem5 Developers        if (fault == NoFault && machInst.itstateMask != 0 &&
10610037SARM gem5 Developers                (!isMicroop() || isLastMicroop())) {
10710037SARM gem5 Developers            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
10810037SARM gem5 Developers        }
10910037SARM gem5 Developers
11010037SARM gem5 Developers        return fault;
11110037SARM gem5 Developers    }
11210037SARM gem5 Developers}};
11310037SARM gem5 Developers
11410037SARM gem5 Developersdef template SwapInitiateAcc {{
11510037SARM gem5 Developers    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
11610037SARM gem5 Developers                                      Trace::InstRecord *traceData) const
11710037SARM gem5 Developers    {
11810037SARM gem5 Developers        Addr EA;
11910037SARM gem5 Developers        Fault fault = NoFault;
12010037SARM gem5 Developers
12110037SARM gem5 Developers        %(op_decl)s;
12210037SARM gem5 Developers        uint64_t memData = 0;
12310037SARM gem5 Developers        %(op_rd)s;
12410037SARM gem5 Developers        %(ea_code)s;
12510037SARM gem5 Developers
12610037SARM gem5 Developers        if (%(predicate_test)s)
12710037SARM gem5 Developers        {
12810037SARM gem5 Developers            %(preacc_code)s;
12910037SARM gem5 Developers
13010037SARM gem5 Developers            if (fault == NoFault) {
13110037SARM gem5 Developers                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
13210037SARM gem5 Developers                                  memAccessFlags, &memData);
13310037SARM gem5 Developers            }
13410037SARM gem5 Developers        } else {
13510037SARM gem5 Developers            xc->setPredicate(false);
13610037SARM gem5 Developers        }
13710037SARM gem5 Developers
13810037SARM gem5 Developers        if (fault == NoFault && machInst.itstateMask != 0 &&
13910037SARM gem5 Developers                (!isMicroop() || isLastMicroop())) {
14010037SARM gem5 Developers            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
14110037SARM gem5 Developers        }
14210037SARM gem5 Developers
14310037SARM gem5 Developers        return fault;
14410037SARM gem5 Developers    }
14510037SARM gem5 Developers}};
14610037SARM gem5 Developers
14710037SARM gem5 Developersdef template SwapCompleteAcc {{
14810037SARM gem5 Developers    Fault %(class_name)s::completeAcc(PacketPtr pkt,
14910037SARM gem5 Developers                                      %(CPU_exec_context)s *xc,
15010037SARM gem5 Developers                                      Trace::InstRecord *traceData) const
15110037SARM gem5 Developers    {
15210037SARM gem5 Developers        Fault fault = NoFault;
15310037SARM gem5 Developers
15410037SARM gem5 Developers        %(op_decl)s;
15510037SARM gem5 Developers        %(op_rd)s;
15610037SARM gem5 Developers
15710037SARM gem5 Developers        if (%(predicate_test)s)
15810037SARM gem5 Developers        {
15910037SARM gem5 Developers            // ARM instructions will not have a pkt if the predicate is false
16010037SARM gem5 Developers            uint64_t memData = pkt->get<typeof(Mem)>();
16110037SARM gem5 Developers
16210037SARM gem5 Developers            %(postacc_code)s;
16310037SARM gem5 Developers
16410037SARM gem5 Developers            if (fault == NoFault) {
16510037SARM gem5 Developers                %(op_wb)s;
16610037SARM gem5 Developers            }
16710037SARM gem5 Developers        }
16810905Sandreas.sandberg@arm.com
16910905Sandreas.sandberg@arm.com        if (fault == NoFault && machInst.itstateMask != 0) {
17010905Sandreas.sandberg@arm.com            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
17110905Sandreas.sandberg@arm.com        }
17210905Sandreas.sandberg@arm.com
17310905Sandreas.sandberg@arm.com        return fault;
17410905Sandreas.sandberg@arm.com    }
17510905Sandreas.sandberg@arm.com}};
17610905Sandreas.sandberg@arm.com
17710905Sandreas.sandberg@arm.comdef template LoadExecute {{
17810905Sandreas.sandberg@arm.com    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
17910037SARM gem5 Developers                                  Trace::InstRecord *traceData) const
18010037SARM gem5 Developers    {
18110037SARM gem5 Developers        Addr EA;
18210037SARM gem5 Developers        Fault fault = NoFault;
18310037SARM gem5 Developers
18410037SARM gem5 Developers        %(op_decl)s;
18510037SARM gem5 Developers        %(op_rd)s;
18610037SARM gem5 Developers        %(ea_code)s;
18710037SARM gem5 Developers
18810037SARM gem5 Developers        if (%(predicate_test)s)
18910037SARM gem5 Developers        {
19010037SARM gem5 Developers            if (fault == NoFault) {
19110037SARM gem5 Developers                fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
19210037SARM gem5 Developers                %(memacc_code)s;
19310037SARM gem5 Developers            }
19410905Sandreas.sandberg@arm.com
19511168Sandreas.hansson@arm.com            if (fault == NoFault) {
19611168Sandreas.hansson@arm.com                %(op_wb)s;
19710037SARM gem5 Developers            }
19810037SARM gem5 Developers        } else {
19910905Sandreas.sandberg@arm.com            xc->setPredicate(false);
20010037SARM gem5 Developers        }
20110037SARM gem5 Developers
20210037SARM gem5 Developers        if (fault == NoFault && machInst.itstateMask != 0 &&
20310037SARM gem5 Developers                (!isMicroop() || isLastMicroop())) {
20410037SARM gem5 Developers            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
20510037SARM gem5 Developers        }
20610037SARM gem5 Developers
20710037SARM gem5 Developers        return fault;
20810037SARM gem5 Developers    }
20910037SARM gem5 Developers}};
21010037SARM gem5 Developers
21110037SARM gem5 Developersdef template NeonLoadExecute {{
21210037SARM gem5 Developers    template <class Element>
21310037SARM gem5 Developers    Fault %(class_name)s<Element>::execute(
21410037SARM gem5 Developers            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
21511168Sandreas.hansson@arm.com    {
21611168Sandreas.hansson@arm.com        Addr EA;
21710037SARM gem5 Developers        Fault fault = NoFault;
21810037SARM gem5 Developers
21910037SARM gem5 Developers        %(op_decl)s;
22010037SARM gem5 Developers        %(mem_decl)s;
22110037SARM gem5 Developers        %(op_rd)s;
22210037SARM gem5 Developers        %(ea_code)s;
22310037SARM gem5 Developers
22410037SARM gem5 Developers        MemUnion memUnion;
22511005Sandreas.sandberg@arm.com        uint8_t *dataPtr = memUnion.bytes;
22610037SARM gem5 Developers
22710037SARM gem5 Developers        if (%(predicate_test)s)
22810037SARM gem5 Developers        {
22910037SARM gem5 Developers            if (fault == NoFault) {
23010037SARM gem5 Developers                fault = xc->readBytes(EA, dataPtr, %(size)d, memAccessFlags);
23110037SARM gem5 Developers                %(memacc_code)s;
23210037SARM gem5 Developers            }
23310037SARM gem5 Developers
23410037SARM gem5 Developers            if (fault == NoFault) {
23510037SARM gem5 Developers                %(op_wb)s;
23610037SARM gem5 Developers            }
23710037SARM gem5 Developers        } else {
23810037SARM gem5 Developers            xc->setPredicate(false);
23910037SARM gem5 Developers        }
24010037SARM gem5 Developers
24110037SARM gem5 Developers        if (fault == NoFault && machInst.itstateMask != 0 &&
24210037SARM gem5 Developers                (!isMicroop() || isLastMicroop())) {
24310037SARM gem5 Developers            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
24410037SARM gem5 Developers        }
24510037SARM gem5 Developers
24610037SARM gem5 Developers        return fault;
24710037SARM gem5 Developers    }
24810037SARM gem5 Developers}};
24910037SARM gem5 Developers
25010037SARM gem5 Developersdef template StoreExecute {{
25110037SARM gem5 Developers    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
25210037SARM gem5 Developers                                  Trace::InstRecord *traceData) const
25310037SARM gem5 Developers    {
25410037SARM gem5 Developers        Addr EA;
25510037SARM gem5 Developers        Fault fault = NoFault;
25610037SARM gem5 Developers
25710037SARM gem5 Developers        %(op_decl)s;
25810037SARM gem5 Developers        %(op_rd)s;
25910037SARM gem5 Developers        %(ea_code)s;
26010037SARM gem5 Developers
26110037SARM gem5 Developers        if (%(predicate_test)s)
26210037SARM gem5 Developers        {
26310037SARM gem5 Developers            if (fault == NoFault) {
26410037SARM gem5 Developers                %(memacc_code)s;
26510037SARM gem5 Developers            }
26610037SARM gem5 Developers
26710037SARM gem5 Developers            if (fault == NoFault) {
26810037SARM gem5 Developers                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
26910037SARM gem5 Developers                                  memAccessFlags, NULL);
27010037SARM gem5 Developers            }
27110037SARM gem5 Developers
27210037SARM gem5 Developers            if (fault == NoFault) {
27310037SARM gem5 Developers                %(op_wb)s;
27410037SARM gem5 Developers            }
27510037SARM gem5 Developers        } else {
27610037SARM gem5 Developers            xc->setPredicate(false);
27710037SARM gem5 Developers        }
278
279        if (fault == NoFault && machInst.itstateMask != 0 &&
280                (!isMicroop() || isLastMicroop())) {
281            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
282        }
283
284        return fault;
285    }
286}};
287
288def template NeonStoreExecute {{
289    template <class Element>
290    Fault %(class_name)s<Element>::execute(
291            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
292    {
293        Addr EA;
294        Fault fault = NoFault;
295
296        %(op_decl)s;
297        %(mem_decl)s;
298        %(op_rd)s;
299        %(ea_code)s;
300
301        MemUnion memUnion;
302        uint8_t *dataPtr = memUnion.bytes;
303
304        if (%(predicate_test)s)
305        {
306            if (fault == NoFault) {
307                %(memacc_code)s;
308            }
309
310            if (fault == NoFault) {
311                fault = xc->writeBytes(dataPtr, %(size)d, EA,
312                                       memAccessFlags, NULL);
313            }
314
315            if (fault == NoFault) {
316                %(op_wb)s;
317            }
318        } else {
319            xc->setPredicate(false);
320        }
321
322        if (fault == NoFault && machInst.itstateMask != 0 &&
323                (!isMicroop() || isLastMicroop())) {
324            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
325        }
326
327        return fault;
328    }
329}};
330
331def template StoreExExecute {{
332    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
333                                  Trace::InstRecord *traceData) const
334    {
335        Addr EA;
336        Fault fault = NoFault;
337
338        %(op_decl)s;
339        %(op_rd)s;
340        %(ea_code)s;
341
342        if (%(predicate_test)s)
343        {
344            if (fault == NoFault) {
345                %(memacc_code)s;
346            }
347
348            uint64_t writeResult;
349
350            if (fault == NoFault) {
351                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
352                                  memAccessFlags, &writeResult);
353            }
354
355            if (fault == NoFault) {
356                %(postacc_code)s;
357            }
358
359            if (fault == NoFault) {
360                %(op_wb)s;
361            }
362        } else {
363            xc->setPredicate(false);
364        }
365
366        if (fault == NoFault && machInst.itstateMask != 0 &&
367                (!isMicroop() || isLastMicroop())) {
368            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
369        }
370
371        return fault;
372    }
373}};
374
375def template StoreExInitiateAcc {{
376    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
377                                      Trace::InstRecord *traceData) const
378    {
379        Addr EA;
380        Fault fault = NoFault;
381
382        %(op_decl)s;
383        %(op_rd)s;
384        %(ea_code)s;
385
386        if (%(predicate_test)s)
387        {
388            if (fault == NoFault) {
389                %(memacc_code)s;
390            }
391
392            if (fault == NoFault) {
393                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
394                                  memAccessFlags, NULL);
395            }
396        } else {
397            xc->setPredicate(false);
398        }
399        if (fault == NoFault && machInst.itstateMask != 0 &&
400                (!isMicroop() || isLastMicroop())) {
401            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
402        }
403
404        return fault;
405    }
406}};
407
408def template StoreInitiateAcc {{
409    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
410                                      Trace::InstRecord *traceData) const
411    {
412        Addr EA;
413        Fault fault = NoFault;
414
415        %(op_decl)s;
416        %(op_rd)s;
417        %(ea_code)s;
418
419        if (%(predicate_test)s)
420        {
421            if (fault == NoFault) {
422                %(memacc_code)s;
423            }
424
425            if (fault == NoFault) {
426                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
427                                  memAccessFlags, NULL);
428            }
429        } else {
430            xc->setPredicate(false);
431        }
432
433        if (fault == NoFault && machInst.itstateMask != 0 &&
434                (!isMicroop() || isLastMicroop())) {
435            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
436        }
437
438        return fault;
439    }
440}};
441
442def template NeonStoreInitiateAcc {{
443    template <class Element>
444    Fault %(class_name)s<Element>::initiateAcc(
445            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
446    {
447        Addr EA;
448        Fault fault = NoFault;
449
450        %(op_decl)s;
451        %(mem_decl)s;
452        %(op_rd)s;
453        %(ea_code)s;
454
455        if (%(predicate_test)s)
456        {
457            MemUnion memUnion;
458            if (fault == NoFault) {
459                %(memacc_code)s;
460            }
461
462            if (fault == NoFault) {
463                fault = xc->writeBytes(memUnion.bytes, %(size)d, EA,
464                                       memAccessFlags, NULL);
465            }
466        } else {
467            xc->setPredicate(false);
468        }
469
470        if (fault == NoFault && machInst.itstateMask != 0 &&
471                (!isMicroop() || isLastMicroop())) {
472            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
473        }
474
475        return fault;
476    }
477}};
478
479def template LoadInitiateAcc {{
480    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
481                                      Trace::InstRecord *traceData) const
482    {
483        Addr EA;
484        Fault fault = NoFault;
485
486        %(op_src_decl)s;
487        %(op_rd)s;
488        %(ea_code)s;
489
490        if (%(predicate_test)s)
491        {
492            if (fault == NoFault) {
493                fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
494            }
495        } else {
496            xc->setPredicate(false);
497            if (fault == NoFault && machInst.itstateMask != 0 &&
498                    (!isMicroop() || isLastMicroop())) {
499                xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
500            }
501        }
502
503        return fault;
504    }
505}};
506
507def template NeonLoadInitiateAcc {{
508    template <class Element>
509    Fault %(class_name)s<Element>::initiateAcc(
510            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
511    {
512        Addr EA;
513        Fault fault = NoFault;
514
515        %(op_src_decl)s;
516        %(op_rd)s;
517        %(ea_code)s;
518
519        if (%(predicate_test)s)
520        {
521            if (fault == NoFault) {
522                fault = xc->readBytes(EA, NULL, %(size)d, memAccessFlags);
523            }
524        } else {
525            xc->setPredicate(false);
526            if (fault == NoFault && machInst.itstateMask != 0 &&
527                   (!isMicroop() || isLastMicroop())) {
528                xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
529            }
530        }
531
532        return fault;
533    }
534}};
535
536def template LoadCompleteAcc {{
537    Fault %(class_name)s::completeAcc(PacketPtr pkt,
538                                      %(CPU_exec_context)s *xc,
539                                      Trace::InstRecord *traceData) const
540    {
541        Fault fault = NoFault;
542
543        %(op_decl)s;
544        %(op_rd)s;
545
546        if (%(predicate_test)s)
547        {
548            // ARM instructions will not have a pkt if the predicate is false
549            Mem = pkt->get<typeof(Mem)>();
550
551            if (fault == NoFault) {
552                %(memacc_code)s;
553            }
554
555            if (fault == NoFault) {
556                %(op_wb)s;
557            }
558        }
559
560        if (fault == NoFault && machInst.itstateMask != 0) {
561            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
562        }
563
564        return fault;
565    }
566}};
567
568def template NeonLoadCompleteAcc {{
569    template <class Element>
570    Fault %(class_name)s<Element>::completeAcc(
571            PacketPtr pkt, %(CPU_exec_context)s *xc,
572            Trace::InstRecord *traceData) const
573    {
574        Fault fault = NoFault;
575
576        %(mem_decl)s;
577        %(op_decl)s;
578        %(op_rd)s;
579
580        if (%(predicate_test)s)
581        {
582            // ARM instructions will not have a pkt if the predicate is false
583            MemUnion &memUnion = *(MemUnion *)pkt->getPtr<uint8_t>();
584
585            if (fault == NoFault) {
586                %(memacc_code)s;
587            }
588
589            if (fault == NoFault) {
590                %(op_wb)s;
591            }
592        }
593
594        if (fault == NoFault && machInst.itstateMask != 0) {
595            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
596        }
597
598        return fault;
599    }
600}};
601
602def template StoreCompleteAcc {{
603    Fault %(class_name)s::completeAcc(PacketPtr pkt,
604                                      %(CPU_exec_context)s *xc,
605                                      Trace::InstRecord *traceData) const
606    {
607        if (machInst.itstateMask != 0) {
608            warn_once("Complete acc isn't called on normal stores in O3.");
609            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
610        }
611        return NoFault;
612    }
613}};
614
615def template NeonStoreCompleteAcc {{
616    template <class Element>
617    Fault %(class_name)s<Element>::completeAcc(
618            PacketPtr pkt, %(CPU_exec_context)s *xc,
619            Trace::InstRecord *traceData) const
620    {
621        if (machInst.itstateMask != 0) {
622            warn_once("Complete acc isn't called on normal stores in O3.");
623            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
624        }
625        return NoFault;
626    }
627}};
628
629def template StoreExCompleteAcc {{
630    Fault %(class_name)s::completeAcc(PacketPtr pkt,
631                                      %(CPU_exec_context)s *xc,
632                                      Trace::InstRecord *traceData) const
633    {
634        Fault fault = NoFault;
635
636        %(op_decl)s;
637        %(op_rd)s;
638
639        if (%(predicate_test)s)
640        {
641            uint64_t writeResult = pkt->req->getExtraData();
642            %(postacc_code)s;
643
644            if (fault == NoFault) {
645                %(op_wb)s;
646            }
647        }
648
649        if (fault == NoFault && machInst.itstateMask != 0) {
650            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
651        }
652
653        return fault;
654    }
655}};
656
657def template RfeDeclare {{
658    /**
659     * Static instruction class for "%(mnemonic)s".
660     */
661    class %(class_name)s : public %(base_class)s
662    {
663      public:
664
665        /// Constructor.
666        %(class_name)s(ExtMachInst machInst,
667                uint32_t _base, int _mode, bool _wb);
668
669        %(BasicExecDeclare)s
670
671        %(InitiateAccDeclare)s
672
673        %(CompleteAccDeclare)s
674    };
675}};
676
677def template SrsDeclare {{
678    /**
679     * Static instruction class for "%(mnemonic)s".
680     */
681    class %(class_name)s : public %(base_class)s
682    {
683      public:
684
685        /// Constructor.
686        %(class_name)s(ExtMachInst machInst,
687                uint32_t _regMode, int _mode, bool _wb);
688
689        %(BasicExecDeclare)s
690
691        %(InitiateAccDeclare)s
692
693        %(CompleteAccDeclare)s
694    };
695}};
696
697def template SwapDeclare {{
698    /**
699     * Static instruction class for "%(mnemonic)s".
700     */
701    class %(class_name)s : public %(base_class)s
702    {
703      public:
704
705        /// Constructor.
706        %(class_name)s(ExtMachInst machInst,
707                uint32_t _dest, uint32_t _op1, uint32_t _base);
708
709        %(BasicExecDeclare)s
710
711        %(InitiateAccDeclare)s
712
713        %(CompleteAccDeclare)s
714    };
715}};
716
717def template LoadStoreDImmDeclare {{
718    /**
719     * Static instruction class for "%(mnemonic)s".
720     */
721    class %(class_name)s : public %(base_class)s
722    {
723      public:
724
725        /// Constructor.
726        %(class_name)s(ExtMachInst machInst,
727                uint32_t _dest, uint32_t _dest2,
728                uint32_t _base, bool _add, int32_t _imm);
729
730        %(BasicExecDeclare)s
731
732        %(InitiateAccDeclare)s
733
734        %(CompleteAccDeclare)s
735    };
736}};
737
738def template StoreExDImmDeclare {{
739    /**
740     * Static instruction class for "%(mnemonic)s".
741     */
742    class %(class_name)s : public %(base_class)s
743    {
744      public:
745
746        /// Constructor.
747        %(class_name)s(ExtMachInst machInst,
748                uint32_t _result, uint32_t _dest, uint32_t _dest2,
749                uint32_t _base, bool _add, int32_t _imm);
750
751        %(BasicExecDeclare)s
752
753        %(InitiateAccDeclare)s
754
755        %(CompleteAccDeclare)s
756    };
757}};
758
759def template LoadStoreImmDeclare {{
760    /**
761     * Static instruction class for "%(mnemonic)s".
762     */
763    class %(class_name)s : public %(base_class)s
764    {
765      public:
766
767        /// Constructor.
768        %(class_name)s(ExtMachInst machInst,
769                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
770
771        %(BasicExecDeclare)s
772
773        %(InitiateAccDeclare)s
774
775        %(CompleteAccDeclare)s
776    };
777}};
778
779def template StoreExImmDeclare {{
780    /**
781     * Static instruction class for "%(mnemonic)s".
782     */
783    class %(class_name)s : public %(base_class)s
784    {
785      public:
786
787        /// Constructor.
788        %(class_name)s(ExtMachInst machInst,
789                uint32_t _result, uint32_t _dest, uint32_t _base,
790                bool _add, int32_t _imm);
791
792        %(BasicExecDeclare)s
793
794        %(InitiateAccDeclare)s
795
796        %(CompleteAccDeclare)s
797    };
798}};
799
800def template StoreDRegDeclare {{
801    /**
802     * Static instruction class for "%(mnemonic)s".
803     */
804    class %(class_name)s : public %(base_class)s
805    {
806      public:
807
808        /// Constructor.
809        %(class_name)s(ExtMachInst machInst,
810                uint32_t _dest, uint32_t _dest2,
811                uint32_t _base, bool _add,
812                int32_t _shiftAmt, uint32_t _shiftType,
813                uint32_t _index);
814
815        %(BasicExecDeclare)s
816
817        %(InitiateAccDeclare)s
818
819        %(CompleteAccDeclare)s
820    };
821}};
822
823def template StoreRegDeclare {{
824    /**
825     * Static instruction class for "%(mnemonic)s".
826     */
827    class %(class_name)s : public %(base_class)s
828    {
829      public:
830
831        /// Constructor.
832        %(class_name)s(ExtMachInst machInst,
833                uint32_t _dest, uint32_t _base, bool _add,
834                int32_t _shiftAmt, uint32_t _shiftType,
835                uint32_t _index);
836
837        %(BasicExecDeclare)s
838
839        %(InitiateAccDeclare)s
840
841        %(CompleteAccDeclare)s
842    };
843}};
844
845def template LoadDRegDeclare {{
846    /**
847     * Static instruction class for "%(mnemonic)s".
848     */
849    class %(class_name)s : public %(base_class)s
850    {
851      public:
852
853        /// Constructor.
854        %(class_name)s(ExtMachInst machInst,
855                uint32_t _dest, uint32_t _dest2,
856                uint32_t _base, bool _add,
857                int32_t _shiftAmt, uint32_t _shiftType,
858                uint32_t _index);
859
860        %(BasicExecDeclare)s
861
862        %(InitiateAccDeclare)s
863
864        %(CompleteAccDeclare)s
865    };
866}};
867
868def template LoadRegDeclare {{
869    /**
870     * Static instruction class for "%(mnemonic)s".
871     */
872    class %(class_name)s : public %(base_class)s
873    {
874      public:
875
876        /// Constructor.
877        %(class_name)s(ExtMachInst machInst,
878                uint32_t _dest, uint32_t _base, bool _add,
879                int32_t _shiftAmt, uint32_t _shiftType,
880                uint32_t _index);
881
882        %(BasicExecDeclare)s
883
884        %(InitiateAccDeclare)s
885
886        %(CompleteAccDeclare)s
887    };
888}};
889
890def template LoadImmDeclare {{
891    /**
892     * Static instruction class for "%(mnemonic)s".
893     */
894    class %(class_name)s : public %(base_class)s
895    {
896      public:
897
898        /// Constructor.
899        %(class_name)s(ExtMachInst machInst,
900                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
901
902        %(BasicExecDeclare)s
903
904        %(InitiateAccDeclare)s
905
906        %(CompleteAccDeclare)s
907    };
908}};
909
910def template InitiateAccDeclare {{
911    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
912}};
913
914def template CompleteAccDeclare {{
915    Fault completeAcc(PacketPtr,  %(CPU_exec_context)s *, Trace::InstRecord *) const;
916}};
917
918def template RfeConstructor {{
919    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
920                                          uint32_t _base, int _mode, bool _wb)
921        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
922                         (IntRegIndex)_base, (AddrMode)_mode, _wb)
923    {
924        %(constructor)s;
925        if (!(condCode == COND_AL || condCode == COND_UC)) {
926            for (int x = 0; x < _numDestRegs; x++) {
927                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
928            }
929        }
930#if %(use_uops)d
931        uops = new StaticInstPtr[1 + %(use_wb)d + %(use_pc)d];
932        int uopIdx = 0;
933        uops[uopIdx] = new %(acc_name)s(machInst, _base, _mode, _wb);
934        uops[uopIdx]->setDelayedCommit();
935#if %(use_wb)d
936        uops[++uopIdx] = new %(wb_decl)s;
937        uops[uopIdx]->setDelayedCommit();
938#endif
939#if %(use_pc)d
940        uops[++uopIdx] = new %(pc_decl)s;
941#endif
942        uops[uopIdx]->setLastMicroop();
943#endif
944    }
945}};
946
947def template SrsConstructor {{
948    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
949            uint32_t _regMode, int _mode, bool _wb)
950         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
951                 (OperatingMode)_regMode, (AddrMode)_mode, _wb)
952    {
953        %(constructor)s;
954        if (!(condCode == COND_AL || condCode == COND_UC)) {
955            for (int x = 0; x < _numDestRegs; x++) {
956                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
957            }
958        }
959#if %(use_uops)d
960        assert(numMicroops >= 2);
961        uops = new StaticInstPtr[numMicroops];
962        uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb);
963        uops[0]->setDelayedCommit();
964        uops[1] = new %(wb_decl)s;
965        uops[1]->setLastMicroop();
966#endif
967    }
968}};
969
970def template SwapConstructor {{
971    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
972            uint32_t _dest, uint32_t _op1, uint32_t _base)
973         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
974                 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
975    {
976        %(constructor)s;
977        if (!(condCode == COND_AL || condCode == COND_UC)) {
978            for (int x = 0; x < _numDestRegs; x++) {
979                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
980            }
981        }
982    }
983}};
984
985def template LoadStoreDImmConstructor {{
986    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
987            uint32_t _dest, uint32_t _dest2,
988            uint32_t _base, bool _add, int32_t _imm)
989         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
990                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
991                 (IntRegIndex)_base, _add, _imm)
992    {
993        %(constructor)s;
994        if (!(condCode == COND_AL || condCode == COND_UC)) {
995            for (int x = 0; x < _numDestRegs; x++) {
996                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
997            }
998        }
999#if %(use_uops)d
1000        assert(numMicroops >= 2);
1001        uops = new StaticInstPtr[numMicroops];
1002        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _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 StoreExDImmConstructor {{
1011    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1012            uint32_t _result, uint32_t _dest, uint32_t _dest2,
1013            uint32_t _base, bool _add, int32_t _imm)
1014         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1015                 (IntRegIndex)_result,
1016                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1017                 (IntRegIndex)_base, _add, _imm)
1018    {
1019        %(constructor)s;
1020        if (!(condCode == COND_AL || condCode == COND_UC)) {
1021            for (int x = 0; x < _numDestRegs; x++) {
1022                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1023            }
1024        }
1025#if %(use_uops)d
1026        assert(numMicroops >= 2);
1027        uops = new StaticInstPtr[numMicroops];
1028        uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2,
1029                                   _base, _add, _imm);
1030        uops[0]->setDelayedCommit();
1031        uops[1] = new %(wb_decl)s;
1032        uops[1]->setLastMicroop();
1033#endif
1034    }
1035}};
1036
1037def template LoadStoreImmConstructor {{
1038    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1039            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
1040         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1041                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
1042    {
1043        %(constructor)s;
1044        if (!(condCode == COND_AL || condCode == COND_UC)) {
1045            for (int x = 0; x < _numDestRegs; x++) {
1046                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1047            }
1048        }
1049#if %(use_uops)d
1050        assert(numMicroops >= 2);
1051        uops = new StaticInstPtr[numMicroops];
1052        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
1053        uops[0]->setDelayedCommit();
1054        uops[1] = new %(wb_decl)s;
1055        uops[1]->setLastMicroop();
1056#endif
1057    }
1058}};
1059
1060def template StoreExImmConstructor {{
1061    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1062            uint32_t _result, uint32_t _dest, uint32_t _base,
1063            bool _add, int32_t _imm)
1064         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1065                 (IntRegIndex)_result, (IntRegIndex)_dest,
1066                 (IntRegIndex)_base, _add, _imm)
1067    {
1068        %(constructor)s;
1069        if (!(condCode == COND_AL || condCode == COND_UC)) {
1070            for (int x = 0; x < _numDestRegs; x++) {
1071                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1072            }
1073        }
1074#if %(use_uops)d
1075        assert(numMicroops >= 2);
1076        uops = new StaticInstPtr[numMicroops];
1077        uops[0] = new %(acc_name)s(machInst, _result, _dest,
1078                                   _base, _add, _imm);
1079        uops[0]->setDelayedCommit();
1080        uops[1] = new %(wb_decl)s;
1081        uops[1]->setLastMicroop();
1082#endif
1083    }
1084}};
1085
1086def template StoreDRegConstructor {{
1087    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1088            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1089            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1090         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1091                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1092                 (IntRegIndex)_base, _add,
1093                 _shiftAmt, (ArmShiftType)_shiftType,
1094                 (IntRegIndex)_index)
1095    {
1096        %(constructor)s;
1097        if (!(condCode == COND_AL || condCode == COND_UC)) {
1098            for (int x = 0; x < _numDestRegs; x++) {
1099                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1100            }
1101        }
1102#if %(use_uops)d
1103        assert(numMicroops >= 2);
1104        uops = new StaticInstPtr[numMicroops];
1105        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1106                                   _shiftAmt, _shiftType, _index);
1107        uops[0]->setDelayedCommit();
1108        uops[1] = new %(wb_decl)s;
1109        uops[1]->setLastMicroop();
1110#endif
1111    }
1112}};
1113
1114def template StoreRegConstructor {{
1115    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1116            uint32_t _dest, uint32_t _base, bool _add,
1117            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1118         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1119                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1120                 _shiftAmt, (ArmShiftType)_shiftType,
1121                 (IntRegIndex)_index)
1122    {
1123        %(constructor)s;
1124        if (!(condCode == COND_AL || condCode == COND_UC)) {
1125            for (int x = 0; x < _numDestRegs; x++) {
1126                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1127            }
1128        }
1129#if %(use_uops)d
1130        assert(numMicroops >= 2);
1131        uops = new StaticInstPtr[numMicroops];
1132        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1133                                   _shiftAmt, _shiftType, _index);
1134        uops[0]->setDelayedCommit();
1135        uops[1] = new %(wb_decl)s;
1136        uops[1]->setLastMicroop();
1137#endif
1138    }
1139}};
1140
1141def template LoadDRegConstructor {{
1142    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1143            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1144            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1145         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1146                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1147                 (IntRegIndex)_base, _add,
1148                 _shiftAmt, (ArmShiftType)_shiftType,
1149                 (IntRegIndex)_index)
1150    {
1151        %(constructor)s;
1152        if (!(condCode == COND_AL || condCode == COND_UC)) {
1153            for (int x = 0; x < _numDestRegs; x++) {
1154                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1155            }
1156        }
1157#if %(use_uops)d
1158        assert(numMicroops >= 2);
1159        uops = new StaticInstPtr[numMicroops];
1160        if ((_dest == _index) || (_dest2 == _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, _dest2, _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, _dest2, _base, _add,
1172                                       _shiftAmt, _shiftType, _index);
1173            uops[0]->setDelayedCommit();
1174            uops[1] = new %(wb_decl)s;
1175            uops[1]->setLastMicroop();
1176        }
1177#endif
1178    }
1179}};
1180
1181def template LoadRegConstructor {{
1182    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1183            uint32_t _dest, uint32_t _base, bool _add,
1184            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1185         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1186                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1187                 _shiftAmt, (ArmShiftType)_shiftType,
1188                 (IntRegIndex)_index)
1189    {
1190        %(constructor)s;
1191        if (!(condCode == COND_AL || condCode == COND_UC)) {
1192            for (int x = 0; x < _numDestRegs; x++) {
1193                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1194            }
1195        }
1196#if %(use_uops)d
1197        assert(numMicroops >= 2);
1198        uops = new StaticInstPtr[numMicroops];
1199        if (_dest == INTREG_PC) {
1200            IntRegIndex wbIndexReg = index;
1201            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1202                                       _shiftAmt, _shiftType, _index);
1203            uops[0]->setDelayedCommit();
1204            uops[1] = new %(wb_decl)s;
1205            uops[1]->setDelayedCommit();
1206            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1207            uops[2]->setLastMicroop();
1208        } else if(_dest == _index) {
1209            IntRegIndex wbIndexReg = INTREG_UREG0;
1210            uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1211            uops[0]->setDelayedCommit();
1212            uops[1] = new %(acc_name)s(machInst, _dest, _base, _add,
1213                                      _shiftAmt, _shiftType, _index);
1214            uops[1]->setDelayedCommit();
1215            uops[2] = new %(wb_decl)s;
1216            uops[2]->setLastMicroop();
1217        } else {
1218            IntRegIndex wbIndexReg = index;
1219            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1220                                      _shiftAmt, _shiftType, _index);
1221            uops[0]->setDelayedCommit();
1222            uops[1] = new %(wb_decl)s;
1223            uops[1]->setLastMicroop();
1224
1225        }
1226#endif
1227    }
1228}};
1229
1230def template LoadImmConstructor {{
1231    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1232            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
1233         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1234                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
1235    {
1236        %(constructor)s;
1237        if (!(condCode == COND_AL || condCode == COND_UC)) {
1238            for (int x = 0; x < _numDestRegs; x++) {
1239                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1240            }
1241        }
1242#if %(use_uops)d
1243        assert(numMicroops >= 2);
1244        uops = new StaticInstPtr[numMicroops];
1245        if (_dest == INTREG_PC) {
1246            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1247                                   _imm);
1248            uops[0]->setDelayedCommit();
1249            uops[1] = new %(wb_decl)s;
1250            uops[1]->setDelayedCommit();
1251            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1252            uops[2]->setLastMicroop();
1253        } else {
1254            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
1255            uops[0]->setDelayedCommit();
1256            uops[1] = new %(wb_decl)s;
1257            uops[1]->setLastMicroop();
1258        }
1259#endif
1260    }
1261}};
1262
1263