macromem.isa revision 12234
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        %(BasicExecDeclare)s
57        %(InitiateAccDeclare)s
58        %(CompleteAccDeclare)s
59    };
60}};
61
62def template MicroMemConstructor {{
63    %(class_name)s::%(class_name)s(ExtMachInst machInst,
64                                   RegIndex _ura,
65                                   RegIndex _urb,
66                                   bool _up,
67                                   uint8_t _imm)
68        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
69                         _ura, _urb, _up, _imm)
70    {
71        %(constructor)s;
72        if (!(condCode == COND_AL || condCode == COND_UC)) {
73            for (int x = 0; x < _numDestRegs; x++) {
74                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
75            }
76        }
77    }
78}};
79
80
81def template MicroMemPairDeclare {{
82    class %(class_name)s : public %(base_class)s
83    {
84      public:
85        %(class_name)s(ExtMachInst machInst,
86                       RegIndex _dreg1, RegIndex _dreg2, RegIndex _base,
87                       bool _up, uint8_t _imm);
88        %(BasicExecDeclare)s
89        %(InitiateAccDeclare)s
90        %(CompleteAccDeclare)s
91    };
92}};
93
94def template MicroMemPairConstructor {{
95    %(class_name)s::%(class_name)s(ExtMachInst machInst,
96                                   RegIndex _dreg1,
97                                   RegIndex _dreg2,
98                                   RegIndex _base,
99                                   bool _up,
100                                   uint8_t _imm)
101        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
102                         _dreg1, _dreg2, _base, _up, _imm)
103    {
104        %(constructor)s;
105        if (!(condCode == COND_AL || condCode == COND_UC)) {
106            for (int x = 0; x < _numDestRegs; x++) {
107                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
108            }
109        }
110    }
111}};
112
113////////////////////////////////////////////////////////////////////
114//
115// Neon load/store microops
116//
117
118def template MicroNeonMemDeclare {{
119    template <class Element>
120    class %(class_name)s : public %(base_class)s
121    {
122      public:
123        %(class_name)s(ExtMachInst machInst, RegIndex _dest,
124                       RegIndex _ura, uint32_t _imm, unsigned extraMemFlags)
125            : %(base_class)s("%(mnemonic)s", machInst,
126                              %(op_class)s, _dest, _ura, _imm)
127        {
128            memAccessFlags |= extraMemFlags;
129            %(constructor)s;
130            if (!(condCode == COND_AL || condCode == COND_UC)) {
131                for (int x = 0; x < _numDestRegs; x++) {
132                    _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
133                }
134            }
135        }
136
137        %(BasicExecDeclare)s
138        %(InitiateAccDeclare)s
139        %(CompleteAccDeclare)s
140    };
141}};
142
143////////////////////////////////////////////////////////////////////
144//
145// PC   = Integer(ura)
146// CPSR = Integer(urb)
147//
148
149def template MicroSetPCCPSRDeclare {{
150    class %(class_name)s : public %(base_class)s
151    {
152      public:
153        %(class_name)s(ExtMachInst machInst,
154                       IntRegIndex _ura,
155                       IntRegIndex _urb,
156                       IntRegIndex _urc);
157        %(BasicExecDeclare)s
158    };
159}};
160
161def template MicroSetPCCPSRConstructor {{
162    %(class_name)s::%(class_name)s(ExtMachInst machInst,
163                                   IntRegIndex _ura,
164                                   IntRegIndex _urb,
165                                   IntRegIndex _urc)
166          : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
167                           _ura, _urb, _urc)
168    {
169        %(constructor)s;
170        if (!(condCode == COND_AL || condCode == COND_UC)) {
171            flags[IsCondControl] = true;
172            for (int x = 0; x < _numDestRegs; x++) {
173                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
174            }
175        } else {
176            flags[IsUncondControl] = true;
177        }
178    }
179}};
180
181////////////////////////////////////////////////////////////////////
182//
183// Integer = Integer op Integer microops
184//
185
186def template MicroIntDeclare {{
187    class %(class_name)s : public %(base_class)s
188    {
189      public:
190        %(class_name)s(ExtMachInst machInst,
191                       RegIndex _ura, RegIndex _urb, RegIndex _urc);
192        %(BasicExecDeclare)s
193    };
194}};
195
196def template MicroIntConstructor {{
197    %(class_name)s::%(class_name)s(ExtMachInst machInst,
198                                   RegIndex _ura,
199                                   RegIndex _urb,
200                                   RegIndex _urc)
201        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
202                         _ura, _urb, _urc)
203    {
204        %(constructor)s;
205        if (!(condCode == COND_AL || condCode == COND_UC)) {
206            for (int x = 0; x < _numDestRegs; x++) {
207                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
208            }
209        }
210    }
211}};
212
213def template MicroNeonMemExecDeclare {{
214    template
215    Fault %(class_name)s<%(targs)s>::execute(
216            ExecContext *, Trace::InstRecord *) const;
217    template
218    Fault %(class_name)s<%(targs)s>::initiateAcc(
219            ExecContext *, Trace::InstRecord *) const;
220    template
221    Fault %(class_name)s<%(targs)s>::completeAcc(PacketPtr,
222            ExecContext *, Trace::InstRecord *) const;
223}};
224
225def template MicroNeonExecDeclare {{
226    template
227    Fault %(class_name)s<%(targs)s>::execute(
228            ExecContext *, Trace::InstRecord *) const;
229}};
230
231////////////////////////////////////////////////////////////////////
232//
233// Neon (de)interlacing microops
234//
235
236def template MicroNeonMixDeclare {{
237    template <class Element>
238    class %(class_name)s : public %(base_class)s
239    {
240      public:
241        %(class_name)s(ExtMachInst machInst, RegIndex _dest, RegIndex _op1,
242                       uint8_t _step) :
243            %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
244                           _dest, _op1, _step)
245        {
246            %(constructor)s;
247            if (!(condCode == COND_AL || condCode == COND_UC)) {
248                for (int x = 0; x < _numDestRegs; x++) {
249                    _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
250                }
251            }
252        }
253
254        %(BasicExecDeclare)s
255    };
256}};
257
258def template MicroNeonMixExecute {{
259    template <class Element>
260    Fault %(class_name)s<Element>::execute(ExecContext *xc,
261            Trace::InstRecord *traceData) const
262    {
263        Fault fault = NoFault;
264        uint64_t resTemp = 0;
265        resTemp = resTemp;
266        %(op_decl)s;
267        %(op_rd)s;
268
269        if (%(predicate_test)s)
270        {
271            %(code)s;
272            if (fault == NoFault)
273            {
274                %(op_wb)s;
275            }
276        } else {
277            xc->setPredicate(false);
278        }
279
280        return fault;
281    }
282}};
283
284////////////////////////////////////////////////////////////////////
285//
286// Neon (un)packing microops using a particular lane
287//
288
289def template MicroNeonMixLaneDeclare {{
290    template <class Element>
291    class %(class_name)s : public %(base_class)s
292    {
293      public:
294        %(class_name)s(ExtMachInst machInst, RegIndex _dest, RegIndex _op1,
295                       uint8_t _step, unsigned _lane) :
296            %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
297                           _dest, _op1, _step, _lane)
298        {
299            %(constructor)s;
300            if (!(condCode == COND_AL || condCode == COND_UC)) {
301                for (int x = 0; x < _numDestRegs; x++) {
302                    _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
303                }
304            }
305        }
306
307        %(BasicExecDeclare)s
308    };
309}};
310
311////////////////////////////////////////////////////////////////////
312//
313// Integer = Integer
314//
315
316def template MicroIntMovDeclare {{
317    class %(class_name)s : public %(base_class)s
318    {
319      public:
320        %(class_name)s(ExtMachInst machInst,
321                       RegIndex _ura, RegIndex _urb);
322        %(BasicExecDeclare)s
323    };
324}};
325def template MicroIntMovConstructor {{
326    %(class_name)s::%(class_name)s(ExtMachInst machInst,
327                                   RegIndex _ura,
328                                   RegIndex _urb)
329        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
330                         _ura, _urb)
331    {
332        %(constructor)s;
333        if (!(condCode == COND_AL || condCode == COND_UC)) {
334            for (int x = 0; x < _numDestRegs; x++) {
335                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
336            }
337        }
338    }
339}};
340
341////////////////////////////////////////////////////////////////////
342//
343// Integer = Integer op Immediate microops
344//
345
346def template MicroIntImmDeclare {{
347    class %(class_name)s : public %(base_class)s
348    {
349      public:
350        %(class_name)s(ExtMachInst machInst,
351                       RegIndex _ura, RegIndex _urb,
352                       int32_t _imm);
353        %(BasicExecDeclare)s
354    };
355}};
356
357def template MicroIntImmConstructor {{
358    %(class_name)s::%(class_name)s(ExtMachInst machInst,
359                                   RegIndex _ura,
360                                   RegIndex _urb,
361                                   int32_t _imm)
362        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
363                         _ura, _urb, _imm)
364    {
365        %(constructor)s;
366        if (!(condCode == COND_AL || condCode == COND_UC)) {
367            for (int x = 0; x < _numDestRegs; x++) {
368                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
369            }
370        }
371    }
372}};
373
374def template MicroIntImmXConstructor {{
375    %(class_name)s::%(class_name)s(ExtMachInst machInst,
376                                   RegIndex _ura,
377                                   RegIndex _urb,
378                                   int32_t _imm)
379        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
380                         _ura, _urb, _imm)
381    {
382        %(constructor)s;
383    }
384}};
385
386def template MicroIntRegDeclare {{
387    class %(class_name)s : public %(base_class)s
388    {
389      public:
390        %(class_name)s(ExtMachInst machInst,
391                       RegIndex _ura, RegIndex _urb, RegIndex _urc,
392                       int32_t _shiftAmt, ArmShiftType _shiftType);
393        %(BasicExecDeclare)s
394    };
395}};
396
397def template MicroIntXERegConstructor {{
398    %(class_name)s::%(class_name)s(ExtMachInst machInst,
399                                   RegIndex _ura, RegIndex _urb, RegIndex _urc,
400                                   ArmExtendType _type, uint32_t _shiftAmt)
401        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
402                         _ura, _urb, _urc, _type, _shiftAmt)
403    {
404        %(constructor)s;
405    }
406}};
407
408def template MicroIntXERegDeclare {{
409    class %(class_name)s : public %(base_class)s
410    {
411      public:
412        %(class_name)s(ExtMachInst machInst,
413                       RegIndex _ura, RegIndex _urb, RegIndex _urc,
414                       ArmExtendType _type, uint32_t _shiftAmt);
415        %(BasicExecDeclare)s
416    };
417}};
418
419def template MicroIntRegConstructor {{
420    %(class_name)s::%(class_name)s(ExtMachInst machInst,
421                                   RegIndex _ura, RegIndex _urb, RegIndex _urc,
422                                   int32_t _shiftAmt, ArmShiftType _shiftType)
423        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
424                         _ura, _urb, _urc, _shiftAmt, _shiftType)
425    {
426        %(constructor)s;
427        if (!(condCode == COND_AL || condCode == COND_UC)) {
428            for (int x = 0; x < _numDestRegs; x++) {
429                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
430            }
431        }
432    }
433}};
434
435////////////////////////////////////////////////////////////////////
436//
437// Macro Memory-format instructions
438//
439
440def template MacroMemDeclare {{
441/**
442 * Static instructions class for a store multiple instruction
443 */
444class %(class_name)s : public %(base_class)s
445{
446    public:
447        // Constructor
448        %(class_name)s(ExtMachInst machInst, IntRegIndex rn,
449                bool index, bool up, bool user, bool writeback, bool load,
450                uint32_t reglist);
451        %(BasicExecPanic)s
452};
453}};
454
455def template MacroMemConstructor {{
456%(class_name)s::%(class_name)s(ExtMachInst machInst, IntRegIndex rn,
457        bool index, bool up, bool user, bool writeback, bool load,
458        uint32_t reglist)
459    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, rn,
460                     index, up, user, writeback, load, reglist)
461{
462    %(constructor)s;
463    if (!(condCode == COND_AL || condCode == COND_UC)) {
464        for (int x = 0; x < _numDestRegs; x++) {
465            _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
466        }
467    }
468}
469
470}};
471
472def template BigFpMemImmDeclare {{
473class %(class_name)s : public %(base_class)s
474{
475  public:
476    // Constructor
477    %(class_name)s(const char *mnemonic, ExtMachInst machInst,
478                   bool load, IntRegIndex dest, IntRegIndex base, int64_t imm);
479    %(BasicExecPanic)s
480};
481}};
482
483def template BigFpMemImmConstructor {{
484%(class_name)s::%(class_name)s(const char *mnemonic, ExtMachInst machInst,
485        bool load, IntRegIndex dest, IntRegIndex base, int64_t imm)
486    : %(base_class)s(mnemonic, machInst, %(op_class)s, load, dest, base, imm)
487{
488    %(constructor)s;
489}
490}};
491
492def template BigFpMemRegDeclare {{
493class %(class_name)s : public %(base_class)s
494{
495  public:
496    // Constructor
497    %(class_name)s(const char *mnemonic, ExtMachInst machInst,
498                   bool load, IntRegIndex dest, IntRegIndex base,
499                   IntRegIndex offset, ArmExtendType type, int64_t imm);
500    %(BasicExecPanic)s
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    %(BasicExecPanic)s
523};
524}};
525
526def template BigFpMemLitConstructor {{
527%(class_name)s::%(class_name)s(const char *mnemonic, ExtMachInst machInst,
528        IntRegIndex dest, int64_t imm)
529    : %(base_class)s(mnemonic, machInst, %(op_class)s, dest, imm)
530{
531    %(constructor)s;
532}
533}};
534
535def template PairMemDeclare {{
536class %(class_name)s : public %(base_class)s
537{
538    public:
539        // Constructor
540        %(class_name)s(const char *mnemonic, ExtMachInst machInst,
541                uint32_t size, bool fp, bool load, bool noAlloc, bool signExt,
542                bool exclusive, bool acrel, uint32_t imm,
543                AddrMode mode, IntRegIndex rn, IntRegIndex rt,
544                IntRegIndex rt2);
545        %(BasicExecPanic)s
546};
547}};
548
549def template PairMemConstructor {{
550%(class_name)s::%(class_name)s(const char *mnemonic, ExtMachInst machInst,
551        uint32_t size, bool fp, bool load, bool noAlloc, bool signExt,
552        bool exclusive, bool acrel, uint32_t imm, AddrMode mode,
553        IntRegIndex rn, IntRegIndex rt, IntRegIndex rt2)
554    : %(base_class)s(mnemonic, machInst, %(op_class)s, size,
555                     fp, load, noAlloc, signExt, exclusive, acrel,
556                     imm, mode, rn, rt, rt2)
557{
558    %(constructor)s;
559}
560}};
561
562def template VMemMultDeclare {{
563class %(class_name)s : public %(base_class)s
564{
565    public:
566        // Constructor
567        %(class_name)s(ExtMachInst machInst, unsigned width,
568                RegIndex rn, RegIndex vd, unsigned regs, unsigned inc,
569                uint32_t size, uint32_t align, RegIndex rm);
570        %(BasicExecPanic)s
571};
572}};
573
574def template VMemMultConstructor {{
575%(class_name)s::%(class_name)s(ExtMachInst machInst, unsigned width,
576        RegIndex rn, RegIndex vd, unsigned regs, unsigned inc,
577        uint32_t size, uint32_t align, RegIndex rm)
578    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, width,
579                     rn, vd, regs, inc, size, align, rm)
580{
581    %(constructor)s;
582    if (!(condCode == COND_AL || condCode == COND_UC)) {
583        for (int x = 0; x < _numDestRegs; x++) {
584            _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
585        }
586    }
587}
588}};
589
590def template VMemSingleDeclare {{
591class %(class_name)s : public %(base_class)s
592{
593    public:
594        // Constructor
595        %(class_name)s(ExtMachInst machInst, bool all, unsigned width,
596                RegIndex rn, RegIndex vd, unsigned regs, unsigned inc,
597                uint32_t size, uint32_t align, RegIndex rm, unsigned lane = 0);
598        %(BasicExecPanic)s
599};
600}};
601
602def template VMemSingleConstructor {{
603%(class_name)s::%(class_name)s(ExtMachInst machInst, bool all, unsigned width,
604        RegIndex rn, RegIndex vd, unsigned regs, unsigned inc,
605        uint32_t size, uint32_t align, RegIndex rm, unsigned lane)
606    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, all, width,
607                     rn, vd, regs, inc, size, align, rm, lane)
608{
609    %(constructor)s;
610    if (!(condCode == COND_AL || condCode == COND_UC)) {
611        for (int x = 0; x < _numDestRegs; x++) {
612            _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
613        }
614    }
615}
616}};
617
618def template MacroVFPMemDeclare {{
619/**
620 * Static instructions class for a store multiple instruction
621 */
622class %(class_name)s : public %(base_class)s
623{
624    public:
625        // Constructor
626        %(class_name)s(ExtMachInst machInst, IntRegIndex rn,
627                RegIndex vd, bool single, bool up, bool writeback,
628                bool load, uint32_t offset);
629        %(BasicExecPanic)s
630};
631}};
632
633def template MacroVFPMemConstructor {{
634%(class_name)s::%(class_name)s(ExtMachInst machInst, IntRegIndex rn,
635        RegIndex vd, bool single, bool up, bool writeback, bool load,
636        uint32_t offset)
637    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, rn,
638                     vd, single, up, writeback, load, offset)
639{
640    %(constructor)s;
641    if (!(condCode == COND_AL || condCode == COND_UC)) {
642        for (int x = 0; x < _numDestRegs; x++) {
643            _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
644        }
645    }
646}
647
648}};
649