registers.hh revision 2459
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_SPARC_REGFILE_HH__
30#define __ARCH_SPARC_REGFILE_HH__
31
32#include "arch/sparc/faults.hh"
33#include "sim/byteswap.hh"
34#include "sim/host.hh"
35
36class Checkpoint;
37
38namespace SparcISA
39{
40
41    typedef uint8_t  RegIndex;
42
43    // Maximum trap level
44    const int MaxTL = 4;
45
46    //For right now, let's pretend the register file is flat
47    typedef IntReg IntRegFile[NumIntRegs];
48
49    typedef float float32_t;
50    typedef double float64_t;
51    //FIXME long double refers to a 10 byte float, rather than a
52    //16 byte float as required. This data type may have to be emulated.
53    typedef double float128_t;
54
55    class FloatRegFile
56    {
57      protected:
58        //Since the floating point registers overlap each other,
59        //A generic storage space is used. The float to be returned is
60        //pulled from the appropriate section of this region.
61        char regSpace[32 * 64];
62
63        static const int SingleWidth = 32;
64        static const int DoubleWidth = 64;
65        static const int QuadWidth = 128;
66
67      public:
68
69        FloatReg readReg(int floatReg, int width)
70        {
71            //In each of these cases, we have to copy the value into a temporary
72            //variable. This is because we may otherwise try to access an
73            //unaligned portion of memory.
74            switch(width)
75            {
76              case SingleWidth:
77                float32_t result32;
78                memcpy(&result32, regSpace + 4 * floatReg, width);
79                return htog(result32);
80              case DoubleWidth:
81                float64_t result64;
82                memcpy(&result64, regSpace + 4 * floatReg, width);
83                return htog(result64);
84              case QuadWidth:
85                float128_t result128;
86                memcpy(&result128, regSpace + 4 * floatReg, width);
87                return htog(result128);
88              default:
89                panic("Attempted to read a %d bit floating point register!", width);
90            }
91        }
92
93        FloatReg readReg(int floatReg)
94        {
95            //Use the "natural" width of a single float
96            return readReg(floatReg, SingleWidth);
97        }
98
99        FloatRegBits readRegBits(int floatReg, int width)
100        {
101            //In each of these cases, we have to copy the value into a temporary
102            //variable. This is because we may otherwise try to access an
103            //unaligned portion of memory.
104            switch(width)
105            {
106              case SingleWidth:
107                uint32_t result32;
108                memcpy(&result32, regSpace + 4 * floatReg, width);
109                return htog(result32);
110              case DoubleWidth:
111                uint64_t result64;
112                memcpy(&result64, regSpace + 4 * floatReg, width);
113                return htog(result64);
114              case QuadWidth:
115                uint64_t result128;
116                memcpy(&result128, regSpace + 4 * floatReg, width);
117                return htog(result128);
118              default:
119                panic("Attempted to read a %d bit floating point register!", width);
120            }
121        }
122
123        FloatRegBits readRegBits(int floatReg)
124        {
125            //Use the "natural" width of a single float
126            return readRegBits(floatReg, SingleWidth);
127        }
128
129        Fault setReg(int floatReg, const FloatReg &val, int width)
130        {
131            //In each of these cases, we have to copy the value into a temporary
132            //variable. This is because we may otherwise try to access an
133            //unaligned portion of memory.
134            switch(width)
135            {
136              case SingleWidth:
137                uint32_t result32 = gtoh((uint32_t)val);
138                memcpy(regSpace + 4 * floatReg, &result32, width);
139              case DoubleWidth:
140                uint64_t result64 = gtoh((uint64_t)val);
141                memcpy(regSpace + 4 * floatReg, &result64, width);
142              case QuadWidth:
143                uint64_t result128 = gtoh((uint64_t)val);
144                memcpy(regSpace + 4 * floatReg, &result128, width);
145              default:
146                panic("Attempted to read a %d bit floating point register!", width);
147            }
148            return NoFault;
149        }
150
151        Fault setReg(int floatReg, const FloatReg &val)
152        {
153            //Use the "natural" width of a single float
154            return setReg(floatReg, val, SingleWidth);
155        }
156
157        Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
158        {
159            //In each of these cases, we have to copy the value into a temporary
160            //variable. This is because we may otherwise try to access an
161            //unaligned portion of memory.
162            switch(width)
163            {
164              case SingleWidth:
165                uint32_t result32 = gtoh((uint32_t)val);
166                memcpy(regSpace + 4 * floatReg, &result32, width);
167              case DoubleWidth:
168                uint64_t result64 = gtoh((uint64_t)val);
169                memcpy(regSpace + 4 * floatReg, &result64, width);
170              case QuadWidth:
171                uint64_t result128 = gtoh((uint64_t)val);
172                memcpy(regSpace + 4 * floatReg, &result128, width);
173              default:
174                panic("Attempted to read a %d bit floating point register!", width);
175            }
176            return NoFault;
177        }
178
179        Fault setRegBits(int floatReg, const FloatRegBits &val)
180        {
181            //Use the "natural" width of a single float
182            return setReg(floatReg, val, SingleWidth);
183        }
184
185        void serialize(std::ostream &os);
186
187        void unserialize(Checkpoint *cp, const std::string &section);
188    };
189
190    enum MiscRegIndex
191    {
192        MISCREG_PSTATE,
193        MISCREG_PSTATE_AG,
194        MISCREG_PSTATE_IE,
195        MISCREG_PSTATE_PRIV,
196        MISCREG_PSTATE_AM,
197        MISCREG_PSTATE_PEF,
198        MISCREG_PSTATE_RED,
199        MISCREG_PSTATE_MM,
200        MISCREG_PSTATE_TLE,
201        MISCREG_PSTATE_CLE,
202        MISCREG_TBA,
203        MISCREG_Y,
204        MISCREG_Y_VALUE,
205        MISCREG_PIL,
206        MISCREG_CWP,
207        MISCREG_TT_BASE,
208        MISCREG_TT_END = MISCREG_TT_BASE + MaxTL,
209        MISCREG_CCR,
210        MISCREG_CCR_ICC,
211        MISCREG_CCR_ICC_C,
212        MISCREG_CCR_ICC_V,
213        MISCREG_CCR_ICC_Z,
214        MISCREG_CCR_ICC_N,
215        MISCREG_CCR_XCC,
216        MISCREG_CCR_XCC_C,
217        MISCREG_CCR_XCC_V,
218        MISCREG_CCR_XCC_Z,
219        MISCREG_CCR_XCC_N,
220        MISCREG_ASI,
221        MISCREG_TL,
222        MISCREG_TPC_BASE,
223        MISCREG_TPC_END = MISCREG_TPC_BASE + MaxTL,
224        MISCREG_TNPC_BASE,
225        MISCREG_TNPC_END = MISCREG_TNPC_BASE + MaxTL,
226        MISCREG_TSTATE_BASE,
227        MISCREG_TSTATE_END = MISCREG_TSTATE_BASE + MaxTL,
228        MISCREG_TSTATE_CWP_BASE,
229        MISCREG_TSTATE_CWP_END = MISCREG_TSTATE_CWP_BASE + MaxTL,
230        MISCREG_TSTATE_PSTATE_BASE,
231        MISCREG_TSTATE_PSTATE_END = MISCREG_TSTATE_PSTATE_BASE + MaxTL,
232        MISCREG_TSTATE_ASI_BASE,
233        MISCREG_TSTATE_ASI_END = MISCREG_TSTATE_ASI_BASE + MaxTL,
234        MISCREG_TSTATE_CCR_BASE,
235        MISCREG_TSTATE_CCR_END = MISCREG_TSTATE_CCR_BASE + MaxTL,
236        MISCREG_TICK,
237        MISCREG_TICK_COUNTER,
238        MISCREG_TICK_NPT,
239        MISCREG_CANSAVE,
240        MISCREG_CANRESTORE,
241        MISCREG_OTHERWIN,
242        MISCREG_CLEANWIN,
243        MISCREG_WSTATE,
244        MISCREG_WSTATE_NORMAL,
245        MISCREG_WSTATE_OTHER,
246        MISCREG_VER,
247        MISCREG_VER_MAXWIN,
248        MISCREG_VER_MAXTL,
249        MISCREG_VER_MASK,
250        MISCREG_VER_IMPL,
251        MISCREG_VER_MANUF,
252        MISCREG_FSR,
253        MISCREG_FSR_CEXC,
254        MISCREG_FSR_CEXC_NXC,
255        MISCREG_FSR_CEXC_DZC,
256        MISCREG_FSR_CEXC_UFC,
257        MISCREG_FSR_CEXC_OFC,
258        MISCREG_FSR_CEXC_NVC,
259        MISCREG_FSR_AEXC,
260        MISCREG_FSR_AEXC_NXC,
261        MISCREG_FSR_AEXC_DZC,
262        MISCREG_FSR_AEXC_UFC,
263        MISCREG_FSR_AEXC_OFC,
264        MISCREG_FSR_AEXC_NVC,
265        MISCREG_FSR_FCC0,
266        MISCREG_FSR_QNE,
267        MISCREG_FSR_FTT,
268        MISCREG_FSR_VER,
269        MISCREG_FSR_NS,
270        MISCREG_FSR_TEM,
271        MISCREG_FSR_TEM_NXM,
272        MISCREG_FSR_TEM_DZM,
273        MISCREG_FSR_TEM_UFM,
274        MISCREG_FSR_TEM_OFM,
275        MISCREG_FSR_TEM_NVM,
276        MISCREG_FSR_RD,
277        MISCREG_FSR_FCC1,
278        MISCREG_FSR_FCC2,
279        MISCREG_FSR_FCC3,
280        MISCREG_FPRS,
281        MISCREG_FPRS_DL,
282        MISCREG_FPRS_DU,
283        MISCREG_FPRS_FEF,
284        numMiscRegs
285    };
286
287    // The control registers, broken out into fields
288    class MiscRegFile
289    {
290      private:
291        union
292        {
293            uint16_t pstate;		// Process State Register
294            struct
295            {
296                uint16_t ag:1;		// Alternate Globals
297                uint16_t ie:1;		// Interrupt enable
298                uint16_t priv:1;	// Privelege mode
299                uint16_t am:1;		// Address mask
300                uint16_t pef:1;		// PSTATE enable floating-point
301                uint16_t red:1;		// RED (reset, error, debug) state
302                uint16_t mm:2;		// Memory Model
303                uint16_t tle:1;		// Trap little-endian
304                uint16_t cle:1;		// Current little-endian
305            } pstateFields;
306        };
307        uint64_t tba;		// Trap Base Address
308        union
309        {
310            uint64_t y;		// Y (used in obsolete multiplication)
311            struct
312            {
313                uint64_t value:32;	// The actual value stored in y
314                uint64_t :32;	// reserved bits
315            } yFields;
316        };
317        uint8_t pil;		// Process Interrupt Register
318        uint8_t cwp;		// Current Window Pointer
319        uint16_t tt[MaxTL];	// Trap Type (Type of trap which occured
320                                // on the previous level)
321        union
322        {
323            uint8_t	ccr;		// Condition Code Register
324            struct
325            {
326                union
327                {
328                    uint8_t icc:4;	// 32-bit condition codes
329                    struct
330                    {
331                        uint8_t c:1;	// Carry
332                        uint8_t v:1;	// Overflow
333                        uint8_t z:1;	// Zero
334                        uint8_t n:1;	// Negative
335                    } iccFields;
336                };
337                union
338                {
339                    uint8_t xcc:4;	// 64-bit condition codes
340                    struct
341                    {
342                        uint8_t c:1;	// Carry
343                        uint8_t v:1;	// Overflow
344                        uint8_t z:1;	// Zero
345                        uint8_t n:1;	// Negative
346                    } xccFields;
347                };
348            } ccrFields;
349        };
350        uint8_t asi;		// Address Space Identifier
351        uint8_t tl;		// Trap Level
352        uint64_t tpc[MaxTL];	// Trap Program Counter (value from
353                                // previous trap level)
354        uint64_t tnpc[MaxTL];	// Trap Next Program Counter (value from
355                                // previous trap level)
356        union
357        {
358            uint64_t tstate[MaxTL];	// Trap State
359            struct
360            {
361                //Values are from previous trap level
362                uint64_t cwp:5;		// Current Window Pointer
363                uint64_t :2;	// Reserved bits
364                uint64_t pstate:10;	// Process State
365                uint64_t :6;	// Reserved bits
366                uint64_t asi:8;		// Address Space Identifier
367                uint64_t ccr:8;		// Condition Code Register
368            } tstateFields[MaxTL];
369        };
370        union
371        {
372            uint64_t tick;		// Hardware clock-tick counter
373            struct
374            {
375                uint64_t counter:63;	// Clock-tick count
376                uint64_t npt:1;		// Non-priveleged trap
377            } tickFields;
378        };
379        uint8_t cansave;	// Savable windows
380        uint8_t canrestore;	// Restorable windows
381        uint8_t otherwin;	// Other windows
382        uint8_t cleanwin;	// Clean windows
383        union
384        {
385            uint8_t wstate;		// Window State
386            struct
387            {
388                uint8_t normal:3;	// Bits TT<4:2> are set to on a normal
389                                        // register window trap
390                uint8_t other:3;	// Bits TT<4:2> are set to on an "otherwin"
391                                        // register window trap
392            } wstateFields;
393        };
394        union
395        {
396            uint64_t ver;		// Version
397            struct
398            {
399                uint64_t maxwin:5;	// Max CWP value
400                uint64_t :2;	// Reserved bits
401                uint64_t maxtl:8;	// Maximum trap level
402                uint64_t :8;	// Reserved bits
403                uint64_t mask:8;	// Processor mask set revision number
404                uint64_t impl:16;	// Implementation identification number
405                uint64_t manuf:16;	// Manufacturer code
406            } verFields;
407        };
408        union
409        {
410            uint64_t	fsr;	// Floating-Point State Register
411            struct
412            {
413                union
414                {
415                    uint64_t cexc:5;	// Current excpetion
416                    struct
417                    {
418                        uint64_t nxc:1;		// Inexact
419                        uint64_t dzc:1;		// Divide by zero
420                        uint64_t ufc:1;		// Underflow
421                        uint64_t ofc:1;		// Overflow
422                        uint64_t nvc:1;		// Invalid operand
423                    } cexcFields;
424                };
425                union
426                {
427                    uint64_t aexc:5;		// Accrued exception
428                    struct
429                    {
430                        uint64_t nxc:1;		// Inexact
431                        uint64_t dzc:1;		// Divide by zero
432                        uint64_t ufc:1;		// Underflow
433                        uint64_t ofc:1;		// Overflow
434                        uint64_t nvc:1;		// Invalid operand
435                    } aexcFields;
436                };
437                uint64_t fcc0:2;		// Floating-Point condtion codes
438                uint64_t :1;		// Reserved bits
439                uint64_t qne:1;			// Deferred trap queue not empty
440                                                // with no queue, it should read 0
441                uint64_t ftt:3;			// Floating-Point trap type
442                uint64_t ver:3;			// Version (of the FPU)
443                uint64_t :2;		// Reserved bits
444                uint64_t ns:1;			// Nonstandard floating point
445                union
446                {
447                    uint64_t tem:5;			// Trap Enable Mask
448                    struct
449                    {
450                        uint64_t nxm:1;		// Inexact
451                        uint64_t dzm:1;		// Divide by zero
452                        uint64_t ufm:1;		// Underflow
453                        uint64_t ofm:1;		// Overflow
454                        uint64_t nvm:1;		// Invalid operand
455                    } temFields;
456                };
457                uint64_t :2;		// Reserved bits
458                uint64_t rd:2;			// Rounding direction
459                uint64_t fcc1:2;		// Floating-Point condition codes
460                uint64_t fcc2:2;		// Floating-Point condition codes
461                uint64_t fcc3:2;		// Floating-Point condition codes
462                uint64_t :26;		// Reserved bits
463            } fsrFields;
464        };
465        union
466        {
467            uint8_t		fprs;	// Floating-Point Register State
468            struct
469            {
470                uint8_t dl:1;		// Dirty lower
471                uint8_t du:1;		// Dirty upper
472                uint8_t fef:1;		// FPRS enable floating-Point
473            } fprsFields;
474        };
475
476      public:
477        MiscReg readReg(int miscReg);
478
479        MiscReg readRegWithEffect(int miscReg, Fault &fault, ExecContext *xc);
480
481        Fault setReg(int miscReg, const MiscReg &val);
482
483        Fault setRegWithEffect(int miscReg, const MiscReg &val,
484                               ExecContext *xc);
485
486        void serialize(std::ostream & os);
487
488        void unserialize(Checkpoint * cp, const std::string & section);
489
490        void copyMiscRegs(ExecContext * xc);
491    };
492
493    typedef union
494    {
495        IntReg  intreg;
496        FloatReg   fpreg;
497        MiscReg ctrlreg;
498    } AnyReg;
499
500    struct RegFile
501    {
502        IntRegFile intRegFile;		// (signed) integer register file
503        FloatRegFile floatRegFile;	// floating point register file
504        MiscRegFile miscRegs;	// control register file
505
506        Addr pc;		// Program Counter
507        Addr npc;		// Next Program Counter
508        Addr nnpc;
509
510        void serialize(std::ostream &os);
511        void unserialize(Checkpoint *cp, const std::string &section);
512    };
513
514} // namespace SparcISA
515
516#endif
517