mem.isa revision 8207:cad97f04eb91
114039Sstacze01@arm.com// -*- mode:c++ -*-
214039Sstacze01@arm.com
314039Sstacze01@arm.com// Copyright (c) 2010 ARM Limited
414039Sstacze01@arm.com// All rights reserved
514039Sstacze01@arm.com//
614039Sstacze01@arm.com// The license below extends only to copyright in the software and shall
714039Sstacze01@arm.com// not be construed as granting a license to any other intellectual
814039Sstacze01@arm.com// property including but not limited to intellectual property relating
914039Sstacze01@arm.com// to a hardware implementation of the functionality of the software
1014039Sstacze01@arm.com// licensed hereunder.  You may use the software subject to the license
1114039Sstacze01@arm.com// terms below provided that you ensure that this notice is replicated
1214039Sstacze01@arm.com// unmodified and in its entirety in all distributions of the software,
1314039Sstacze01@arm.com// modified or unmodified, in source code or in binary form.
1414039Sstacze01@arm.com//
1514039Sstacze01@arm.com// Copyright (c) 2007-2008 The Florida State University
1614039Sstacze01@arm.com// All rights reserved.
1714039Sstacze01@arm.com//
1814039Sstacze01@arm.com// Redistribution and use in source and binary forms, with or without
1914039Sstacze01@arm.com// modification, are permitted provided that the following conditions are
2014039Sstacze01@arm.com// met: redistributions of source code must retain the above copyright
2114039Sstacze01@arm.com// notice, this list of conditions and the following disclaimer;
2214039Sstacze01@arm.com// redistributions in binary form must reproduce the above copyright
2314039Sstacze01@arm.com// notice, this list of conditions and the following disclaimer in the
2414039Sstacze01@arm.com// documentation and/or other materials provided with the distribution;
2514039Sstacze01@arm.com// neither the name of the copyright holders nor the names of its
2614039Sstacze01@arm.com// contributors may be used to endorse or promote products derived from
2714039Sstacze01@arm.com// this software without specific prior written permission.
2814039Sstacze01@arm.com//
2914039Sstacze01@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3014039Sstacze01@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3114039Sstacze01@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3214039Sstacze01@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3314039Sstacze01@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3414039Sstacze01@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3514039Sstacze01@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3614039Sstacze01@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3714039Sstacze01@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3814039Sstacze01@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3914039Sstacze01@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4014039Sstacze01@arm.com//
4114039Sstacze01@arm.com// Authors: Stephen Hines
4214039Sstacze01@arm.com
4314252Sgabeblack@google.com
4414039Sstacze01@arm.comdef template PanicExecute {{
4514252Sgabeblack@google.com    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
4614039Sstacze01@arm.com                                  Trace::InstRecord *traceData) const
4714039Sstacze01@arm.com    {
4814039Sstacze01@arm.com        panic("Execute function executed when it shouldn't be!\n");
4914039Sstacze01@arm.com        return NoFault;
5014039Sstacze01@arm.com    }
5114039Sstacze01@arm.com}};
5214039Sstacze01@arm.com
5314039Sstacze01@arm.comdef template PanicInitiateAcc {{
5414039Sstacze01@arm.com    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
5514039Sstacze01@arm.com                                      Trace::InstRecord *traceData) const
5614039Sstacze01@arm.com    {
5714039Sstacze01@arm.com        panic("InitiateAcc function executed when it shouldn't be!\n");
5814039Sstacze01@arm.com        return NoFault;
5914039Sstacze01@arm.com    }
6014039Sstacze01@arm.com}};
6114039Sstacze01@arm.com
6214039Sstacze01@arm.comdef template PanicCompleteAcc {{
6314039Sstacze01@arm.com    Fault %(class_name)s::completeAcc(PacketPtr pkt,
6414039Sstacze01@arm.com                                      %(CPU_exec_context)s *xc,
6514039Sstacze01@arm.com                                      Trace::InstRecord *traceData) const
6614039Sstacze01@arm.com    {
6714039Sstacze01@arm.com        panic("CompleteAcc function executed when it shouldn't be!\n");
6814039Sstacze01@arm.com        return NoFault;
6914039Sstacze01@arm.com    }
7014039Sstacze01@arm.com}};
7114039Sstacze01@arm.com
7214039Sstacze01@arm.com
7314039Sstacze01@arm.comdef template SwapExecute {{
7414039Sstacze01@arm.com    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
7514039Sstacze01@arm.com                                  Trace::InstRecord *traceData) const
7614252Sgabeblack@google.com    {
7714039Sstacze01@arm.com        Addr EA;
7814039Sstacze01@arm.com        Fault fault = NoFault;
7914039Sstacze01@arm.com
8014039Sstacze01@arm.com        %(op_decl)s;
8114039Sstacze01@arm.com        uint64_t memData = 0;
8214039Sstacze01@arm.com        %(op_rd)s;
8314039Sstacze01@arm.com        %(ea_code)s;
8414039Sstacze01@arm.com
8514039Sstacze01@arm.com        if (%(predicate_test)s)
8614039Sstacze01@arm.com        {
8714039Sstacze01@arm.com            %(preacc_code)s;
8814039Sstacze01@arm.com
8914039Sstacze01@arm.com            if (fault == NoFault) {
9014039Sstacze01@arm.com                fault = xc->write((uint%(mem_acc_size)d_t&)Mem,
9114039Sstacze01@arm.com                        EA, memAccessFlags, &memData);
9214039Sstacze01@arm.com            }
9314039Sstacze01@arm.com
9414039Sstacze01@arm.com            if (fault == NoFault) {
9514039Sstacze01@arm.com                %(postacc_code)s;
9614039Sstacze01@arm.com            }
9714039Sstacze01@arm.com
9814039Sstacze01@arm.com            if (fault == NoFault) {
9914039Sstacze01@arm.com                %(op_wb)s;
10014039Sstacze01@arm.com            }
10114039Sstacze01@arm.com        } else {
10214039Sstacze01@arm.com            xc->setPredicate(false);
10314039Sstacze01@arm.com        }
10414039Sstacze01@arm.com
10514039Sstacze01@arm.com        return fault;
10614039Sstacze01@arm.com    }
10714039Sstacze01@arm.com}};
10814039Sstacze01@arm.com
10914039Sstacze01@arm.comdef template SwapInitiateAcc {{
11014039Sstacze01@arm.com    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
11114039Sstacze01@arm.com                                      Trace::InstRecord *traceData) const
11214039Sstacze01@arm.com    {
11314039Sstacze01@arm.com        Addr EA;
11414039Sstacze01@arm.com        Fault fault = NoFault;
11514039Sstacze01@arm.com
11614039Sstacze01@arm.com        %(op_decl)s;
11714039Sstacze01@arm.com        uint64_t memData = 0;
11814039Sstacze01@arm.com        %(op_rd)s;
11914039Sstacze01@arm.com        %(ea_code)s;
12014039Sstacze01@arm.com
12114039Sstacze01@arm.com        if (%(predicate_test)s)
12214039Sstacze01@arm.com        {
12314039Sstacze01@arm.com            %(preacc_code)s;
12414039Sstacze01@arm.com
12514039Sstacze01@arm.com            if (fault == NoFault) {
12614039Sstacze01@arm.com                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
12714039Sstacze01@arm.com                                  memAccessFlags, &memData);
12814039Sstacze01@arm.com            }
12914039Sstacze01@arm.com        } else {
13014039Sstacze01@arm.com            xc->setPredicate(false);
13114039Sstacze01@arm.com        }
13214039Sstacze01@arm.com
13314039Sstacze01@arm.com        return fault;
13414039Sstacze01@arm.com    }
13514039Sstacze01@arm.com}};
13614039Sstacze01@arm.com
13714039Sstacze01@arm.comdef template SwapCompleteAcc {{
13814039Sstacze01@arm.com    Fault %(class_name)s::completeAcc(PacketPtr pkt,
13914039Sstacze01@arm.com                                      %(CPU_exec_context)s *xc,
14014039Sstacze01@arm.com                                      Trace::InstRecord *traceData) const
14114039Sstacze01@arm.com    {
14214039Sstacze01@arm.com        Fault fault = NoFault;
14314039Sstacze01@arm.com
14414039Sstacze01@arm.com        %(op_decl)s;
14514039Sstacze01@arm.com        %(op_rd)s;
14614039Sstacze01@arm.com
14714039Sstacze01@arm.com        if (%(predicate_test)s)
14814039Sstacze01@arm.com        {
14914039Sstacze01@arm.com            // ARM instructions will not have a pkt if the predicate is false
15014039Sstacze01@arm.com            uint64_t memData = pkt->get<typeof(Mem)>();
15114039Sstacze01@arm.com
15214039Sstacze01@arm.com            %(postacc_code)s;
15314039Sstacze01@arm.com
15414039Sstacze01@arm.com            if (fault == NoFault) {
15514039Sstacze01@arm.com                %(op_wb)s;
15614039Sstacze01@arm.com            }
15714039Sstacze01@arm.com        }
15814039Sstacze01@arm.com
15914039Sstacze01@arm.com        return fault;
16014039Sstacze01@arm.com    }
16114039Sstacze01@arm.com}};
16214039Sstacze01@arm.com
16314039Sstacze01@arm.comdef template LoadExecute {{
16414039Sstacze01@arm.com    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
16514039Sstacze01@arm.com                                  Trace::InstRecord *traceData) const
16614039Sstacze01@arm.com    {
16714039Sstacze01@arm.com        Addr EA;
16814039Sstacze01@arm.com        Fault fault = NoFault;
16914039Sstacze01@arm.com
17014039Sstacze01@arm.com        %(op_decl)s;
17114039Sstacze01@arm.com        %(op_rd)s;
17214039Sstacze01@arm.com        %(ea_code)s;
17314039Sstacze01@arm.com
17414039Sstacze01@arm.com        if (%(predicate_test)s)
17514039Sstacze01@arm.com        {
17614039Sstacze01@arm.com            if (fault == NoFault) {
17714039Sstacze01@arm.com                fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
17814039Sstacze01@arm.com                %(memacc_code)s;
17914039Sstacze01@arm.com            }
18014039Sstacze01@arm.com
18114039Sstacze01@arm.com            if (fault == NoFault) {
18214039Sstacze01@arm.com                %(op_wb)s;
18314039Sstacze01@arm.com            }
18414039Sstacze01@arm.com        } else {
18514039Sstacze01@arm.com            xc->setPredicate(false);
18614039Sstacze01@arm.com        }
18714039Sstacze01@arm.com
18814039Sstacze01@arm.com        return fault;
18914039Sstacze01@arm.com    }
19014039Sstacze01@arm.com}};
19114039Sstacze01@arm.com
19214039Sstacze01@arm.comdef template NeonLoadExecute {{
19314039Sstacze01@arm.com    template <class Element>
19414039Sstacze01@arm.com    Fault %(class_name)s<Element>::execute(
19514039Sstacze01@arm.com            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
19614039Sstacze01@arm.com    {
19714039Sstacze01@arm.com        Addr EA;
19814039Sstacze01@arm.com        Fault fault = NoFault;
19914039Sstacze01@arm.com
20014039Sstacze01@arm.com        %(op_decl)s;
20114039Sstacze01@arm.com        %(mem_decl)s;
20214039Sstacze01@arm.com        %(op_rd)s;
20314039Sstacze01@arm.com        %(ea_code)s;
20414039Sstacze01@arm.com
20514039Sstacze01@arm.com        MemUnion memUnion;
20614039Sstacze01@arm.com        uint8_t *dataPtr = memUnion.bytes;
20714039Sstacze01@arm.com
20814039Sstacze01@arm.com        if (%(predicate_test)s)
20914039Sstacze01@arm.com        {
210            if (fault == NoFault) {
211                fault = xc->readBytes(EA, dataPtr, %(size)d, memAccessFlags);
212                %(memacc_code)s;
213            }
214
215            if (fault == NoFault) {
216                %(op_wb)s;
217            }
218        } else {
219            xc->setPredicate(false);
220        }
221
222        return fault;
223    }
224}};
225
226def template StoreExecute {{
227    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
228                                  Trace::InstRecord *traceData) const
229    {
230        Addr EA;
231        Fault fault = NoFault;
232
233        %(op_decl)s;
234        %(op_rd)s;
235        %(ea_code)s;
236
237        if (%(predicate_test)s)
238        {
239            if (fault == NoFault) {
240                %(memacc_code)s;
241            }
242
243            if (fault == NoFault) {
244                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
245                                  memAccessFlags, NULL);
246            }
247
248            if (fault == NoFault) {
249                %(op_wb)s;
250            }
251        } else {
252            xc->setPredicate(false);
253        }
254
255        return fault;
256    }
257}};
258
259def template NeonStoreExecute {{
260    template <class Element>
261    Fault %(class_name)s<Element>::execute(
262            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
263    {
264        Addr EA;
265        Fault fault = NoFault;
266
267        %(op_decl)s;
268        %(mem_decl)s;
269        %(op_rd)s;
270        %(ea_code)s;
271
272        MemUnion memUnion;
273        uint8_t *dataPtr = memUnion.bytes;
274
275        if (%(predicate_test)s)
276        {
277            if (fault == NoFault) {
278                %(memacc_code)s;
279            }
280
281            if (fault == NoFault) {
282                fault = xc->writeBytes(dataPtr, %(size)d, EA,
283                                       memAccessFlags, NULL);
284            }
285
286            if (fault == NoFault) {
287                %(op_wb)s;
288            }
289        } else {
290            xc->setPredicate(false);
291        }
292
293        return fault;
294    }
295}};
296
297def template StoreExExecute {{
298    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
299                                  Trace::InstRecord *traceData) const
300    {
301        Addr EA;
302        Fault fault = NoFault;
303
304        %(op_decl)s;
305        %(op_rd)s;
306        %(ea_code)s;
307
308        if (%(predicate_test)s)
309        {
310            if (fault == NoFault) {
311                %(memacc_code)s;
312            }
313
314            uint64_t writeResult;
315
316            if (fault == NoFault) {
317                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
318                                  memAccessFlags, &writeResult);
319            }
320
321            if (fault == NoFault) {
322                %(postacc_code)s;
323            }
324
325            if (fault == NoFault) {
326                %(op_wb)s;
327            }
328        } else {
329            xc->setPredicate(false);
330        }
331
332        return fault;
333    }
334}};
335
336def template StoreExInitiateAcc {{
337    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
338                                      Trace::InstRecord *traceData) const
339    {
340        Addr EA;
341        Fault fault = NoFault;
342
343        %(op_decl)s;
344        %(op_rd)s;
345        %(ea_code)s;
346
347        if (%(predicate_test)s)
348        {
349            if (fault == NoFault) {
350                %(memacc_code)s;
351            }
352
353            if (fault == NoFault) {
354                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
355                                  memAccessFlags, NULL);
356            }
357        } else {
358            xc->setPredicate(false);
359        }
360
361        return fault;
362    }
363}};
364
365def template StoreInitiateAcc {{
366    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
367                                      Trace::InstRecord *traceData) const
368    {
369        Addr EA;
370        Fault fault = NoFault;
371
372        %(op_decl)s;
373        %(op_rd)s;
374        %(ea_code)s;
375
376        if (%(predicate_test)s)
377        {
378            if (fault == NoFault) {
379                %(memacc_code)s;
380            }
381
382            if (fault == NoFault) {
383                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
384                                  memAccessFlags, NULL);
385            }
386        } else {
387            xc->setPredicate(false);
388        }
389
390        return fault;
391    }
392}};
393
394def template NeonStoreInitiateAcc {{
395    template <class Element>
396    Fault %(class_name)s<Element>::initiateAcc(
397            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
398    {
399        Addr EA;
400        Fault fault = NoFault;
401
402        %(op_decl)s;
403        %(mem_decl)s;
404        %(op_rd)s;
405        %(ea_code)s;
406
407        if (%(predicate_test)s)
408        {
409            MemUnion memUnion;
410            if (fault == NoFault) {
411                %(memacc_code)s;
412            }
413
414            if (fault == NoFault) {
415                fault = xc->writeBytes(memUnion.bytes, %(size)d, EA,
416                                       memAccessFlags, NULL);
417            }
418        } else {
419            xc->setPredicate(false);
420        }
421
422        return fault;
423    }
424}};
425
426def template LoadInitiateAcc {{
427    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
428                                      Trace::InstRecord *traceData) const
429    {
430        Addr EA;
431        Fault fault = NoFault;
432
433        %(op_src_decl)s;
434        %(op_rd)s;
435        %(ea_code)s;
436
437        if (%(predicate_test)s)
438        {
439            if (fault == NoFault) {
440                fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
441            }
442        } else {
443            xc->setPredicate(false);
444        }
445
446        return fault;
447    }
448}};
449
450def template NeonLoadInitiateAcc {{
451    template <class Element>
452    Fault %(class_name)s<Element>::initiateAcc(
453            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
454    {
455        Addr EA;
456        Fault fault = NoFault;
457
458        %(op_decl)s;
459        %(mem_decl)s;
460        %(op_rd)s;
461        %(ea_code)s;
462
463        MemUnion memUnion;
464        uint8_t *dataPtr = memUnion.bytes;
465
466        if (%(predicate_test)s)
467        {
468            if (fault == NoFault) {
469                fault = xc->readBytes(EA, dataPtr, %(size)d, memAccessFlags);
470            }
471        } else {
472            xc->setPredicate(false);
473        }
474
475        return fault;
476    }
477}};
478
479def template LoadCompleteAcc {{
480    Fault %(class_name)s::completeAcc(PacketPtr pkt,
481                                      %(CPU_exec_context)s *xc,
482                                      Trace::InstRecord *traceData) const
483    {
484        Fault fault = NoFault;
485
486        %(op_decl)s;
487        %(op_rd)s;
488
489        if (%(predicate_test)s)
490        {
491            // ARM instructions will not have a pkt if the predicate is false
492            Mem = pkt->get<typeof(Mem)>();
493
494            if (fault == NoFault) {
495                %(memacc_code)s;
496            }
497
498            if (fault == NoFault) {
499                %(op_wb)s;
500            }
501        }
502
503        return fault;
504    }
505}};
506
507def template NeonLoadCompleteAcc {{
508    template <class Element>
509    Fault %(class_name)s<Element>::completeAcc(
510            PacketPtr pkt, %(CPU_exec_context)s *xc,
511            Trace::InstRecord *traceData) const
512    {
513        Fault fault = NoFault;
514
515        %(mem_decl)s;
516        %(op_decl)s;
517        %(op_rd)s;
518
519        if (%(predicate_test)s)
520        {
521            // ARM instructions will not have a pkt if the predicate is false
522            MemUnion &memUnion = *(MemUnion *)pkt->getPtr<uint8_t>();
523
524            if (fault == NoFault) {
525                %(memacc_code)s;
526            }
527
528            if (fault == NoFault) {
529                %(op_wb)s;
530            }
531        }
532
533        return fault;
534    }
535}};
536
537def template StoreCompleteAcc {{
538    Fault %(class_name)s::completeAcc(PacketPtr pkt,
539                                      %(CPU_exec_context)s *xc,
540                                      Trace::InstRecord *traceData) const
541    {
542        return NoFault;
543    }
544}};
545
546def template NeonStoreCompleteAcc {{
547    template <class Element>
548    Fault %(class_name)s<Element>::completeAcc(
549            PacketPtr pkt, %(CPU_exec_context)s *xc,
550            Trace::InstRecord *traceData) const
551    {
552        return NoFault;
553    }
554}};
555
556def template StoreExCompleteAcc {{
557    Fault %(class_name)s::completeAcc(PacketPtr pkt,
558                                      %(CPU_exec_context)s *xc,
559                                      Trace::InstRecord *traceData) const
560    {
561        Fault fault = NoFault;
562
563        %(op_decl)s;
564        %(op_rd)s;
565
566        if (%(predicate_test)s)
567        {
568            uint64_t writeResult = pkt->req->getExtraData();
569            %(postacc_code)s;
570
571            if (fault == NoFault) {
572                %(op_wb)s;
573            }
574        }
575
576        return fault;
577    }
578}};
579
580def template RfeDeclare {{
581    /**
582     * Static instruction class for "%(mnemonic)s".
583     */
584    class %(class_name)s : public %(base_class)s
585    {
586      public:
587
588        /// Constructor.
589        %(class_name)s(ExtMachInst machInst,
590                uint32_t _base, int _mode, bool _wb);
591
592        %(BasicExecDeclare)s
593
594        %(InitiateAccDeclare)s
595
596        %(CompleteAccDeclare)s
597    };
598}};
599
600def template SrsDeclare {{
601    /**
602     * Static instruction class for "%(mnemonic)s".
603     */
604    class %(class_name)s : public %(base_class)s
605    {
606      public:
607
608        /// Constructor.
609        %(class_name)s(ExtMachInst machInst,
610                uint32_t _regMode, int _mode, bool _wb);
611
612        %(BasicExecDeclare)s
613
614        %(InitiateAccDeclare)s
615
616        %(CompleteAccDeclare)s
617    };
618}};
619
620def template SwapDeclare {{
621    /**
622     * Static instruction class for "%(mnemonic)s".
623     */
624    class %(class_name)s : public %(base_class)s
625    {
626      public:
627
628        /// Constructor.
629        %(class_name)s(ExtMachInst machInst,
630                uint32_t _dest, uint32_t _op1, uint32_t _base);
631
632        %(BasicExecDeclare)s
633
634        %(InitiateAccDeclare)s
635
636        %(CompleteAccDeclare)s
637    };
638}};
639
640def template LoadStoreDImmDeclare {{
641    /**
642     * Static instruction class for "%(mnemonic)s".
643     */
644    class %(class_name)s : public %(base_class)s
645    {
646      public:
647
648        /// Constructor.
649        %(class_name)s(ExtMachInst machInst,
650                uint32_t _dest, uint32_t _dest2,
651                uint32_t _base, bool _add, int32_t _imm);
652
653        %(BasicExecDeclare)s
654
655        %(InitiateAccDeclare)s
656
657        %(CompleteAccDeclare)s
658    };
659}};
660
661def template StoreExDImmDeclare {{
662    /**
663     * Static instruction class for "%(mnemonic)s".
664     */
665    class %(class_name)s : public %(base_class)s
666    {
667      public:
668
669        /// Constructor.
670        %(class_name)s(ExtMachInst machInst,
671                uint32_t _result, uint32_t _dest, uint32_t _dest2,
672                uint32_t _base, bool _add, int32_t _imm);
673
674        %(BasicExecDeclare)s
675
676        %(InitiateAccDeclare)s
677
678        %(CompleteAccDeclare)s
679    };
680}};
681
682def template LoadStoreImmDeclare {{
683    /**
684     * Static instruction class for "%(mnemonic)s".
685     */
686    class %(class_name)s : public %(base_class)s
687    {
688      public:
689
690        /// Constructor.
691        %(class_name)s(ExtMachInst machInst,
692                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
693
694        %(BasicExecDeclare)s
695
696        %(InitiateAccDeclare)s
697
698        %(CompleteAccDeclare)s
699    };
700}};
701
702def template StoreExImmDeclare {{
703    /**
704     * Static instruction class for "%(mnemonic)s".
705     */
706    class %(class_name)s : public %(base_class)s
707    {
708      public:
709
710        /// Constructor.
711        %(class_name)s(ExtMachInst machInst,
712                uint32_t _result, uint32_t _dest, uint32_t _base,
713                bool _add, int32_t _imm);
714
715        %(BasicExecDeclare)s
716
717        %(InitiateAccDeclare)s
718
719        %(CompleteAccDeclare)s
720    };
721}};
722
723def template StoreDRegDeclare {{
724    /**
725     * Static instruction class for "%(mnemonic)s".
726     */
727    class %(class_name)s : public %(base_class)s
728    {
729      public:
730
731        /// Constructor.
732        %(class_name)s(ExtMachInst machInst,
733                uint32_t _dest, uint32_t _dest2,
734                uint32_t _base, bool _add,
735                int32_t _shiftAmt, uint32_t _shiftType,
736                uint32_t _index);
737
738        %(BasicExecDeclare)s
739
740        %(InitiateAccDeclare)s
741
742        %(CompleteAccDeclare)s
743    };
744}};
745
746def template StoreRegDeclare {{
747    /**
748     * Static instruction class for "%(mnemonic)s".
749     */
750    class %(class_name)s : public %(base_class)s
751    {
752      public:
753
754        /// Constructor.
755        %(class_name)s(ExtMachInst machInst,
756                uint32_t _dest, uint32_t _base, bool _add,
757                int32_t _shiftAmt, uint32_t _shiftType,
758                uint32_t _index);
759
760        %(BasicExecDeclare)s
761
762        %(InitiateAccDeclare)s
763
764        %(CompleteAccDeclare)s
765    };
766}};
767
768def template LoadDRegDeclare {{
769    /**
770     * Static instruction class for "%(mnemonic)s".
771     */
772    class %(class_name)s : public %(base_class)s
773    {
774      public:
775
776        /// Constructor.
777        %(class_name)s(ExtMachInst machInst,
778                uint32_t _dest, uint32_t _dest2,
779                uint32_t _base, bool _add,
780                int32_t _shiftAmt, uint32_t _shiftType,
781                uint32_t _index);
782
783        %(BasicExecDeclare)s
784
785        %(InitiateAccDeclare)s
786
787        %(CompleteAccDeclare)s
788    };
789}};
790
791def template LoadRegDeclare {{
792    /**
793     * Static instruction class for "%(mnemonic)s".
794     */
795    class %(class_name)s : public %(base_class)s
796    {
797      public:
798
799        /// Constructor.
800        %(class_name)s(ExtMachInst machInst,
801                uint32_t _dest, uint32_t _base, bool _add,
802                int32_t _shiftAmt, uint32_t _shiftType,
803                uint32_t _index);
804
805        %(BasicExecDeclare)s
806
807        %(InitiateAccDeclare)s
808
809        %(CompleteAccDeclare)s
810    };
811}};
812
813def template LoadImmDeclare {{
814    /**
815     * Static instruction class for "%(mnemonic)s".
816     */
817    class %(class_name)s : public %(base_class)s
818    {
819      public:
820
821        /// Constructor.
822        %(class_name)s(ExtMachInst machInst,
823                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
824
825        %(BasicExecDeclare)s
826
827        %(InitiateAccDeclare)s
828
829        %(CompleteAccDeclare)s
830    };
831}};
832
833def template InitiateAccDeclare {{
834    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
835}};
836
837def template CompleteAccDeclare {{
838    Fault completeAcc(PacketPtr,  %(CPU_exec_context)s *, Trace::InstRecord *) const;
839}};
840
841def template RfeConstructor {{
842    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
843                                          uint32_t _base, int _mode, bool _wb)
844        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
845                         (IntRegIndex)_base, (AddrMode)_mode, _wb)
846    {
847        %(constructor)s;
848        if (!(condCode == COND_AL || condCode == COND_UC)) {
849            for (int x = 0; x < _numDestRegs; x++) {
850                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
851            }
852        }
853#if %(use_uops)d
854        uops = new StaticInstPtr[1 + %(use_wb)d + %(use_pc)d];
855        int uopIdx = 0;
856        uops[uopIdx] = new %(acc_name)s(machInst, _base, _mode, _wb);
857        uops[uopIdx]->setDelayedCommit();
858#if %(use_wb)d
859        uops[++uopIdx] = new %(wb_decl)s;
860        uops[uopIdx]->setDelayedCommit();
861#endif
862#if %(use_pc)d
863        uops[++uopIdx] = new %(pc_decl)s;
864#endif
865        uops[uopIdx]->setLastMicroop();
866#endif
867    }
868}};
869
870def template SrsConstructor {{
871    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
872            uint32_t _regMode, int _mode, bool _wb)
873         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
874                 (OperatingMode)_regMode, (AddrMode)_mode, _wb)
875    {
876        %(constructor)s;
877        if (!(condCode == COND_AL || condCode == COND_UC)) {
878            for (int x = 0; x < _numDestRegs; x++) {
879                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
880            }
881        }
882#if %(use_uops)d
883        assert(numMicroops >= 2);
884        uops = new StaticInstPtr[numMicroops];
885        uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb);
886        uops[0]->setDelayedCommit();
887        uops[1] = new %(wb_decl)s;
888        uops[1]->setLastMicroop();
889#endif
890    }
891}};
892
893def template SwapConstructor {{
894    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
895            uint32_t _dest, uint32_t _op1, uint32_t _base)
896         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
897                 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
898    {
899        %(constructor)s;
900        if (!(condCode == COND_AL || condCode == COND_UC)) {
901            for (int x = 0; x < _numDestRegs; x++) {
902                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
903            }
904        }
905    }
906}};
907
908def template LoadStoreDImmConstructor {{
909    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
910            uint32_t _dest, uint32_t _dest2,
911            uint32_t _base, bool _add, int32_t _imm)
912         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
913                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
914                 (IntRegIndex)_base, _add, _imm)
915    {
916        %(constructor)s;
917        if (!(condCode == COND_AL || condCode == COND_UC)) {
918            for (int x = 0; x < _numDestRegs; x++) {
919                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
920            }
921        }
922#if %(use_uops)d
923        assert(numMicroops >= 2);
924        uops = new StaticInstPtr[numMicroops];
925        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm);
926        uops[0]->setDelayedCommit();
927        uops[1] = new %(wb_decl)s;
928        uops[1]->setLastMicroop();
929#endif
930    }
931}};
932
933def template StoreExDImmConstructor {{
934    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
935            uint32_t _result, uint32_t _dest, uint32_t _dest2,
936            uint32_t _base, bool _add, int32_t _imm)
937         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
938                 (IntRegIndex)_result,
939                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
940                 (IntRegIndex)_base, _add, _imm)
941    {
942        %(constructor)s;
943        if (!(condCode == COND_AL || condCode == COND_UC)) {
944            for (int x = 0; x < _numDestRegs; x++) {
945                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
946            }
947        }
948#if %(use_uops)d
949        assert(numMicroops >= 2);
950        uops = new StaticInstPtr[numMicroops];
951        uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2,
952                                   _base, _add, _imm);
953        uops[0]->setDelayedCommit();
954        uops[1] = new %(wb_decl)s;
955        uops[1]->setLastMicroop();
956#endif
957    }
958}};
959
960def template LoadStoreImmConstructor {{
961    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
962            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
963         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
964                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
965    {
966        %(constructor)s;
967        if (!(condCode == COND_AL || condCode == COND_UC)) {
968            for (int x = 0; x < _numDestRegs; x++) {
969                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
970            }
971        }
972#if %(use_uops)d
973        assert(numMicroops >= 2);
974        uops = new StaticInstPtr[numMicroops];
975        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
976        uops[0]->setDelayedCommit();
977        uops[1] = new %(wb_decl)s;
978        uops[1]->setLastMicroop();
979#endif
980    }
981}};
982
983def template StoreExImmConstructor {{
984    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
985            uint32_t _result, uint32_t _dest, uint32_t _base,
986            bool _add, int32_t _imm)
987         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
988                 (IntRegIndex)_result, (IntRegIndex)_dest,
989                 (IntRegIndex)_base, _add, _imm)
990    {
991        %(constructor)s;
992        if (!(condCode == COND_AL || condCode == COND_UC)) {
993            for (int x = 0; x < _numDestRegs; x++) {
994                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
995            }
996        }
997#if %(use_uops)d
998        assert(numMicroops >= 2);
999        uops = new StaticInstPtr[numMicroops];
1000        uops[0] = new %(acc_name)s(machInst, _result, _dest,
1001                                   _base, _add, _imm);
1002        uops[0]->setDelayedCommit();
1003        uops[1] = new %(wb_decl)s;
1004        uops[1]->setLastMicroop();
1005#endif
1006    }
1007}};
1008
1009def template StoreDRegConstructor {{
1010    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1011            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1012            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1013         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1014                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1015                 (IntRegIndex)_base, _add,
1016                 _shiftAmt, (ArmShiftType)_shiftType,
1017                 (IntRegIndex)_index)
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, _dest, _dest2, _base, _add,
1029                                   _shiftAmt, _shiftType, _index);
1030        uops[0]->setDelayedCommit();
1031        uops[1] = new %(wb_decl)s;
1032        uops[1]->setLastMicroop();
1033#endif
1034    }
1035}};
1036
1037def template StoreRegConstructor {{
1038    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1039            uint32_t _dest, uint32_t _base, bool _add,
1040            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1041         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1042                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1043                 _shiftAmt, (ArmShiftType)_shiftType,
1044                 (IntRegIndex)_index)
1045    {
1046        %(constructor)s;
1047        if (!(condCode == COND_AL || condCode == COND_UC)) {
1048            for (int x = 0; x < _numDestRegs; x++) {
1049                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1050            }
1051        }
1052#if %(use_uops)d
1053        assert(numMicroops >= 2);
1054        uops = new StaticInstPtr[numMicroops];
1055        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1056                                   _shiftAmt, _shiftType, _index);
1057        uops[0]->setDelayedCommit();
1058        uops[1] = new %(wb_decl)s;
1059        uops[1]->setLastMicroop();
1060#endif
1061    }
1062}};
1063
1064def template LoadDRegConstructor {{
1065    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1066            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1067            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1068         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1069                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1070                 (IntRegIndex)_base, _add,
1071                 _shiftAmt, (ArmShiftType)_shiftType,
1072                 (IntRegIndex)_index)
1073    {
1074        %(constructor)s;
1075        if (!(condCode == COND_AL || condCode == COND_UC)) {
1076            for (int x = 0; x < _numDestRegs; x++) {
1077                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1078            }
1079        }
1080#if %(use_uops)d
1081        assert(numMicroops >= 2);
1082        uops = new StaticInstPtr[numMicroops];
1083        if ((_dest == _index) || (_dest2 == _index)) {
1084            IntRegIndex wbIndexReg = INTREG_UREG0;
1085            uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1086            uops[0]->setDelayedCommit();
1087            uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1088                                       _shiftAmt, _shiftType, _index);
1089            uops[1]->setDelayedCommit();
1090            uops[2] = new %(wb_decl)s;
1091            uops[2]->setLastMicroop();
1092        } else {
1093            IntRegIndex wbIndexReg = index;
1094            uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1095                                       _shiftAmt, _shiftType, _index);
1096            uops[0]->setDelayedCommit();
1097            uops[1] = new %(wb_decl)s;
1098            uops[1]->setLastMicroop();
1099        }
1100#endif
1101    }
1102}};
1103
1104def template LoadRegConstructor {{
1105    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1106            uint32_t _dest, uint32_t _base, bool _add,
1107            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1108         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1109                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1110                 _shiftAmt, (ArmShiftType)_shiftType,
1111                 (IntRegIndex)_index)
1112    {
1113        %(constructor)s;
1114        bool conditional = false;
1115        if (!(condCode == COND_AL || condCode == COND_UC)) {
1116            conditional = true;
1117            for (int x = 0; x < _numDestRegs; x++) {
1118                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1119            }
1120        }
1121#if %(use_uops)d
1122        assert(numMicroops >= 2);
1123        uops = new StaticInstPtr[numMicroops];
1124        if (_dest == INTREG_PC) {
1125            IntRegIndex wbIndexReg = index;
1126            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1127                                       _shiftAmt, _shiftType, _index);
1128            uops[0]->setDelayedCommit();
1129            uops[1] = new %(wb_decl)s;
1130            uops[1]->setDelayedCommit();
1131            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1132            uops[2]->setFlag(StaticInst::IsControl);
1133            uops[2]->setFlag(StaticInst::IsIndirectControl);
1134            if (conditional)
1135                uops[2]->setFlag(StaticInst::IsCondControl);
1136            else
1137                uops[2]->setFlag(StaticInst::IsUncondControl);
1138            uops[2]->setLastMicroop();
1139        } else if(_dest == _index) {
1140            IntRegIndex wbIndexReg = INTREG_UREG0;
1141            uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1142            uops[0]->setDelayedCommit();
1143            uops[1] = new %(acc_name)s(machInst, _dest, _base, _add,
1144                                      _shiftAmt, _shiftType, _index);
1145            uops[1]->setDelayedCommit();
1146            uops[2] = new %(wb_decl)s;
1147            uops[2]->setLastMicroop();
1148        } else {
1149            IntRegIndex wbIndexReg = index;
1150            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1151                                      _shiftAmt, _shiftType, _index);
1152            uops[0]->setDelayedCommit();
1153            uops[1] = new %(wb_decl)s;
1154            uops[1]->setLastMicroop();
1155
1156        }
1157#endif
1158    }
1159}};
1160
1161def template LoadImmConstructor {{
1162    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1163            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
1164         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1165                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
1166    {
1167        %(constructor)s;
1168        bool conditional = false;
1169        if (!(condCode == COND_AL || condCode == COND_UC)) {
1170            conditional = true;
1171            for (int x = 0; x < _numDestRegs; x++) {
1172                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1173            }
1174        }
1175#if %(use_uops)d
1176        assert(numMicroops >= 2);
1177        uops = new StaticInstPtr[numMicroops];
1178        if (_dest == INTREG_PC) {
1179            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1180                                   _imm);
1181            uops[0]->setDelayedCommit();
1182            uops[1] = new %(wb_decl)s;
1183            uops[1]->setDelayedCommit();
1184            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1185            uops[2]->setFlag(StaticInst::IsControl);
1186            uops[2]->setFlag(StaticInst::IsIndirectControl);
1187            if (conditional)
1188                uops[2]->setFlag(StaticInst::IsCondControl);
1189            else
1190                uops[2]->setFlag(StaticInst::IsUncondControl);
1191            if (_base == INTREG_SP && _add && _imm == 4 && %(is_ras_pop)s)
1192                uops[2]->setFlag(StaticInst::IsReturn);
1193            uops[2]->setLastMicroop();
1194        } else {
1195            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
1196            uops[0]->setDelayedCommit();
1197            uops[1] = new %(wb_decl)s;
1198            uops[1]->setLastMicroop();
1199        }
1200#endif
1201    }
1202}};
1203
1204