types.hh revision 10037:5cac77888310
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        {}
228
229        void
230        set(Addr val)
231        {
232            Base::set(val);
233            npc(val + (thumb() ? 2 : 4));
234        }
235
236        PCState(Addr val) : flags(0), nextFlags(0), _itstate(0), _nextItstate(0)
237        { set(val); }
238
239        bool
240        thumb() const
241        {
242            return flags & ThumbBit;
243        }
244
245        void
246        thumb(bool val)
247        {
248            if (val)
249                flags |= ThumbBit;
250            else
251                flags &= ~ThumbBit;
252        }
253
254        bool
255        nextThumb() const
256        {
257            return nextFlags & ThumbBit;
258        }
259
260        void
261        nextThumb(bool val)
262        {
263            if (val)
264                nextFlags |= ThumbBit;
265            else
266                nextFlags &= ~ThumbBit;
267        }
268
269        void size(uint8_t s) { _size = s; }
270        uint8_t size() const { return _size; }
271
272        bool
273        branching() const
274        {
275            return ((this->pc() + this->size()) != this->npc());
276        }
277
278
279        bool
280        jazelle() const
281        {
282            return flags & JazelleBit;
283        }
284
285        void
286        jazelle(bool val)
287        {
288            if (val)
289                flags |= JazelleBit;
290            else
291                flags &= ~JazelleBit;
292        }
293
294        bool
295        nextJazelle() const
296        {
297            return nextFlags & JazelleBit;
298        }
299
300        void
301        nextJazelle(bool val)
302        {
303            if (val)
304                nextFlags |= JazelleBit;
305            else
306                nextFlags &= ~JazelleBit;
307        }
308
309        bool
310        aarch64() const
311        {
312            return flags & AArch64Bit;
313        }
314
315        void
316        aarch64(bool val)
317        {
318            if (val)
319                flags |= AArch64Bit;
320            else
321                flags &= ~AArch64Bit;
322        }
323
324        bool
325        nextAArch64() const
326        {
327            return nextFlags & AArch64Bit;
328        }
329
330        void
331        nextAArch64(bool val)
332        {
333            if (val)
334                nextFlags |= AArch64Bit;
335            else
336                nextFlags &= ~AArch64Bit;
337        }
338
339
340        uint8_t
341        itstate() const
342        {
343            return _itstate;
344        }
345
346        void
347        itstate(uint8_t value)
348        {
349            _itstate = value;
350        }
351
352        uint8_t
353        nextItstate() const
354        {
355            return _nextItstate;
356        }
357
358        void
359        nextItstate(uint8_t value)
360        {
361            _nextItstate = value;
362        }
363
364        void
365        advance()
366        {
367            Base::advance();
368            flags = nextFlags;
369            npc(pc() + (thumb() ? 2 : 4));
370
371            if (_nextItstate) {
372                _itstate = _nextItstate;
373                _nextItstate = 0;
374            } else if (_itstate) {
375                ITSTATE it = _itstate;
376                uint8_t cond_mask = it.mask;
377                uint8_t thumb_cond = it.cond;
378                DPRINTF(Decoder, "Advancing ITSTATE from %#x,%#x.\n",
379                        thumb_cond, cond_mask);
380                cond_mask <<= 1;
381                uint8_t new_bit = bits(cond_mask, 4);
382                cond_mask &= mask(4);
383                if (cond_mask == 0)
384                    thumb_cond = 0;
385                else
386                    replaceBits(thumb_cond, 0, new_bit);
387                DPRINTF(Decoder, "Advancing ITSTATE to %#x,%#x.\n",
388                        thumb_cond, cond_mask);
389                it.mask = cond_mask;
390                it.cond = thumb_cond;
391                _itstate = it;
392            }
393        }
394
395        void
396        uEnd()
397        {
398            advance();
399            upc(0);
400            nupc(1);
401        }
402
403        Addr
404        instPC() const
405        {
406            return pc() + (thumb() ? 4 : 8);
407        }
408
409        void
410        instNPC(Addr val)
411        {
412            // @todo: review this when AArch32/64 interprocessing is
413            // supported
414            if (aarch64())
415                npc(val);  // AArch64 doesn't force PC alignment, a PC
416                           // Alignment Fault can be raised instead
417            else
418                npc(val &~ mask(nextThumb() ? 1 : 2));
419        }
420
421        Addr
422        instNPC() const
423        {
424            return npc();
425        }
426
427        // Perform an interworking branch.
428        void
429        instIWNPC(Addr val)
430        {
431            bool thumbEE = (thumb() && jazelle());
432
433            Addr newPC = val;
434            if (thumbEE) {
435                if (bits(newPC, 0)) {
436                    newPC = newPC & ~mask(1);
437                }  // else we have a bad interworking address; do not call
438                   // panic() since the instruction could be executed
439                   // speculatively
440            } else {
441                if (bits(newPC, 0)) {
442                    nextThumb(true);
443                    newPC = newPC & ~mask(1);
444                } else if (!bits(newPC, 1)) {
445                    nextThumb(false);
446                } else {
447                    // This state is UNPREDICTABLE in the ARM architecture
448                    // The easy thing to do is just mask off the bit and
449                    // stay in the current mode, so we'll do that.
450                    newPC &= ~mask(2);
451                }
452            }
453            npc(newPC);
454        }
455
456        // Perform an interworking branch in ARM mode, a regular branch
457        // otherwise.
458        void
459        instAIWNPC(Addr val)
460        {
461            if (!thumb() && !jazelle())
462                instIWNPC(val);
463            else
464                instNPC(val);
465        }
466
467        bool
468        operator == (const PCState &opc) const
469        {
470            return Base::operator == (opc) &&
471                flags == opc.flags && nextFlags == opc.nextFlags &&
472                _itstate == opc._itstate && _nextItstate == opc._nextItstate;
473        }
474
475        bool
476        operator != (const PCState &opc) const
477        {
478            return !(*this == opc);
479        }
480
481        void
482        serialize(std::ostream &os)
483        {
484            Base::serialize(os);
485            SERIALIZE_SCALAR(flags);
486            SERIALIZE_SCALAR(_size);
487            SERIALIZE_SCALAR(nextFlags);
488            SERIALIZE_SCALAR(_itstate);
489            SERIALIZE_SCALAR(_nextItstate);
490        }
491
492        void
493        unserialize(Checkpoint *cp, const std::string &section)
494        {
495            Base::unserialize(cp, section);
496            UNSERIALIZE_SCALAR(flags);
497            UNSERIALIZE_SCALAR(_size);
498            UNSERIALIZE_SCALAR(nextFlags);
499            UNSERIALIZE_SCALAR(_itstate);
500            UNSERIALIZE_SCALAR(_nextItstate);
501        }
502    };
503
504    // Shift types for ARM instructions
505    enum ArmShiftType {
506        LSL = 0,
507        LSR,
508        ASR,
509        ROR
510    };
511
512    // Extension types for ARM instructions
513    enum ArmExtendType {
514        UXTB = 0,
515        UXTH = 1,
516        UXTW = 2,
517        UXTX = 3,
518        SXTB = 4,
519        SXTH = 5,
520        SXTW = 6,
521        SXTX = 7
522    };
523
524    typedef uint64_t LargestRead;
525    // Need to use 64 bits to make sure that read requests get handled properly
526
527    typedef int RegContextParam;
528    typedef int RegContextVal;
529
530    //used in FP convert & round function
531    enum ConvertType{
532        SINGLE_TO_DOUBLE,
533        SINGLE_TO_WORD,
534        SINGLE_TO_LONG,
535
536        DOUBLE_TO_SINGLE,
537        DOUBLE_TO_WORD,
538        DOUBLE_TO_LONG,
539
540        LONG_TO_SINGLE,
541        LONG_TO_DOUBLE,
542        LONG_TO_WORD,
543        LONG_TO_PS,
544
545        WORD_TO_SINGLE,
546        WORD_TO_DOUBLE,
547        WORD_TO_LONG,
548        WORD_TO_PS,
549
550        PL_TO_SINGLE,
551        PU_TO_SINGLE
552    };
553
554    //used in FP convert & round function
555    enum RoundMode{
556        RND_ZERO,
557        RND_DOWN,
558        RND_UP,
559        RND_NEAREST
560    };
561
562    enum ExceptionLevel {
563        EL0 = 0,
564        EL1,
565        EL2,
566        EL3
567    };
568
569    enum OperatingMode {
570        MODE_EL0T = 0x0,
571        MODE_EL1T = 0x4,
572        MODE_EL1H = 0x5,
573        MODE_EL2T = 0x8,
574        MODE_EL2H = 0x9,
575        MODE_EL3T = 0xC,
576        MODE_EL3H = 0xD,
577        MODE_USER = 16,
578        MODE_FIQ = 17,
579        MODE_IRQ = 18,
580        MODE_SVC = 19,
581        MODE_MON = 22,
582        MODE_ABORT = 23,
583        MODE_HYP = 26,
584        MODE_UNDEFINED = 27,
585        MODE_SYSTEM = 31,
586        MODE_MAXMODE = MODE_SYSTEM
587    };
588
589    enum ExceptionClass {
590        EC_INVALID                 = -1,
591        EC_UNKNOWN                 = 0x0,
592        EC_TRAPPED_WFI_WFE         = 0x1,
593        EC_TRAPPED_CP15_MCR_MRC    = 0x3,
594        EC_TRAPPED_CP15_MCRR_MRRC  = 0x4,
595        EC_TRAPPED_CP14_MCR_MRC    = 0x5,
596        EC_TRAPPED_CP14_LDC_STC    = 0x6,
597        EC_TRAPPED_HCPTR           = 0x7,
598        EC_TRAPPED_SIMD_FP         = 0x7,   // AArch64 alias
599        EC_TRAPPED_CP10_MRC_VMRS   = 0x8,
600        EC_TRAPPED_BXJ             = 0xA,
601        EC_TRAPPED_CP14_MCRR_MRRC  = 0xC,
602        EC_ILLEGAL_INST            = 0xE,
603        EC_SVC_TO_HYP              = 0x11,
604        EC_SVC                     = 0x11,  // AArch64 alias
605        EC_HVC                     = 0x12,
606        EC_SMC_TO_HYP              = 0x13,
607        EC_SMC                     = 0x13,  // AArch64 alias
608        EC_SVC_64                  = 0x15,
609        EC_HVC_64                  = 0x16,
610        EC_SMC_64                  = 0x17,
611        EC_TRAPPED_MSR_MRS_64      = 0x18,
612        EC_PREFETCH_ABORT_TO_HYP   = 0x20,
613        EC_PREFETCH_ABORT_LOWER_EL = 0x20,  // AArch64 alias
614        EC_PREFETCH_ABORT_FROM_HYP = 0x21,
615        EC_PREFETCH_ABORT_CURR_EL  = 0x21,  // AArch64 alias
616        EC_PC_ALIGNMENT            = 0x22,
617        EC_DATA_ABORT_TO_HYP       = 0x24,
618        EC_DATA_ABORT_LOWER_EL     = 0x24,  // AArch64 alias
619        EC_DATA_ABORT_FROM_HYP     = 0x25,
620        EC_DATA_ABORT_CURR_EL      = 0x25,  // AArch64 alias
621        EC_STACK_PTR_ALIGNMENT     = 0x26,
622        EC_FP_EXCEPTION            = 0x28,
623        EC_FP_EXCEPTION_64         = 0x2C,
624        EC_SERROR                  = 0x2F
625    };
626
627    BitUnion8(OperatingMode64)
628        Bitfield<0> spX;
629        Bitfield<3, 2> el;
630        Bitfield<4> width;
631    EndBitUnion(OperatingMode64)
632
633    static bool inline
634    opModeIs64(OperatingMode mode)
635    {
636        return ((OperatingMode64)(uint8_t)mode).width == 0;
637    }
638
639    static bool inline
640    opModeIsH(OperatingMode mode)
641    {
642        return (mode == MODE_EL1H || mode == MODE_EL2H || mode == MODE_EL3H);
643    }
644
645    static bool inline
646    opModeIsT(OperatingMode mode)
647    {
648        return (mode == MODE_EL0T || mode == MODE_EL1T || mode == MODE_EL2T ||
649                mode == MODE_EL3T);
650    }
651
652    static ExceptionLevel inline
653    opModeToEL(OperatingMode mode)
654    {
655        bool aarch32 = ((mode >> 4) & 1) ? true : false;
656        if (aarch32) {
657            switch (mode) {
658              case MODE_USER:
659                return EL0;
660              case MODE_FIQ:
661              case MODE_IRQ:
662              case MODE_SVC:
663              case MODE_ABORT:
664              case MODE_UNDEFINED:
665              case MODE_SYSTEM:
666                return EL1;
667              case MODE_HYP:
668                return EL2;
669              case MODE_MON:
670                return EL3;
671              default:
672                panic("Invalid operating mode: %d", mode);
673                break;
674            }
675        } else {
676            // aarch64
677            return (ExceptionLevel) ((mode >> 2) & 3);
678        }
679    }
680
681    static inline bool
682    badMode(OperatingMode mode)
683    {
684        switch (mode) {
685          case MODE_EL0T:
686          case MODE_EL1T:
687          case MODE_EL1H:
688          case MODE_EL2T:
689          case MODE_EL2H:
690          case MODE_EL3T:
691          case MODE_EL3H:
692          case MODE_USER:
693          case MODE_FIQ:
694          case MODE_IRQ:
695          case MODE_SVC:
696          case MODE_MON:
697          case MODE_ABORT:
698          case MODE_HYP:
699          case MODE_UNDEFINED:
700          case MODE_SYSTEM:
701            return false;
702          default:
703            return true;
704        }
705    }
706
707
708    static inline bool
709    badMode32(OperatingMode mode)
710    {
711        switch (mode) {
712          case MODE_USER:
713          case MODE_FIQ:
714          case MODE_IRQ:
715          case MODE_SVC:
716          case MODE_MON:
717          case MODE_ABORT:
718          case MODE_HYP:
719          case MODE_UNDEFINED:
720          case MODE_SYSTEM:
721            return false;
722          default:
723            return true;
724        }
725    }
726
727} // namespace ArmISA
728
729__hash_namespace_begin
730    template<>
731    struct hash<ArmISA::ExtMachInst> : public hash<uint32_t> {
732        size_t operator()(const ArmISA::ExtMachInst &emi) const {
733            return hash<uint32_t>::operator()((uint32_t)emi);
734        };
735    };
736__hash_namespace_end
737
738#endif
739