types.hh revision 10537:47fe87b0cf97
1/*
2 * Copyright (c) 2010, 2012-2013 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder.  You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2007-2008 The Florida State University
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Stephen Hines
41 */
42
43#ifndef __ARCH_ARM_TYPES_HH__
44#define __ARCH_ARM_TYPES_HH__
45
46#include "arch/generic/types.hh"
47#include "base/bitunion.hh"
48#include "base/hashmap.hh"
49#include "base/misc.hh"
50#include "base/types.hh"
51#include "debug/Decoder.hh"
52
53namespace ArmISA
54{
55    typedef uint32_t MachInst;
56
57    BitUnion8(ITSTATE)
58        /* Note that the split (cond, mask) below is not as in ARM ARM.
59         * But it is more convenient for simulation. The condition
60         * is always the concatenation of the top 3 bits and the next bit,
61         * which applies when one of the bottom 4 bits is set.
62         * Refer to predecoder.cc for the use case.
63         */
64        Bitfield<7, 4> cond;
65        Bitfield<3, 0> mask;
66        // Bitfields for moving to/from CPSR
67        Bitfield<7, 2> top6;
68        Bitfield<1, 0> bottom2;
69    EndBitUnion(ITSTATE)
70
71
72    BitUnion64(ExtMachInst)
73        // ITSTATE bits
74        Bitfield<55, 48> itstate;
75        Bitfield<55, 52> itstateCond;
76        Bitfield<51, 48> itstateMask;
77
78        // FPSCR fields
79        Bitfield<41, 40> fpscrStride;
80        Bitfield<39, 37> fpscrLen;
81
82        // Bitfields to select mode.
83        Bitfield<36>     thumb;
84        Bitfield<35>     bigThumb;
85        Bitfield<34>     aarch64;
86
87        // Made up bitfields that make life easier.
88        Bitfield<33>     sevenAndFour;
89        Bitfield<32>     isMisc;
90
91        uint32_t         instBits;
92
93        // All the different types of opcode fields.
94        Bitfield<27, 25> encoding;
95        Bitfield<25>     useImm;
96        Bitfield<24, 21> opcode;
97        Bitfield<24, 20> mediaOpcode;
98        Bitfield<24>     opcode24;
99        Bitfield<24, 23> opcode24_23;
100        Bitfield<23, 20> opcode23_20;
101        Bitfield<23, 21> opcode23_21;
102        Bitfield<20>     opcode20;
103        Bitfield<22>     opcode22;
104        Bitfield<19, 16> opcode19_16;
105        Bitfield<19>     opcode19;
106        Bitfield<18>     opcode18;
107        Bitfield<15, 12> opcode15_12;
108        Bitfield<15>     opcode15;
109        Bitfield<7,  4>  miscOpcode;
110        Bitfield<7,5>    opc2;
111        Bitfield<7>      opcode7;
112        Bitfield<6>      opcode6;
113        Bitfield<4>      opcode4;
114
115        Bitfield<31, 28> condCode;
116        Bitfield<20>     sField;
117        Bitfield<19, 16> rn;
118        Bitfield<15, 12> rd;
119        Bitfield<15, 12> rt;
120        Bitfield<11, 7>  shiftSize;
121        Bitfield<6,  5>  shift;
122        Bitfield<3,  0>  rm;
123
124        Bitfield<11, 8>  rs;
125
126        SubBitUnion(puswl, 24, 20)
127            Bitfield<24> prepost;
128            Bitfield<23> up;
129            Bitfield<22> psruser;
130            Bitfield<21> writeback;
131            Bitfield<20> loadOp;
132        EndSubBitUnion(puswl)
133
134        Bitfield<24, 20> pubwl;
135
136        Bitfield<7, 0> imm;
137
138        Bitfield<11, 8>  rotate;
139
140        Bitfield<11, 0>  immed11_0;
141        Bitfield<7,  0>  immed7_0;
142
143        Bitfield<11, 8>  immedHi11_8;
144        Bitfield<3,  0>  immedLo3_0;
145
146        Bitfield<15, 0>  regList;
147
148        Bitfield<23, 0>  offset;
149
150        Bitfield<23, 0>  immed23_0;
151
152        Bitfield<11, 8>  cpNum;
153        Bitfield<18, 16> fn;
154        Bitfield<14, 12> fd;
155        Bitfield<3>      fpRegImm;
156        Bitfield<3,  0>  fm;
157        Bitfield<2,  0>  fpImm;
158        Bitfield<24, 20> punwl;
159
160        Bitfield<15,  8>  m5Func;
161
162        // 16 bit thumb bitfields
163        Bitfield<15, 13> topcode15_13;
164        Bitfield<13, 11> topcode13_11;
165        Bitfield<12, 11> topcode12_11;
166        Bitfield<12, 10> topcode12_10;
167        Bitfield<11, 9>  topcode11_9;
168        Bitfield<11, 8>  topcode11_8;
169        Bitfield<10, 9>  topcode10_9;
170        Bitfield<10, 8>  topcode10_8;
171        Bitfield<9,  6>  topcode9_6;
172        Bitfield<7>      topcode7;
173        Bitfield<7, 6>   topcode7_6;
174        Bitfield<7, 5>   topcode7_5;
175        Bitfield<7, 4>   topcode7_4;
176        Bitfield<3, 0>   topcode3_0;
177
178        // 32 bit thumb bitfields
179        Bitfield<28, 27> htopcode12_11;
180        Bitfield<26, 25> htopcode10_9;
181        Bitfield<25>     htopcode9;
182        Bitfield<25, 24> htopcode9_8;
183        Bitfield<25, 21> htopcode9_5;
184        Bitfield<25, 20> htopcode9_4;
185        Bitfield<24>     htopcode8;
186        Bitfield<24, 23> htopcode8_7;
187        Bitfield<24, 22> htopcode8_6;
188        Bitfield<24, 21> htopcode8_5;
189        Bitfield<23>     htopcode7;
190        Bitfield<23, 21> htopcode7_5;
191        Bitfield<22>     htopcode6;
192        Bitfield<22, 21> htopcode6_5;
193        Bitfield<21, 20> htopcode5_4;
194        Bitfield<20>     htopcode4;
195
196        Bitfield<19, 16> htrn;
197        Bitfield<20>     hts;
198
199        Bitfield<15>     ltopcode15;
200        Bitfield<11, 8>  ltopcode11_8;
201        Bitfield<7,  6>  ltopcode7_6;
202        Bitfield<7,  4>  ltopcode7_4;
203        Bitfield<4>      ltopcode4;
204
205        Bitfield<11, 8>  ltrd;
206        Bitfield<11, 8>  ltcoproc;
207    EndBitUnion(ExtMachInst)
208
209    class PCState : public GenericISA::UPCState<MachInst>
210    {
211      protected:
212
213        typedef GenericISA::UPCState<MachInst> Base;
214
215        enum FlagBits {
216            ThumbBit = (1 << 0),
217            JazelleBit = (1 << 1),
218            AArch64Bit = (1 << 2)
219        };
220        uint8_t flags;
221        uint8_t nextFlags;
222        uint8_t _itstate;
223        uint8_t _nextItstate;
224        uint8_t _size;
225      public:
226        PCState() : flags(0), nextFlags(0), _itstate(0), _nextItstate(0),
227                    _size(0)
228        {}
229
230        void
231        set(Addr val)
232        {
233            Base::set(val);
234            npc(val + (thumb() ? 2 : 4));
235        }
236
237        PCState(Addr val) : flags(0), nextFlags(0), _itstate(0),
238                            _nextItstate(0), _size(0)
239        { set(val); }
240
241        bool
242        thumb() const
243        {
244            return flags & ThumbBit;
245        }
246
247        void
248        thumb(bool val)
249        {
250            if (val)
251                flags |= ThumbBit;
252            else
253                flags &= ~ThumbBit;
254        }
255
256        bool
257        nextThumb() const
258        {
259            return nextFlags & ThumbBit;
260        }
261
262        void
263        nextThumb(bool val)
264        {
265            if (val)
266                nextFlags |= ThumbBit;
267            else
268                nextFlags &= ~ThumbBit;
269        }
270
271        void size(uint8_t s) { _size = s; }
272        uint8_t size() const { return _size; }
273
274        bool
275        branching() const
276        {
277            return ((this->pc() + this->size()) != this->npc());
278        }
279
280
281        bool
282        jazelle() const
283        {
284            return flags & JazelleBit;
285        }
286
287        void
288        jazelle(bool val)
289        {
290            if (val)
291                flags |= JazelleBit;
292            else
293                flags &= ~JazelleBit;
294        }
295
296        bool
297        nextJazelle() const
298        {
299            return nextFlags & JazelleBit;
300        }
301
302        void
303        nextJazelle(bool val)
304        {
305            if (val)
306                nextFlags |= JazelleBit;
307            else
308                nextFlags &= ~JazelleBit;
309        }
310
311        bool
312        aarch64() const
313        {
314            return flags & AArch64Bit;
315        }
316
317        void
318        aarch64(bool val)
319        {
320            if (val)
321                flags |= AArch64Bit;
322            else
323                flags &= ~AArch64Bit;
324        }
325
326        bool
327        nextAArch64() const
328        {
329            return nextFlags & AArch64Bit;
330        }
331
332        void
333        nextAArch64(bool val)
334        {
335            if (val)
336                nextFlags |= AArch64Bit;
337            else
338                nextFlags &= ~AArch64Bit;
339        }
340
341
342        uint8_t
343        itstate() const
344        {
345            return _itstate;
346        }
347
348        void
349        itstate(uint8_t value)
350        {
351            _itstate = value;
352        }
353
354        uint8_t
355        nextItstate() const
356        {
357            return _nextItstate;
358        }
359
360        void
361        nextItstate(uint8_t value)
362        {
363            _nextItstate = value;
364        }
365
366        void
367        advance()
368        {
369            Base::advance();
370            flags = nextFlags;
371            npc(pc() + (thumb() ? 2 : 4));
372
373            if (_nextItstate) {
374                _itstate = _nextItstate;
375                _nextItstate = 0;
376            } else if (_itstate) {
377                ITSTATE it = _itstate;
378                uint8_t cond_mask = it.mask;
379                uint8_t thumb_cond = it.cond;
380                DPRINTF(Decoder, "Advancing ITSTATE from %#x,%#x.\n",
381                        thumb_cond, cond_mask);
382                cond_mask <<= 1;
383                uint8_t new_bit = bits(cond_mask, 4);
384                cond_mask &= mask(4);
385                if (cond_mask == 0)
386                    thumb_cond = 0;
387                else
388                    replaceBits(thumb_cond, 0, new_bit);
389                DPRINTF(Decoder, "Advancing ITSTATE to %#x,%#x.\n",
390                        thumb_cond, cond_mask);
391                it.mask = cond_mask;
392                it.cond = thumb_cond;
393                _itstate = it;
394            }
395        }
396
397        void
398        uEnd()
399        {
400            advance();
401            upc(0);
402            nupc(1);
403        }
404
405        Addr
406        instPC() const
407        {
408            return pc() + (thumb() ? 4 : 8);
409        }
410
411        void
412        instNPC(Addr val)
413        {
414            // @todo: review this when AArch32/64 interprocessing is
415            // supported
416            if (aarch64())
417                npc(val);  // AArch64 doesn't force PC alignment, a PC
418                           // Alignment Fault can be raised instead
419            else
420                npc(val &~ mask(nextThumb() ? 1 : 2));
421        }
422
423        Addr
424        instNPC() const
425        {
426            return npc();
427        }
428
429        // Perform an interworking branch.
430        void
431        instIWNPC(Addr val)
432        {
433            bool thumbEE = (thumb() && jazelle());
434
435            Addr newPC = val;
436            if (thumbEE) {
437                if (bits(newPC, 0)) {
438                    newPC = newPC & ~mask(1);
439                }  // else we have a bad interworking address; do not call
440                   // panic() since the instruction could be executed
441                   // speculatively
442            } else {
443                if (bits(newPC, 0)) {
444                    nextThumb(true);
445                    newPC = newPC & ~mask(1);
446                } else if (!bits(newPC, 1)) {
447                    nextThumb(false);
448                } else {
449                    // This state is UNPREDICTABLE in the ARM architecture
450                    // The easy thing to do is just mask off the bit and
451                    // stay in the current mode, so we'll do that.
452                    newPC &= ~mask(2);
453                }
454            }
455            npc(newPC);
456        }
457
458        // Perform an interworking branch in ARM mode, a regular branch
459        // otherwise.
460        void
461        instAIWNPC(Addr val)
462        {
463            if (!thumb() && !jazelle())
464                instIWNPC(val);
465            else
466                instNPC(val);
467        }
468
469        bool
470        operator == (const PCState &opc) const
471        {
472            return Base::operator == (opc) &&
473                flags == opc.flags && nextFlags == opc.nextFlags &&
474                _itstate == opc._itstate && _nextItstate == opc._nextItstate;
475        }
476
477        bool
478        operator != (const PCState &opc) const
479        {
480            return !(*this == opc);
481        }
482
483        void
484        serialize(std::ostream &os)
485        {
486            Base::serialize(os);
487            SERIALIZE_SCALAR(flags);
488            SERIALIZE_SCALAR(_size);
489            SERIALIZE_SCALAR(nextFlags);
490            SERIALIZE_SCALAR(_itstate);
491            SERIALIZE_SCALAR(_nextItstate);
492        }
493
494        void
495        unserialize(Checkpoint *cp, const std::string &section)
496        {
497            Base::unserialize(cp, section);
498            UNSERIALIZE_SCALAR(flags);
499            UNSERIALIZE_SCALAR(_size);
500            UNSERIALIZE_SCALAR(nextFlags);
501            UNSERIALIZE_SCALAR(_itstate);
502            UNSERIALIZE_SCALAR(_nextItstate);
503        }
504    };
505
506    // Shift types for ARM instructions
507    enum ArmShiftType {
508        LSL = 0,
509        LSR,
510        ASR,
511        ROR
512    };
513
514    // Extension types for ARM instructions
515    enum ArmExtendType {
516        UXTB = 0,
517        UXTH = 1,
518        UXTW = 2,
519        UXTX = 3,
520        SXTB = 4,
521        SXTH = 5,
522        SXTW = 6,
523        SXTX = 7
524    };
525
526    typedef uint64_t LargestRead;
527    // Need to use 64 bits to make sure that read requests get handled properly
528
529    typedef int RegContextParam;
530    typedef int RegContextVal;
531
532    //used in FP convert & round function
533    enum ConvertType{
534        SINGLE_TO_DOUBLE,
535        SINGLE_TO_WORD,
536        SINGLE_TO_LONG,
537
538        DOUBLE_TO_SINGLE,
539        DOUBLE_TO_WORD,
540        DOUBLE_TO_LONG,
541
542        LONG_TO_SINGLE,
543        LONG_TO_DOUBLE,
544        LONG_TO_WORD,
545        LONG_TO_PS,
546
547        WORD_TO_SINGLE,
548        WORD_TO_DOUBLE,
549        WORD_TO_LONG,
550        WORD_TO_PS,
551
552        PL_TO_SINGLE,
553        PU_TO_SINGLE
554    };
555
556    //used in FP convert & round function
557    enum RoundMode{
558        RND_ZERO,
559        RND_DOWN,
560        RND_UP,
561        RND_NEAREST
562    };
563
564    enum ExceptionLevel {
565        EL0 = 0,
566        EL1,
567        EL2,
568        EL3
569    };
570
571    enum OperatingMode {
572        MODE_EL0T = 0x0,
573        MODE_EL1T = 0x4,
574        MODE_EL1H = 0x5,
575        MODE_EL2T = 0x8,
576        MODE_EL2H = 0x9,
577        MODE_EL3T = 0xC,
578        MODE_EL3H = 0xD,
579        MODE_USER = 16,
580        MODE_FIQ = 17,
581        MODE_IRQ = 18,
582        MODE_SVC = 19,
583        MODE_MON = 22,
584        MODE_ABORT = 23,
585        MODE_HYP = 26,
586        MODE_UNDEFINED = 27,
587        MODE_SYSTEM = 31,
588        MODE_MAXMODE = MODE_SYSTEM
589    };
590
591    enum ExceptionClass {
592        EC_INVALID                 = -1,
593        EC_UNKNOWN                 = 0x0,
594        EC_TRAPPED_WFI_WFE         = 0x1,
595        EC_TRAPPED_CP15_MCR_MRC    = 0x3,
596        EC_TRAPPED_CP15_MCRR_MRRC  = 0x4,
597        EC_TRAPPED_CP14_MCR_MRC    = 0x5,
598        EC_TRAPPED_CP14_LDC_STC    = 0x6,
599        EC_TRAPPED_HCPTR           = 0x7,
600        EC_TRAPPED_SIMD_FP         = 0x7,   // AArch64 alias
601        EC_TRAPPED_CP10_MRC_VMRS   = 0x8,
602        EC_TRAPPED_BXJ             = 0xA,
603        EC_TRAPPED_CP14_MCRR_MRRC  = 0xC,
604        EC_ILLEGAL_INST            = 0xE,
605        EC_SVC_TO_HYP              = 0x11,
606        EC_SVC                     = 0x11,  // AArch64 alias
607        EC_HVC                     = 0x12,
608        EC_SMC_TO_HYP              = 0x13,
609        EC_SMC                     = 0x13,  // AArch64 alias
610        EC_SVC_64                  = 0x15,
611        EC_HVC_64                  = 0x16,
612        EC_SMC_64                  = 0x17,
613        EC_TRAPPED_MSR_MRS_64      = 0x18,
614        EC_PREFETCH_ABORT_TO_HYP   = 0x20,
615        EC_PREFETCH_ABORT_LOWER_EL = 0x20,  // AArch64 alias
616        EC_PREFETCH_ABORT_FROM_HYP = 0x21,
617        EC_PREFETCH_ABORT_CURR_EL  = 0x21,  // AArch64 alias
618        EC_PC_ALIGNMENT            = 0x22,
619        EC_DATA_ABORT_TO_HYP       = 0x24,
620        EC_DATA_ABORT_LOWER_EL     = 0x24,  // AArch64 alias
621        EC_DATA_ABORT_FROM_HYP     = 0x25,
622        EC_DATA_ABORT_CURR_EL      = 0x25,  // AArch64 alias
623        EC_STACK_PTR_ALIGNMENT     = 0x26,
624        EC_FP_EXCEPTION            = 0x28,
625        EC_FP_EXCEPTION_64         = 0x2C,
626        EC_SERROR                  = 0x2F
627    };
628
629    BitUnion8(OperatingMode64)
630        Bitfield<0> spX;
631        Bitfield<3, 2> el;
632        Bitfield<4> width;
633    EndBitUnion(OperatingMode64)
634
635    static bool inline
636    opModeIs64(OperatingMode mode)
637    {
638        return ((OperatingMode64)(uint8_t)mode).width == 0;
639    }
640
641    static bool inline
642    opModeIsH(OperatingMode mode)
643    {
644        return (mode == MODE_EL1H || mode == MODE_EL2H || mode == MODE_EL3H);
645    }
646
647    static bool inline
648    opModeIsT(OperatingMode mode)
649    {
650        return (mode == MODE_EL0T || mode == MODE_EL1T || mode == MODE_EL2T ||
651                mode == MODE_EL3T);
652    }
653
654    static ExceptionLevel inline
655    opModeToEL(OperatingMode mode)
656    {
657        bool aarch32 = ((mode >> 4) & 1) ? true : false;
658        if (aarch32) {
659            switch (mode) {
660              case MODE_USER:
661                return EL0;
662              case MODE_FIQ:
663              case MODE_IRQ:
664              case MODE_SVC:
665              case MODE_ABORT:
666              case MODE_UNDEFINED:
667              case MODE_SYSTEM:
668                return EL1;
669              case MODE_HYP:
670                return EL2;
671              case MODE_MON:
672                return EL3;
673              default:
674                panic("Invalid operating mode: %d", mode);
675                break;
676            }
677        } else {
678            // aarch64
679            return (ExceptionLevel) ((mode >> 2) & 3);
680        }
681    }
682
683    static inline bool
684    badMode(OperatingMode mode)
685    {
686        switch (mode) {
687          case MODE_EL0T:
688          case MODE_EL1T:
689          case MODE_EL1H:
690          case MODE_EL2T:
691          case MODE_EL2H:
692          case MODE_EL3T:
693          case MODE_EL3H:
694          case MODE_USER:
695          case MODE_FIQ:
696          case MODE_IRQ:
697          case MODE_SVC:
698          case MODE_MON:
699          case MODE_ABORT:
700          case MODE_HYP:
701          case MODE_UNDEFINED:
702          case MODE_SYSTEM:
703            return false;
704          default:
705            return true;
706        }
707    }
708
709
710    static inline bool
711    badMode32(OperatingMode mode)
712    {
713        switch (mode) {
714          case MODE_USER:
715          case MODE_FIQ:
716          case MODE_IRQ:
717          case MODE_SVC:
718          case MODE_MON:
719          case MODE_ABORT:
720          case MODE_HYP:
721          case MODE_UNDEFINED:
722          case MODE_SYSTEM:
723            return false;
724          default:
725            return true;
726        }
727    }
728
729} // namespace ArmISA
730
731__hash_namespace_begin
732
733template<>
734struct hash<ArmISA::ExtMachInst> :
735        public hash<ArmISA::ExtMachInst::__DataType> {
736
737    size_t operator()(const ArmISA::ExtMachInst &emi) const {
738        return hash<ArmISA::ExtMachInst::__DataType>::operator()(emi);
739    }
740
741};
742
743__hash_namespace_end
744
745#endif
746