isa_traits.hh revision 2125
1/*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef __ARCH_MIPS_ISA_TRAITS_HH__
30#define __ARCH_MIPS_ISA_TRAITS_HH__
31
32//This makes sure the big endian versions of certain functions are used.
33namespace LittleEndianGuest {}
34using namespace LittleEndianGuest
35
36#include "arch/mips/faults.hh"
37#include "base/misc.hh"
38#include "sim/host.hh"
39
40class FastCPU;
41class FullCPU;
42class Checkpoint;
43
44#define TARGET_MIPS
45
46template <class ISA> class StaticInst;
47template <class ISA> class StaticInstPtr;
48
49//namespace MIPS34K
50//{
51//	int DTB_ASN_ASN(uint64_t reg);
52//	int ITB_ASN_ASN(uint64_t reg);
53//}
54
55class MipsISA
56{
57        public:
58
59        typedef uint32_t MachInst;
60        typedef uint64_t Addr;
61        typedef uint8_t  RegIndex;
62
63        enum
64        {
65                MemoryEnd = 0xffffffffffffffffULL,
66
67                NumFloatRegs = 32,
68                NumMiscRegs = 32,
69
70                MaxRegsOfAnyType = 32,
71                // Static instruction parameters
72                MaxInstSrcRegs = 3,
73                MaxInstDestRegs = 2,
74
75                // Maximum trap level
76                MaxTL = 4
77
78                // semantically meaningful register indices
79                ZeroReg = 0,	// architecturally meaningful
80                // the rest of these depend on the ABI
81        }
82        typedef uint64_t IntReg;
83
84        class IntRegFile
85        {
86        private:
87                //For right now, let's pretend the register file is static
88                IntReg regs[32];
89        public:
90                IntReg & operator [] (RegIndex index)
91                {
92                        //Don't allow indexes outside of the 32 registers
93                        index &= 0x1F
94                        return regs[index];
95                }
96        };
97
98        void inline serialize(std::ostream & os)
99        {
100                SERIALIZE_ARRAY(regs, 32);
101        }
102
103        void inline unserialize(Checkpoint &*cp, const std::string &section)
104        {
105                UNSERIALIZE_ARRAY(regs, 32);
106        }
107
108        class FloatRegFile
109        {
110        private:
111                //By using the largest data type, we ensure everything
112                //is aligned correctly in memory
113                union
114                {
115                        double double rawRegs[16];
116                        uint64_t regDump[32];
117                };
118                class QuadRegs
119                {
120                        private:
121                                FloatRegFile * parent;
122                        public:
123                                QuadRegs(FloatRegFile * p) : parent(p) {;}
124                                double double & operator [] (RegIndex index)
125                                {
126                                        //Quad floats are index by the single
127                                        //precision register the start on,
128                                        //and only 16 should be accessed
129                                        index = (index >> 2) & 0xF;
130                                        return parent->rawRegs[index];
131                                }
132                };
133                class DoubleRegs
134                {
135                        private:
136                                FloatRegFile * parent;
137                        public:
138                                DoubleRegs(FloatRegFile * p) : parent(p) {;}
139                                double & operator [] (RegIndex index)
140                                {
141                                        //Double floats are index by the single
142                                        //precision register the start on,
143                                        //and only 32 should be accessed
144                                        index = (index >> 1) & 0x1F
145                                        return ((double [])parent->rawRegs)[index];
146                                }
147                }
148                class SingleRegs
149                {
150                        private:
151                                FloatRegFile * parent;
152                                public:
153                                SingleRegs(FloatRegFile * p) : parent(p) {;}
154                                double & operator [] (RegFile index)
155                                {
156                                        //Only 32 single floats should be accessed
157                                        index &= 0x1F
158                                        return ((float [])parent->rawRegs)[index];
159                                }
160                }
161        public:
162                void inline serialize(std::ostream & os)
163                {
164                        SERIALIZE_ARRAY(regDump, 32);
165                }
166
167                void inline unserialize(Checkpoint &* cp, std::string & section)
168                {
169                        UNSERIALIZE_ARRAY(regDump, 32);
170                }
171
172                QuadRegs quadRegs;
173                DoubleRegs doubleRegs;
174                SingleRegs singleRegs;
175                FloatRegFile() : quadRegs(this), doubleRegs(this), singleRegs(this)
176                {;}
177        };
178
179        // control register file contents
180        typedef uint64_t MiscReg;
181        // The control registers, broken out into fields
182        class MiscRegFile
183        {
184        public:
185                union
186                {
187                        uint16_t pstate;		// Process State Register
188                        struct
189                        {
190                                uint16_t ag:1;		// Alternate Globals
191                                uint16_t ie:1;		// Interrupt enable
192                                uint16_t priv:1;	// Privelege mode
193                                uint16_t am:1;		// Address mask
194                                uint16_t pef:1;		// PSTATE enable floating-point
195                                uint16_t red:1;		// RED (reset, error, debug) state
196                                uint16_t mm:2;		// Memory Model
197                                uint16_t tle:1;		// Trap little-endian
198                                uint16_t cle:1;		// Current little-endian
199                        } pstateFields;
200                }
201                uint64_t tba;		// Trap Base Address
202                union
203                {
204                        uint64_t y;		// Y (used in obsolete multiplication)
205                        struct
206                        {
207                                uint64_t value:32;	// The actual value stored in y
208                                const uint64_t :32;	// reserved bits
209                        } yFields;
210                }
211                uint8_t pil;		// Process Interrupt Register
212                uint8_t cwp;		// Current Window Pointer
213                uint16_t tt[MaxTL];	// Trap Type (Type of trap which occured on the previous level)
214                union
215                {
216                        uint8_t	ccr;		// Condition Code Register
217                        struct
218                        {
219                                union
220                                {
221                                        uint8_t icc:4;	// 32-bit condition codes
222                                        struct
223                                        {
224                                                uint8_t c:1;	// Carry
225                                                uint8_t v:1;	// Overflow
226                                                uint8_t z:1;	// Zero
227                                                uint8_t n:1;	// Negative
228                                        } iccFields:4;
229                                } :4;
230                                union
231                                {
232                                        uint8_t xcc:4;	// 64-bit condition codes
233                                        struct
234                                        {
235                                                uint8_t c:1;	// Carry
236                                                uint8_t v:1;	// Overflow
237                                                uint8_t z:1;	// Zero
238                                                uint8_t n:1;	// Negative
239                                        } xccFields:4;
240                                } :4;
241                        } ccrFields;
242                }
243                uint8_t asi;		// Address Space Identifier
244                uint8_t tl;		// Trap Level
245                uint64_t tpc[MaxTL];	// Trap Program Counter (value from previous trap level)
246                uint64_t tnpc[MaxTL];	// Trap Next Program Counter (value from previous trap level)
247                union
248                {
249                        uint64_t tstate[MaxTL];	// Trap State
250                        struct
251                        {
252                                //Values are from previous trap level
253                                uint64_t cwp:5;		// Current Window Pointer
254                                const uint64_t :2;	// Reserved bits
255                                uint64_t pstate:10;	// Process State
256                                const uint64_t :6;	// Reserved bits
257                                uint64_t asi:8;		// Address Space Identifier
258                                uint64_t ccr:8;		// Condition Code Register
259                        } tstateFields[MaxTL];
260                }
261                union
262                {
263                        uint64_t	tick;		// Hardware clock-tick counter
264                        struct
265                        {
266                                uint64_t counter:63;	// Clock-tick count
267                                uint64_t npt:1;		// Non-priveleged trap
268                        } tickFields;
269                }
270                uint8_t cansave;	// Savable windows
271                uint8_t canrestore;	// Restorable windows
272                uint8_t otherwin;	// Other windows
273                uint8_t cleanwin;	// Clean windows
274                union
275                {
276                        uint8_t wstate;		// Window State
277                        struct
278                        {
279                                uint8_t normal:3;	// Bits TT<4:2> are set to on a normal
280                                                        // register window trap
281                                uint8_t other:3;	// Bits TT<4:2> are set to on an "otherwin"
282                                                        // register window trap
283                        } wstateFields;
284                }
285                union
286                {
287                        uint64_t ver;		// Version
288                        struct
289                        {
290                                uint64_t maxwin:5;	// Max CWP value
291                                const uint64_t :2;	// Reserved bits
292                                uint64_t maxtl:8;	// Maximum trap level
293                                const uint64_t :8;	// Reserved bits
294                                uint64_t mask:8;	// Processor mask set revision number
295                                uint64_t impl:16;	// Implementation identification number
296                                uint64_t manuf:16;	// Manufacturer code
297                        } verFields;
298                }
299                union
300                {
301                        uint64_t	fsr;	// Floating-Point State Register
302                        struct
303                        {
304                                union
305                                {
306                                        uint64_t cexc:5;	// Current excpetion
307                                        struct
308                                        {
309                                                uint64_t nxc:1;		// Inexact
310                                                uint64_t dzc:1;		// Divide by zero
311                                                uint64_t ufc:1;		// Underflow
312                                                uint64_t ofc:1;		// Overflow
313                                                uint64_t nvc:1;		// Invalid operand
314                                        } cexecFields:5;
315                                } :5;
316                                union
317                                {
318                                        uint64_t aexc:5;		// Accrued exception
319                                        struct
320                                        {
321                                                uint64_t nxc:1;		// Inexact
322                                                uint64_t dzc:1;		// Divide by zero
323                                                uint64_t ufc:1;		// Underflow
324                                                uint64_t ofc:1;		// Overflow
325                                                uint64_t nvc:1;		// Invalid operand
326                                        } aexecFields:5;
327                                } :5;
328                                uint64_t fcc0:2;		// Floating-Point condtion codes
329                                const uint64_t :1;		// Reserved bits
330                                uint64_t qne:1;			// Deferred trap queue not empty
331                                                                // with no queue, it should read 0
332                                uint64_t ftt:3;			// Floating-Point trap type
333                                uint64_t ver:3;			// Version (of the FPU)
334                                const uint64_t :2;		// Reserved bits
335                                uint64_t ns:1;			// Nonstandard floating point
336                                union
337                                {
338                                        uint64_t tem:5;			// Trap Enable Mask
339                                        struct
340                                        {
341                                                uint64_t nxm:1;		// Inexact
342                                                uint64_t dzm:1;		// Divide by zero
343                                                uint64_t ufm:1;		// Underflow
344                                                uint64_t ofm:1;		// Overflow
345                                                uint64_t nvm:1;		// Invalid operand
346                                        } temFields:5;
347                                } :5;
348                                const uint64_t :2;		// Reserved bits
349                                uint64_t rd:2;			// Rounding direction
350                                uint64_t fcc1:2;		// Floating-Point condition codes
351                                uint64_t fcc2:2;		// Floating-Point condition codes
352                                uint64_t fcc3:2;		// Floating-Point condition codes
353                                const uint64_t :26;		// Reserved bits
354                        } fsrFields;
355                }
356                union
357                {
358                        uint8_t		fprs;	// Floating-Point Register State
359                        struct
360                        {
361                                dl:1;		// Dirty lower
362                                du:1;		// Dirty upper
363                                fef:1;		// FPRS enable floating-Point
364                        } fprsFields;
365                };
366
367                void serialize(std::ostream & os)
368                {
369                        SERIALIZE_SCALAR(pstate);
370                        SERIAlIZE_SCALAR(tba);
371                        SERIALIZE_SCALAR(y);
372                        SERIALIZE_SCALAR(pil);
373                        SERIALIZE_SCALAR(cwp);
374                        SERIALIZE_ARRAY(tt, MaxTL);
375                        SERIALIZE_SCALAR(ccr);
376                        SERIALIZE_SCALAR(asi);
377                        SERIALIZE_SCALAR(tl);
378                        SERIALIZE_SCALAR(tpc);
379                        SERIALIZE_SCALAR(tnpc);
380                        SERIALIZE_ARRAY(tstate, MaxTL);
381                        SERIALIZE_SCALAR(tick);
382                        SERIALIZE_SCALAR(cansave);
383                        SERIALIZE_SCALAR(canrestore);
384                        SERIALIZE_SCALAR(otherwin);
385                        SERIALIZE_SCALAR(cleanwin);
386                        SERIALIZE_SCALAR(wstate);
387                        SERIALIZE_SCALAR(ver);
388                        SERIALIZE_SCALAR(fsr);
389                        SERIALIZE_SCALAR(fprs);
390                }
391
392                void unserialize(Checkpoint &* cp, std::string & section)
393                {
394                        UNSERIALIZE_SCALAR(pstate);
395                        UNSERIAlIZE_SCALAR(tba);
396                        UNSERIALIZE_SCALAR(y);
397                        UNSERIALIZE_SCALAR(pil);
398                        UNSERIALIZE_SCALAR(cwp);
399                        UNSERIALIZE_ARRAY(tt, MaxTL);
400                        UNSERIALIZE_SCALAR(ccr);
401                        UNSERIALIZE_SCALAR(asi);
402                        UNSERIALIZE_SCALAR(tl);
403                        UNSERIALIZE_SCALAR(tpc);
404                        UNSERIALIZE_SCALAR(tnpc);
405                        UNSERIALIZE_ARRAY(tstate, MaxTL);
406                        UNSERIALIZE_SCALAR(tick);
407                        UNSERIALIZE_SCALAR(cansave);
408                        UNSERIALIZE_SCALAR(canrestore);
409                        UNSERIALIZE_SCALAR(otherwin);
410                        UNSERIALIZE_SCALAR(cleanwin);
411                        UNSERIALIZE_SCALAR(wstate);
412                        UNSERIALIZE_SCALAR(ver);
413                        UNSERIALIZE_SCALAR(fsr);
414                        UNSERIALIZE_SCALAR(fprs);
415                }
416        };
417
418        typedef union
419        {
420                IntReg  intreg;
421                FloatReg   fpreg;
422                MiscReg ctrlreg;
423        } AnyReg;
424
425        struct RegFile
426        {
427                IntRegFile intRegFile;		// (signed) integer register file
428                FloatRegFile floatRegFile;	// floating point register file
429                MiscRegFile miscRegFile;	// control register file
430
431                Addr pc;		// Program Counter
432                Addr npc;		// Next Program Counter
433            Addr nnpc;                  // Next next program Counter
434
435
436                void serialize(std::ostream &os);
437                void unserialize(Checkpoint *cp, const std::string &section);
438        };
439
440        static StaticInstPtr<MipsISA> decodeInst(MachInst);
441
442        // return a no-op instruction... used for instruction fetch faults
443        static const MachInst NoopMachInst;
444
445        // Instruction address compression hooks
446        static inline Addr realPCToFetchPC(const Addr &addr)
447        {
448                return addr;
449        }
450
451        static inline Addr fetchPCToRealPC(const Addr &addr)
452        {
453                return addr;
454        }
455
456        // the size of "fetched" instructions (not necessarily the size
457        // of real instructions for PISA)
458        static inline size_t fetchInstSize()
459        {
460                return sizeof(MachInst);
461        }
462
463        /**
464         * Function to insure ISA semantics about 0 registers.
465         * @param xc The execution context.
466         */
467        template <class XC>
468        static void zeroRegisters(XC *xc);
469};
470
471
472typedef MIPSISA TheISA;
473
474typedef TheISA::MachInst MachInst;
475typedef TheISA::Addr Addr;
476typedef TheISA::RegIndex RegIndex;
477typedef TheISA::IntReg IntReg;
478typedef TheISA::IntRegFile IntRegFile;
479typedef TheISA::FloatReg FloatReg;
480typedef TheISA::FloatRegFile FloatRegFile;
481typedef TheISA::MiscReg MiscReg;
482typedef TheISA::MiscRegFile MiscRegFile;
483typedef TheISA::AnyReg AnyReg;
484typedef TheISA::RegFile RegFile;
485
486const int VMPageSize   = TheISA::VMPageSize;
487const int LogVMPageSize   = TheISA::LogVMPageSize;
488const int ZeroReg = TheISA::ZeroReg;
489const int BranchPredAddrShiftAmt = TheISA::BranchPredAddrShiftAmt;
490const int MaxAddr = (Addr)-1;
491
492#ifndef FULL_SYSTEM
493class SyscallReturn {
494        public:
495           template <class T>
496           SyscallReturn(T v, bool s)
497           {
498               retval = (uint64_t)v;
499               success = s;
500           }
501
502           template <class T>
503           SyscallReturn(T v)
504           {
505               success = (v >= 0);
506               retval = (uint64_t)v;
507           }
508
509           ~SyscallReturn() {}
510
511           SyscallReturn& operator=(const SyscallReturn& s) {
512               retval = s.retval;
513               success = s.success;
514               return *this;
515           }
516
517           bool successful() { return success; }
518           uint64_t value() { return retval; }
519
520
521       private:
522           uint64_t retval;
523           bool success;
524};
525
526#endif
527
528
529#ifdef FULL_SYSTEM
530
531#include "arch/mips/mips34k.hh"
532#endif
533
534#endif // __ARCH_MIPS_ISA_TRAITS_HH__
535