1// -*- mode:c++ -*-
2
3// Copyright (c) 2010-2014 ARM Limited
4// All rights reserved
5//
6// The license below extends only to copyright in the software and shall
7// not be construed as granting a license to any other intellectual
8// property including but not limited to intellectual property relating
9// to a hardware implementation of the functionality of the software
10// licensed hereunder.  You may use the software subject to the license
11// terms below provided that you ensure that this notice is replicated
12// unmodified and in its entirety in all distributions of the software,
13// modified or unmodified, in source code or in binary form.
14//
15// Copyright (c) 2007-2008 The Florida State University
16// All rights reserved.
17//
18// Redistribution and use in source and binary forms, with or without
19// modification, are permitted provided that the following conditions are
20// met: redistributions of source code must retain the above copyright
21// notice, this list of conditions and the following disclaimer;
22// redistributions in binary form must reproduce the above copyright
23// notice, this list of conditions and the following disclaimer in the
24// documentation and/or other materials provided with the distribution;
25// neither the name of the copyright holders nor the names of its
26// contributors may be used to endorse or promote products derived from
27// this software without specific prior written permission.
28//
29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40//
41// Authors: Stephen Hines
42//          Gabe Black
43
44////////////////////////////////////////////////////////////////////
45//
46// Load/store microops
47//
48
49def template MicroMemDeclare {{
50    class %(class_name)s : public %(base_class)s
51    {
52      public:
53        %(class_name)s(ExtMachInst machInst,
54                       RegIndex _ura, RegIndex _urb, bool _up,
55                       uint8_t _imm);
56        Fault execute(ExecContext *, Trace::InstRecord *) const override;
57        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
58        Fault completeAcc(PacketPtr, ExecContext *,
59                          Trace::InstRecord *) const override;
60    };
61}};
62
63def template MicroMemConstructor {{
64    %(class_name)s::%(class_name)s(ExtMachInst machInst,
65                                   RegIndex _ura,
66                                   RegIndex _urb,
67                                   bool _up,
68                                   uint8_t _imm)
69        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
70                         _ura, _urb, _up, _imm)
71    {
72        %(constructor)s;
73        if (!(condCode == COND_AL || condCode == COND_UC)) {
74            for (int x = 0; x < _numDestRegs; x++) {
75                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
76            }
77        }
78    }
79}};
80
81
82def template MicroMemPairDeclare {{
83    class %(class_name)s : public %(base_class)s
84    {
85      public:
86        %(class_name)s(ExtMachInst machInst,
87                       RegIndex _dreg1, RegIndex _dreg2, RegIndex _base,
88                       bool _up, uint8_t _imm);
89        Fault execute(ExecContext *, Trace::InstRecord *) const override;
90        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
91        Fault completeAcc(PacketPtr, ExecContext *,
92                          Trace::InstRecord *) const override;
93    };
94}};
95
96def template MicroMemPairConstructor {{
97    %(class_name)s::%(class_name)s(ExtMachInst machInst,
98                                   RegIndex _dreg1,
99                                   RegIndex _dreg2,
100                                   RegIndex _base,
101                                   bool _up,
102                                   uint8_t _imm)
103        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
104                         _dreg1, _dreg2, _base, _up, _imm)
105    {
106        %(constructor)s;
107        if (!(condCode == COND_AL || condCode == COND_UC)) {
108            for (int x = 0; x < _numDestRegs; x++) {
109                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
110            }
111        }
112    }
113}};
114
115////////////////////////////////////////////////////////////////////
116//
117// Neon load/store microops
118//
119
120def template MicroNeonMemDeclare {{
121    template <class Element>
122    class %(class_name)s : public %(base_class)s
123    {
124      public:
125        %(class_name)s(ExtMachInst machInst, RegIndex _dest,
126                       RegIndex _ura, uint32_t _imm, unsigned extraMemFlags)
127            : %(base_class)s("%(mnemonic)s", machInst,
128                              %(op_class)s, _dest, _ura, _imm)
129        {
130            memAccessFlags |= extraMemFlags;
131            %(constructor)s;
132            if (!(condCode == COND_AL || condCode == COND_UC)) {
133                for (int x = 0; x < _numDestRegs; x++) {
134                    _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
135                }
136            }
137        }
138
139        Fault execute(ExecContext *, Trace::InstRecord *) const override;
140        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
141        Fault completeAcc(PacketPtr, ExecContext *,
142                          Trace::InstRecord *) const override;
143    };
144}};
145
146////////////////////////////////////////////////////////////////////
147//
148// PC   = Integer(ura)
149// CPSR = Integer(urb)
150//
151
152def template MicroSetPCCPSRDeclare {{
153    class %(class_name)s : public %(base_class)s
154    {
155      public:
156        %(class_name)s(ExtMachInst machInst,
157                       IntRegIndex _ura,
158                       IntRegIndex _urb,
159                       IntRegIndex _urc);
160        Fault execute(ExecContext *, Trace::InstRecord *) const override;
161    };
162}};
163
164def template MicroSetPCCPSRConstructor {{
165    %(class_name)s::%(class_name)s(ExtMachInst machInst,
166                                   IntRegIndex _ura,
167                                   IntRegIndex _urb,
168                                   IntRegIndex _urc)
169          : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
170                           _ura, _urb, _urc)
171    {
172        %(constructor)s;
173        if (!(condCode == COND_AL || condCode == COND_UC)) {
174            flags[IsCondControl] = true;
175            for (int x = 0; x < _numDestRegs; x++) {
176                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
177            }
178        } else {
179            flags[IsUncondControl] = true;
180        }
181    }
182}};
183
184////////////////////////////////////////////////////////////////////
185//
186// Integer = Integer op Integer microops
187//
188
189def template MicroIntDeclare {{
190    class %(class_name)s : public %(base_class)s
191    {
192      public:
193        %(class_name)s(ExtMachInst machInst,
194                       RegIndex _ura, RegIndex _urb, RegIndex _urc);
195        Fault execute(ExecContext *, Trace::InstRecord *) const override;
196    };
197}};
198
199def template MicroIntConstructor {{
200    %(class_name)s::%(class_name)s(ExtMachInst machInst,
201                                   RegIndex _ura,
202                                   RegIndex _urb,
203                                   RegIndex _urc)
204        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
205                         _ura, _urb, _urc)
206    {
207        %(constructor)s;
208        if (!(condCode == COND_AL || condCode == COND_UC)) {
209            for (int x = 0; x < _numDestRegs; x++) {
210                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
211            }
212        }
213    }
214}};
215
216def template MicroNeonMemExecDeclare {{
217    template
218    Fault %(class_name)s<%(targs)s>::execute(
219            ExecContext *, Trace::InstRecord *) const;
220    template
221    Fault %(class_name)s<%(targs)s>::initiateAcc(
222            ExecContext *, Trace::InstRecord *) const;
223    template
224    Fault %(class_name)s<%(targs)s>::completeAcc(PacketPtr,
225            ExecContext *, Trace::InstRecord *) const;
226}};
227
228def template MicroNeonExecDeclare {{
229    template
230    Fault %(class_name)s<%(targs)s>::execute(
231            ExecContext *, Trace::InstRecord *) const;
232}};
233
234////////////////////////////////////////////////////////////////////
235//
236// Neon (de)interlacing microops
237//
238
239def template MicroNeonMixDeclare {{
240    template <class Element>
241    class %(class_name)s : public %(base_class)s
242    {
243      public:
244        %(class_name)s(ExtMachInst machInst, RegIndex _dest, RegIndex _op1,
245                       uint8_t _step) :
246            %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
247                           _dest, _op1, _step)
248        {
249            %(constructor)s;
250            if (!(condCode == COND_AL || condCode == COND_UC)) {
251                for (int x = 0; x < _numDestRegs; x++) {
252                    _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
253                }
254            }
255        }
256
257        Fault execute(ExecContext *, Trace::InstRecord *) const override;
258    };
259}};
260
261def template MicroNeonMixExecute {{
262    template <class Element>
263    Fault %(class_name)s<Element>::execute(ExecContext *xc,
264            Trace::InstRecord *traceData) const
265    {
266        Fault fault = NoFault;
267        uint64_t resTemp = 0;
268        resTemp = resTemp;
269        %(op_decl)s;
270        %(op_rd)s;
271
272        if (%(predicate_test)s)
273        {
274            %(code)s;
275            if (fault == NoFault)
276            {
277                %(op_wb)s;
278            }
279        } else {
280            xc->setPredicate(false);
281        }
282
283        return fault;
284    }
285}};
286
287////////////////////////////////////////////////////////////////////
288//
289// Neon (un)packing microops using a particular lane
290//
291
292def template MicroNeonMixLaneDeclare {{
293    template <class Element>
294    class %(class_name)s : public %(base_class)s
295    {
296      public:
297        %(class_name)s(ExtMachInst machInst, RegIndex _dest, RegIndex _op1,
298                       uint8_t _step, unsigned _lane) :
299            %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
300                           _dest, _op1, _step, _lane)
301        {
302            %(constructor)s;
303            if (!(condCode == COND_AL || condCode == COND_UC)) {
304                for (int x = 0; x < _numDestRegs; x++) {
305                    _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
306                }
307            }
308        }
309
310        Fault execute(ExecContext *, Trace::InstRecord *) const override;
311    };
312}};
313
314////////////////////////////////////////////////////////////////////
315//
316// Integer = Integer
317//
318
319def template MicroIntMovDeclare {{
320    class %(class_name)s : public %(base_class)s
321    {
322      public:
323        %(class_name)s(ExtMachInst machInst,
324                       RegIndex _ura, RegIndex _urb);
325        Fault execute(ExecContext *, Trace::InstRecord *) const override;
326    };
327}};
328def template MicroIntMovConstructor {{
329    %(class_name)s::%(class_name)s(ExtMachInst machInst,
330                                   RegIndex _ura,
331                                   RegIndex _urb)
332        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
333                         _ura, _urb)
334    {
335        %(constructor)s;
336        if (!(condCode == COND_AL || condCode == COND_UC)) {
337            for (int x = 0; x < _numDestRegs; x++) {
338                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
339            }
340        }
341    }
342}};
343
344////////////////////////////////////////////////////////////////////
345//
346// Integer = Integer op Immediate microops
347//
348
349def template MicroIntImmDeclare {{
350    class %(class_name)s : public %(base_class)s
351    {
352      public:
353        %(class_name)s(ExtMachInst machInst,
354                       RegIndex _ura, RegIndex _urb,
355                       int32_t _imm);
356        Fault execute(ExecContext *, Trace::InstRecord *) const override;
357    };
358}};
359
360def template MicroIntImmConstructor {{
361    %(class_name)s::%(class_name)s(ExtMachInst machInst,
362                                   RegIndex _ura,
363                                   RegIndex _urb,
364                                   int32_t _imm)
365        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
366                         _ura, _urb, _imm)
367    {
368        %(constructor)s;
369        if (!(condCode == COND_AL || condCode == COND_UC)) {
370            for (int x = 0; x < _numDestRegs; x++) {
371                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
372            }
373        }
374    }
375}};
376
377def template MicroIntImmXConstructor {{
378    %(class_name)s::%(class_name)s(ExtMachInst machInst,
379                                   RegIndex _ura,
380                                   RegIndex _urb,
381                                   int32_t _imm)
382        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
383                         _ura, _urb, _imm)
384    {
385        %(constructor)s;
386    }
387}};
388
389def template MicroIntRegDeclare {{
390    class %(class_name)s : public %(base_class)s
391    {
392      public:
393        %(class_name)s(ExtMachInst machInst,
394                       RegIndex _ura, RegIndex _urb, RegIndex _urc,
395                       int32_t _shiftAmt, ArmShiftType _shiftType);
396        Fault execute(ExecContext *, Trace::InstRecord *) const override;
397    };
398}};
399
400def template MicroIntXERegConstructor {{
401    %(class_name)s::%(class_name)s(ExtMachInst machInst,
402                                   RegIndex _ura, RegIndex _urb, RegIndex _urc,
403                                   ArmExtendType _type, uint32_t _shiftAmt)
404        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
405                         _ura, _urb, _urc, _type, _shiftAmt)
406    {
407        %(constructor)s;
408    }
409}};
410
411def template MicroIntXERegDeclare {{
412    class %(class_name)s : public %(base_class)s
413    {
414      public:
415        %(class_name)s(ExtMachInst machInst,
416                       RegIndex _ura, RegIndex _urb, RegIndex _urc,
417                       ArmExtendType _type, uint32_t _shiftAmt);
418        Fault execute(ExecContext *, Trace::InstRecord *) const override;
419    };
420}};
421
422def template MicroIntRegConstructor {{
423    %(class_name)s::%(class_name)s(ExtMachInst machInst,
424                                   RegIndex _ura, RegIndex _urb, RegIndex _urc,
425                                   int32_t _shiftAmt, ArmShiftType _shiftType)
426        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
427                         _ura, _urb, _urc, _shiftAmt, _shiftType)
428    {
429        %(constructor)s;
430        if (!(condCode == COND_AL || condCode == COND_UC)) {
431            for (int x = 0; x < _numDestRegs; x++) {
432                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
433            }
434        }
435    }
436}};
437
438////////////////////////////////////////////////////////////////////
439//
440// Macro Memory-format instructions
441//
442
443def template MacroMemDeclare {{
444/**
445 * Static instructions class for a store multiple instruction
446 */
447class %(class_name)s : public %(base_class)s
448{
449    public:
450        // Constructor
451        %(class_name)s(ExtMachInst machInst, IntRegIndex rn,
452                bool index, bool up, bool user, bool writeback, bool load,
453                uint32_t reglist);
454};
455}};
456
457def template MacroMemConstructor {{
458%(class_name)s::%(class_name)s(ExtMachInst machInst, IntRegIndex rn,
459        bool index, bool up, bool user, bool writeback, bool load,
460        uint32_t reglist)
461    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, rn,
462                     index, up, user, writeback, load, reglist)
463{
464    %(constructor)s;
465    if (!(condCode == COND_AL || condCode == COND_UC)) {
466        for (int x = 0; x < _numDestRegs; x++) {
467            _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
468        }
469    }
470}
471
472}};
473
474def template BigFpMemImmDeclare {{
475class %(class_name)s : public %(base_class)s
476{
477  public:
478    // Constructor
479    %(class_name)s(const char *mnemonic, ExtMachInst machInst,
480                   bool load, IntRegIndex dest, IntRegIndex base, int64_t imm);
481};
482}};
483
484def template BigFpMemImmConstructor {{
485%(class_name)s::%(class_name)s(const char *mnemonic, ExtMachInst machInst,
486        bool load, IntRegIndex dest, IntRegIndex base, int64_t imm)
487    : %(base_class)s(mnemonic, machInst, %(op_class)s, load, dest, base, imm)
488{
489    %(constructor)s;
490}
491}};
492
493def template BigFpMemRegDeclare {{
494class %(class_name)s : public %(base_class)s
495{
496  public:
497    // Constructor
498    %(class_name)s(const char *mnemonic, ExtMachInst machInst,
499                   bool load, IntRegIndex dest, IntRegIndex base,
500                   IntRegIndex offset, ArmExtendType type, int64_t imm);
501};
502}};
503
504def template BigFpMemRegConstructor {{
505%(class_name)s::%(class_name)s(const char *mnemonic, ExtMachInst machInst,
506        bool load, IntRegIndex dest, IntRegIndex base,
507        IntRegIndex offset, ArmExtendType type, int64_t imm)
508    : %(base_class)s(mnemonic, machInst, %(op_class)s, load, dest, base,
509                     offset, type, imm)
510{
511    %(constructor)s;
512}
513}};
514
515def template BigFpMemLitDeclare {{
516class %(class_name)s : public %(base_class)s
517{
518  public:
519    // Constructor
520    %(class_name)s(const char *mnemonic, ExtMachInst machInst,
521                   IntRegIndex dest, int64_t imm);
522};
523}};
524
525def template BigFpMemLitConstructor {{
526%(class_name)s::%(class_name)s(const char *mnemonic, ExtMachInst machInst,
527        IntRegIndex dest, int64_t imm)
528    : %(base_class)s(mnemonic, machInst, %(op_class)s, dest, imm)
529{
530    %(constructor)s;
531}
532}};
533
534def template PairMemDeclare {{
535class %(class_name)s : public %(base_class)s
536{
537    public:
538        // Constructor
539        %(class_name)s(const char *mnemonic, ExtMachInst machInst,
540                uint32_t size, bool fp, bool load, bool noAlloc, bool signExt,
541                bool exclusive, bool acrel, uint32_t imm,
542                AddrMode mode, IntRegIndex rn, IntRegIndex rt,
543                IntRegIndex rt2);
544};
545}};
546
547def template PairMemConstructor {{
548%(class_name)s::%(class_name)s(const char *mnemonic, ExtMachInst machInst,
549        uint32_t size, bool fp, bool load, bool noAlloc, bool signExt,
550        bool exclusive, bool acrel, uint32_t imm, AddrMode mode,
551        IntRegIndex rn, IntRegIndex rt, IntRegIndex rt2)
552    : %(base_class)s(mnemonic, machInst, %(op_class)s, size,
553                     fp, load, noAlloc, signExt, exclusive, acrel,
554                     imm, mode, rn, rt, rt2)
555{
556    %(constructor)s;
557}
558}};
559
560def template VMemMultDeclare {{
561class %(class_name)s : public %(base_class)s
562{
563    public:
564        // Constructor
565        %(class_name)s(ExtMachInst machInst, unsigned width,
566                RegIndex rn, RegIndex vd, unsigned regs, unsigned inc,
567                uint32_t size, uint32_t align, RegIndex rm);
568};
569}};
570
571def template VMemMultConstructor {{
572%(class_name)s::%(class_name)s(ExtMachInst machInst, unsigned width,
573        RegIndex rn, RegIndex vd, unsigned regs, unsigned inc,
574        uint32_t size, uint32_t align, RegIndex rm)
575    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, width,
576                     rn, vd, regs, inc, size, align, rm)
577{
578    %(constructor)s;
579    if (!(condCode == COND_AL || condCode == COND_UC)) {
580        for (int x = 0; x < _numDestRegs; x++) {
581            _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
582        }
583    }
584}
585}};
586
587def template VMemSingleDeclare {{
588class %(class_name)s : public %(base_class)s
589{
590    public:
591        // Constructor
592        %(class_name)s(ExtMachInst machInst, bool all, unsigned width,
593                RegIndex rn, RegIndex vd, unsigned regs, unsigned inc,
594                uint32_t size, uint32_t align, RegIndex rm, unsigned lane = 0);
595};
596}};
597
598def template VMemSingleConstructor {{
599%(class_name)s::%(class_name)s(ExtMachInst machInst, bool all, unsigned width,
600        RegIndex rn, RegIndex vd, unsigned regs, unsigned inc,
601        uint32_t size, uint32_t align, RegIndex rm, unsigned lane)
602    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, all, width,
603                     rn, vd, regs, inc, size, align, rm, lane)
604{
605    %(constructor)s;
606    if (!(condCode == COND_AL || condCode == COND_UC)) {
607        for (int x = 0; x < _numDestRegs; x++) {
608            _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
609        }
610    }
611}
612}};
613
614def template MacroVFPMemDeclare {{
615/**
616 * Static instructions class for a store multiple instruction
617 */
618class %(class_name)s : public %(base_class)s
619{
620    public:
621        // Constructor
622        %(class_name)s(ExtMachInst machInst, IntRegIndex rn,
623                RegIndex vd, bool single, bool up, bool writeback,
624                bool load, uint32_t offset);
625};
626}};
627
628def template MacroVFPMemConstructor {{
629%(class_name)s::%(class_name)s(ExtMachInst machInst, IntRegIndex rn,
630        RegIndex vd, bool single, bool up, bool writeback, bool load,
631        uint32_t offset)
632    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, rn,
633                     vd, single, up, writeback, load, offset)
634{
635    %(constructor)s;
636    if (!(condCode == COND_AL || condCode == COND_UC)) {
637        for (int x = 0; x < _numDestRegs; x++) {
638            _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
639        }
640    }
641}
642
643}};
644