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