types.hh revision 8205
1/*
2 * Copyright (c) 2010 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
52namespace ArmISA
53{
54    typedef uint32_t MachInst;
55
56    BitUnion8(ITSTATE)
57        /* Note that the split (cond, mask) below is not as in ARM ARM.
58         * But it is more convenient for simulation. The condition
59         * is always the concatenation of the top 3 bits and the next bit,
60         * which applies when one of the bottom 4 bits is set.
61         * Refer to predecoder.cc for the use case.
62         */
63        Bitfield<7, 4> cond;
64        Bitfield<3, 0> mask;
65        // Bitfields for moving to/from CPSR
66        Bitfield<7, 2> top6;
67        Bitfield<1, 0> bottom2;
68    EndBitUnion(ITSTATE)
69
70
71    BitUnion64(ExtMachInst)
72        // ITSTATE bits
73        Bitfield<55, 48> itstate;
74        Bitfield<55, 52> itstateCond;
75        Bitfield<51, 48> itstateMask;
76
77        // FPSCR fields
78        Bitfield<41, 40> fpscrStride;
79        Bitfield<39, 37> fpscrLen;
80
81        // Bitfields to select mode.
82        Bitfield<36>     thumb;
83        Bitfield<35>     bigThumb;
84
85        // Made up bitfields that make life easier.
86        Bitfield<33>     sevenAndFour;
87        Bitfield<32>     isMisc;
88
89        uint32_t         instBits;
90
91        // All the different types of opcode fields.
92        Bitfield<27, 25> encoding;
93        Bitfield<25>     useImm;
94        Bitfield<24, 21> opcode;
95        Bitfield<24, 20> mediaOpcode;
96        Bitfield<24>     opcode24;
97        Bitfield<24, 23> opcode24_23;
98        Bitfield<23, 20> opcode23_20;
99        Bitfield<23, 21> opcode23_21;
100        Bitfield<20>     opcode20;
101        Bitfield<22>     opcode22;
102        Bitfield<19, 16> opcode19_16;
103        Bitfield<19>     opcode19;
104        Bitfield<18>     opcode18;
105        Bitfield<15, 12> opcode15_12;
106        Bitfield<15>     opcode15;
107        Bitfield<7,  4>  miscOpcode;
108        Bitfield<7,5>    opc2;
109        Bitfield<7>      opcode7;
110        Bitfield<6>      opcode6;
111        Bitfield<4>      opcode4;
112
113        Bitfield<31, 28> condCode;
114        Bitfield<20>     sField;
115        Bitfield<19, 16> rn;
116        Bitfield<15, 12> rd;
117        Bitfield<15, 12> rt;
118        Bitfield<11, 7>  shiftSize;
119        Bitfield<6,  5>  shift;
120        Bitfield<3,  0>  rm;
121
122        Bitfield<11, 8>  rs;
123
124        SubBitUnion(puswl, 24, 20)
125            Bitfield<24> prepost;
126            Bitfield<23> up;
127            Bitfield<22> psruser;
128            Bitfield<21> writeback;
129            Bitfield<20> loadOp;
130        EndSubBitUnion(puswl)
131
132        Bitfield<24, 20> pubwl;
133
134        Bitfield<7, 0> imm;
135
136        Bitfield<11, 8>  rotate;
137
138        Bitfield<11, 0>  immed11_0;
139        Bitfield<7,  0>  immed7_0;
140
141        Bitfield<11, 8>  immedHi11_8;
142        Bitfield<3,  0>  immedLo3_0;
143
144        Bitfield<15, 0>  regList;
145
146        Bitfield<23, 0>  offset;
147
148        Bitfield<23, 0>  immed23_0;
149
150        Bitfield<11, 8>  cpNum;
151        Bitfield<18, 16> fn;
152        Bitfield<14, 12> fd;
153        Bitfield<3>      fpRegImm;
154        Bitfield<3,  0>  fm;
155        Bitfield<2,  0>  fpImm;
156        Bitfield<24, 20> punwl;
157
158        Bitfield<15,  8>  m5Func;
159
160        // 16 bit thumb bitfields
161        Bitfield<15, 13> topcode15_13;
162        Bitfield<13, 11> topcode13_11;
163        Bitfield<12, 11> topcode12_11;
164        Bitfield<12, 10> topcode12_10;
165        Bitfield<11, 9>  topcode11_9;
166        Bitfield<11, 8>  topcode11_8;
167        Bitfield<10, 9>  topcode10_9;
168        Bitfield<10, 8>  topcode10_8;
169        Bitfield<9,  6>  topcode9_6;
170        Bitfield<7>      topcode7;
171        Bitfield<7, 6>   topcode7_6;
172        Bitfield<7, 5>   topcode7_5;
173        Bitfield<7, 4>   topcode7_4;
174        Bitfield<3, 0>   topcode3_0;
175
176        // 32 bit thumb bitfields
177        Bitfield<28, 27> htopcode12_11;
178        Bitfield<26, 25> htopcode10_9;
179        Bitfield<25>     htopcode9;
180        Bitfield<25, 24> htopcode9_8;
181        Bitfield<25, 21> htopcode9_5;
182        Bitfield<25, 20> htopcode9_4;
183        Bitfield<24>     htopcode8;
184        Bitfield<24, 23> htopcode8_7;
185        Bitfield<24, 22> htopcode8_6;
186        Bitfield<24, 21> htopcode8_5;
187        Bitfield<23>     htopcode7;
188        Bitfield<23, 21> htopcode7_5;
189        Bitfield<22>     htopcode6;
190        Bitfield<22, 21> htopcode6_5;
191        Bitfield<21, 20> htopcode5_4;
192        Bitfield<20>     htopcode4;
193
194        Bitfield<19, 16> htrn;
195        Bitfield<20>     hts;
196
197        Bitfield<15>     ltopcode15;
198        Bitfield<11, 8>  ltopcode11_8;
199        Bitfield<7,  6>  ltopcode7_6;
200        Bitfield<7,  4>  ltopcode7_4;
201        Bitfield<4>      ltopcode4;
202
203        Bitfield<11, 8>  ltrd;
204        Bitfield<11, 8>  ltcoproc;
205    EndBitUnion(ExtMachInst)
206
207    class PCState : public GenericISA::UPCState<MachInst>
208    {
209      protected:
210
211        typedef GenericISA::UPCState<MachInst> Base;
212
213        enum FlagBits {
214            ThumbBit = (1 << 0),
215            JazelleBit = (1 << 1)
216        };
217        uint8_t flags;
218        uint8_t nextFlags;
219        uint8_t _itstate;
220        uint8_t _nextItstate;
221        uint8_t _size;
222      public:
223        PCState() : flags(0), nextFlags(0), _itstate(0), _nextItstate(0)
224        {}
225
226        void
227        set(Addr val)
228        {
229            Base::set(val);
230            npc(val + (thumb() ? 2 : 4));
231        }
232
233        PCState(Addr val) : flags(0), nextFlags(0), _itstate(0), _nextItstate(0)
234        { set(val); }
235
236        bool
237        thumb() const
238        {
239            return flags & ThumbBit;
240        }
241
242        void
243        thumb(bool val)
244        {
245            if (val)
246                flags |= ThumbBit;
247            else
248                flags &= ~ThumbBit;
249        }
250
251        bool
252        nextThumb() const
253        {
254            return nextFlags & ThumbBit;
255        }
256
257        void
258        nextThumb(bool val)
259        {
260            if (val)
261                nextFlags |= ThumbBit;
262            else
263                nextFlags &= ~ThumbBit;
264        }
265
266        void size(uint8_t s) { _size = s; }
267        uint8_t size() const { return _size; }
268
269        bool
270        branching() const
271        {
272            return ((this->pc() + this->size()) != this->npc());
273        }
274
275
276        bool
277        jazelle() const
278        {
279            return flags & JazelleBit;
280        }
281
282        void
283        jazelle(bool val)
284        {
285            if (val)
286                flags |= JazelleBit;
287            else
288                flags &= ~JazelleBit;
289        }
290
291        bool
292        nextJazelle() const
293        {
294            return nextFlags & JazelleBit;
295        }
296
297        void
298        nextJazelle(bool val)
299        {
300            if (val)
301                nextFlags |= JazelleBit;
302            else
303                nextFlags &= ~JazelleBit;
304        }
305
306        uint8_t
307        itstate() const
308        {
309            return _itstate;
310        }
311
312        void
313        itstate(uint8_t value)
314        {
315            _itstate = value;
316        }
317
318        uint8_t
319        nextItstate() const
320        {
321            return _nextItstate;
322        }
323
324        void
325        nextItstate(uint8_t value)
326        {
327            _nextItstate = value;
328        }
329
330        void
331        advance()
332        {
333            Base::advance();
334            npc(pc() + (thumb() ? 2 : 4));
335            flags = nextFlags;
336
337            if (_nextItstate) {
338                _itstate = _nextItstate;
339                _nextItstate = 0;
340            } else if (_itstate) {
341                ITSTATE it = _itstate;
342                uint8_t cond_mask = it.mask;
343                uint8_t thumb_cond = it.cond;
344                DPRINTF(Predecoder, "Advancing ITSTATE from %#x,%#x.\n",
345                        thumb_cond, cond_mask);
346                cond_mask <<= 1;
347                uint8_t new_bit = bits(cond_mask, 4);
348                cond_mask &= mask(4);
349                if (cond_mask == 0)
350                    thumb_cond = 0;
351                else
352                    replaceBits(thumb_cond, 0, new_bit);
353                DPRINTF(Predecoder, "Advancing ITSTATE to %#x,%#x.\n",
354                        thumb_cond, cond_mask);
355                it.mask = cond_mask;
356                it.cond = thumb_cond;
357                _itstate = it;
358            }
359        }
360
361        void
362        uEnd()
363        {
364            advance();
365            upc(0);
366            nupc(1);
367        }
368
369        Addr
370        instPC() const
371        {
372            return pc() + (thumb() ? 4 : 8);
373        }
374
375        void
376        instNPC(uint32_t val)
377        {
378            npc(val &~ mask(nextThumb() ? 1 : 2));
379        }
380
381        Addr
382        instNPC() const
383        {
384            return npc();
385        }
386
387        // Perform an interworking branch.
388        void
389        instIWNPC(uint32_t val)
390        {
391            bool thumbEE = (thumb() && jazelle());
392
393            Addr newPC = val;
394            if (thumbEE) {
395                if (bits(newPC, 0)) {
396                    newPC = newPC & ~mask(1);
397                }  // else we have a bad interworking address; do not call
398                   // panic() since the instruction could be executed
399                   // speculatively
400            } else {
401                if (bits(newPC, 0)) {
402                    nextThumb(true);
403                    newPC = newPC & ~mask(1);
404                } else if (!bits(newPC, 1)) {
405                    nextThumb(false);
406                } else {
407                    // This state is UNPREDICTABLE in the ARM architecture
408                    // The easy thing to do is just mask off the bit and
409                    // stay in the current mode, so we'll do that.
410                    newPC &= ~mask(2);
411                }
412            }
413            npc(newPC);
414        }
415
416        // Perform an interworking branch in ARM mode, a regular branch
417        // otherwise.
418        void
419        instAIWNPC(uint32_t val)
420        {
421            if (!thumb() && !jazelle())
422                instIWNPC(val);
423            else
424                instNPC(val);
425        }
426
427        bool
428        operator == (const PCState &opc) const
429        {
430            return Base::operator == (opc) &&
431                flags == opc.flags && nextFlags == opc.nextFlags &&
432                _itstate == opc._itstate && _nextItstate == opc._nextItstate;
433        }
434
435        void
436        serialize(std::ostream &os)
437        {
438            Base::serialize(os);
439            SERIALIZE_SCALAR(flags);
440            SERIALIZE_SCALAR(_size);
441            SERIALIZE_SCALAR(nextFlags);
442            SERIALIZE_SCALAR(_itstate);
443            SERIALIZE_SCALAR(_nextItstate);
444        }
445
446        void
447        unserialize(Checkpoint *cp, const std::string &section)
448        {
449            Base::unserialize(cp, section);
450            UNSERIALIZE_SCALAR(flags);
451            UNSERIALIZE_SCALAR(_size);
452            UNSERIALIZE_SCALAR(nextFlags);
453            UNSERIALIZE_SCALAR(_itstate);
454            UNSERIALIZE_SCALAR(_nextItstate);
455        }
456    };
457
458    // Shift types for ARM instructions
459    enum ArmShiftType {
460        LSL = 0,
461        LSR,
462        ASR,
463        ROR
464    };
465
466    typedef uint64_t LargestRead;
467    // Need to use 64 bits to make sure that read requests get handled properly
468
469    typedef int RegContextParam;
470    typedef int RegContextVal;
471
472    //used in FP convert & round function
473    enum ConvertType{
474        SINGLE_TO_DOUBLE,
475        SINGLE_TO_WORD,
476        SINGLE_TO_LONG,
477
478        DOUBLE_TO_SINGLE,
479        DOUBLE_TO_WORD,
480        DOUBLE_TO_LONG,
481
482        LONG_TO_SINGLE,
483        LONG_TO_DOUBLE,
484        LONG_TO_WORD,
485        LONG_TO_PS,
486
487        WORD_TO_SINGLE,
488        WORD_TO_DOUBLE,
489        WORD_TO_LONG,
490        WORD_TO_PS,
491
492        PL_TO_SINGLE,
493        PU_TO_SINGLE
494    };
495
496    //used in FP convert & round function
497    enum RoundMode{
498        RND_ZERO,
499        RND_DOWN,
500        RND_UP,
501        RND_NEAREST
502    };
503
504    enum OperatingMode {
505        MODE_USER = 16,
506        MODE_FIQ = 17,
507        MODE_IRQ = 18,
508        MODE_SVC = 19,
509        MODE_MON = 22,
510        MODE_ABORT = 23,
511        MODE_UNDEFINED = 27,
512        MODE_SYSTEM = 31,
513        MODE_MAXMODE = MODE_SYSTEM
514    };
515
516    static inline bool
517    badMode(OperatingMode mode)
518    {
519        switch (mode) {
520          case MODE_USER:
521          case MODE_FIQ:
522          case MODE_IRQ:
523          case MODE_SVC:
524          case MODE_MON:
525          case MODE_ABORT:
526          case MODE_UNDEFINED:
527          case MODE_SYSTEM:
528            return false;
529          default:
530            return true;
531        }
532    }
533
534} // namespace ArmISA
535
536namespace __hash_namespace {
537    template<>
538    struct hash<ArmISA::ExtMachInst> : public hash<uint32_t> {
539        size_t operator()(const ArmISA::ExtMachInst &emi) const {
540            return hash<uint32_t>::operator()((uint32_t)emi);
541        };
542    };
543}
544
545#endif
546