isa_traits.hh revision 2495
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//#include "arch/mips/misc_regfile.hh"
33#include "base/misc.hh"
34#include "config/full_system.hh"
35#include "sim/host.hh"
36#include "sim/faults.hh"
37
38#include <vector>
39
40class FastCPU;
41class FullCPU;
42class Checkpoint;
43class ExecContext;
44
45namespace LittleEndianGuest {};
46using namespace LittleEndianGuest;
47
48#define TARGET_MIPS
49
50class StaticInst;
51class StaticInstPtr;
52
53namespace MIPS34K {
54int DTB_ASN_ASN(uint64_t reg);
55int ITB_ASN_ASN(uint64_t reg);
56};
57
58#if !FULL_SYSTEM
59class SyscallReturn {
60        public:
61           template <class T>
62           SyscallReturn(T v, bool s)
63           {
64               retval = (uint32_t)v;
65               success = s;
66           }
67
68           template <class T>
69           SyscallReturn(T v)
70           {
71               success = (v >= 0);
72               retval = (uint32_t)v;
73           }
74
75           ~SyscallReturn() {}
76
77           SyscallReturn& operator=(const SyscallReturn& s) {
78               retval = s.retval;
79               success = s.success;
80               return *this;
81           }
82
83           bool successful() { return success; }
84           uint64_t value() { return retval; }
85
86
87       private:
88           uint64_t retval;
89           bool success;
90};
91#endif
92
93namespace MipsISA
94{
95    typedef uint32_t MachInst;
96    typedef uint32_t MachInst;
97    typedef uint64_t ExtMachInst;
98    typedef uint8_t  RegIndex;
99//  typedef uint64_t Addr;
100
101       // Constants Related to the number of registers
102
103    const int NumIntArchRegs = 32;
104    const int NumPALShadowRegs = 8;
105    const int NumFloatArchRegs = 32;
106    // @todo: Figure out what this number really should be.
107    const int NumMiscArchRegs = 32;
108
109    const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs;
110    const int NumFloatRegs = NumFloatArchRegs;
111    const int NumMiscRegs = NumMiscArchRegs;
112
113    const int TotalNumRegs = NumIntRegs + NumFloatRegs +
114    NumMiscRegs + 0/*NumInternalProcRegs*/;
115
116    const int TotalDataRegs = NumIntRegs + NumFloatRegs;
117
118    // Static instruction parameters
119    const int MaxInstSrcRegs = 3;
120    const int MaxInstDestRegs = 2;
121
122    // semantically meaningful register indices
123    const int ZeroReg = 0;
124    const int AssemblerReg = 1;
125    const int ReturnValueReg1 = 2;
126    const int ReturnValueReg2 = 3;
127    const int ArgumentReg0 = 4;
128    const int ArgumentReg1 = 5;
129    const int ArgumentReg2 = 6;
130    const int ArgumentReg3 = 7;
131    const int KernelReg0 = 26;
132    const int KernelReg1 = 27;
133    const int GlobalPointerReg = 28;
134    const int StackPointerReg = 29;
135    const int FramePointerReg = 30;
136    const int ReturnAddressReg = 31;
137
138    const int SyscallNumReg = ReturnValueReg1;
139    const int SyscallPseudoReturnReg = ReturnValueReg1;
140    const int SyscallSuccessReg = ArgumentReg3;
141
142    const int LogVMPageSize = 13;	// 8K bytes
143    const int VMPageSize = (1 << LogVMPageSize);
144
145    const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned
146
147    const int MachineBytes = 4;
148    const int WordBytes = 4;
149    const int HalfwordBytes = 2;
150    const int ByteBytes = 1;
151
152
153    // These enumerate all the registers for dependence tracking.
154    enum DependenceTags {
155        // 0..31 are the integer regs 0..31
156        // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag)
157        FP_Base_DepTag = 32,
158        Ctrl_Base_DepTag = 64,
159        Fpcr_DepTag = 64,		// floating point control register
160        Uniq_DepTag = 65,
161        IPR_Base_DepTag = 66,
162        MiscReg_DepTag = 67
163    };
164
165    typedef uint32_t IntReg;
166    typedef IntReg IntRegFile[NumIntRegs];
167
168/* floating point register file entry type
169    typedef union {
170        uint64_t q;
171        double d;
172    } FloatReg;*/
173
174    typedef double FloatReg;
175    typedef uint64_t FloatRegBits;
176
177/*typedef union {
178        uint64_t q[NumFloatRegs];	// integer qword view
179        double d[NumFloatRegs];		// double-precision floating point view
180    } FloatRegFile;*/
181
182   class FloatRegFile
183    {
184      protected:
185
186        FloatRegBits q[NumFloatRegs];	// integer qword view
187        double d[NumFloatRegs];	// double-precision floating point view
188
189      public:
190
191        FloatReg readReg(int floatReg)
192        {
193            return d[floatReg];
194        }
195
196        FloatReg readReg(int floatReg, int width)
197        {
198            return readReg(floatReg);
199        }
200
201        FloatRegBits readRegBits(int floatReg)
202        {
203            return q[floatReg];
204        }
205
206        FloatRegBits readRegBits(int floatReg, int width)
207        {
208            return readRegBits(floatReg);
209        }
210
211        Fault setReg(int floatReg, const FloatReg &val)
212        {
213            d[floatReg] = val;
214            return NoFault;
215        }
216
217        Fault setReg(int floatReg, const FloatReg &val, int width)
218        {
219            return setReg(floatReg, val);
220        }
221
222        Fault setRegBits(int floatReg, const FloatRegBits &val)
223        {
224            q[floatReg] = val;
225            return NoFault;
226        }
227
228        Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
229        {
230            return setRegBits(floatReg, val);
231        }
232
233        void serialize(std::ostream &os);
234
235        void unserialize(Checkpoint *cp, const std::string &section);
236
237    };
238
239        void copyRegs(ExecContext *src, ExecContext *dest);
240
241    // cop-0/cop-1 system control register file
242    typedef uint64_t MiscReg;
243    //typedef MiscReg MiscRegFile[NumMiscRegs];
244    class MiscRegFile {
245
246      protected:
247        uint64_t	fpcr;		// floating point condition codes
248        uint64_t	uniq;		// process-unique register
249        bool		lock_flag;	// lock flag for LL/SC
250        Addr		lock_addr;	// lock address for LL/SC
251
252        MiscReg miscRegFile[NumMiscRegs];
253
254      public:
255        //These functions should be removed once the simplescalar cpu model
256        //has been replaced.
257        int getInstAsid();
258        int getDataAsid();
259
260        void copyMiscRegs(ExecContext *xc);
261
262        MiscReg readReg(int misc_reg)
263        { return miscRegFile[misc_reg]; }
264
265        MiscReg readRegWithEffect(int misc_reg, Fault &fault, ExecContext *xc)
266        { return miscRegFile[misc_reg];}
267
268        Fault setReg(int misc_reg, const MiscReg &val)
269        { miscRegFile[misc_reg] = val; return NoFault; }
270
271        Fault setRegWithEffect(int misc_reg, const MiscReg &val,
272                               ExecContext *xc)
273        { miscRegFile[misc_reg] = val; return NoFault; }
274
275#if FULL_SYSTEM
276        void clearIprs() { }
277
278      protected:
279        InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
280
281      private:
282        MiscReg readIpr(int idx, Fault &fault, ExecContext *xc) { }
283
284        Fault setIpr(int idx, uint64_t val, ExecContext *xc) { }
285#endif
286        friend class RegFile;
287    };
288
289    enum MiscRegTags {
290        //Coprocessor 0 Registers
291        //Reference MIPS32 Arch. for Programmers, Vol. III, Ch.8
292        //(Register Number-Register Select) Summary of Register
293        //------------------------------------------------------
294        Index = 0,       //0-0 Index into the TLB array
295
296        MVPControl = 1,  //0-1 Per-processor register containing global
297                     //MIPS� MT configuration data
298
299        MVPConf0 = 2,    //0-2 Per-processor register containing global
300                     //MIPS� MT configuration data
301
302        MVPConf1 = 3,    //0-3 Per-processor register containing global
303                     //MIPS� MT configuration data
304
305        Random = 8,      //1-0 Randomly generated index into the TLB array
306
307        VPEControl = 9,  //1-1 Per-VPE register containing relatively volatile
308                     //thread configuration data
309
310        VPEConf0 = 10,    //1-2 Per-VPE multi-thread configuration
311                     //information
312
313
314        VPEConf1 = 11,    //1-2 Per-VPE multi-thread configuration
315                     //information
316
317        YQMask = 12,      //Per-VPE register defining which YIELD
318                     //qualifier bits may be used without generating
319                     //an exception
320
321        VPESchedule = 13,
322        VPEScheFBack =  14,
323        VPEOpt = 15,
324        EntryLo0 = 16, // Bank 3: 16 - 23
325        TCStatus = 17,
326        TCBind = 18,
327        TCRestart = 19,
328        TCHalt = 20,
329        TCContext = 21,
330        TCSchedule = 22,
331        TCScheFBack = 23,
332
333        EntryLo1 = 24,// Bank 4: 24 - 31
334
335        Context = 32, // Bank 5: 32 - 39
336        ContextConfig = 33,
337
338        //PageMask = 40, //Bank 6: 40 - 47
339        PageGrain = 41,
340
341        Wired = 48, //Bank 7:48 - 55
342        SRSConf0 = 49,
343        SRSConf1 = 50,
344        SRSConf2 = 51,
345        SRSConf3 = 52,
346        SRSConf4 = 53,
347        BadVAddr = 54,
348
349        HWRena = 56,//Bank 8:56 - 63
350
351        Count = 64, //Bank 9:64 - 71
352
353        EntryHi = 72,//Bank 10:72 - 79
354
355        Compare = 80,//Bank 11:80 - 87
356
357        Status = 88,//Bank 12:88 - 96     //12-0 Processor status and control
358        IntCtl = 89,                      //12-1 Interrupt system status and control
359        SRSCtl = 90,                      //12-2 Shadow register set status and control
360        SRSMap = 91,                      //12-3 Shadow set IPL mapping
361
362        Cause = 97,//97-104      //13-0 Cause of last general exception
363
364        EPC = 105,//105-112        //14-0 Program counter at last exception
365
366        PRId = 113,//113-120,       //15-0 Processor identification and revision
367        EBase = 114,      //15-1 Exception vector base register
368
369        Config = 121,//Bank 16: 121-128
370        Config1 = 122,
371        Config2 = 123,
372        Config3 = 124,
373        Config6 = 127,
374        Config7 = 128,
375
376
377        LLAddr = 129,//Bank 17: 129-136
378
379        WatchLo0 = 137,//Bank 18: 137-144
380        WatchLo1 = 138,
381        WatchLo2 = 139,
382        WatchLo3 = 140,
383        WatchLo4 = 141,
384        WatchLo5 = 142,
385        WatchLo6 = 143,
386        WatchLo7 = 144,
387
388        WatchHi0 = 145,//Bank 19: 145-152
389        WatchHi1 = 146,
390        WatchHi2 = 147,
391        WatchHi3 = 148,
392        WatchHi4 = 149,
393        WatchHi5 = 150,
394        WatchHi6 = 151,
395        WatchHi7 = 152,
396
397        XCContext64 = 153,//Bank 20: 153-160
398
399        //Bank 21: 161-168
400
401        //Bank 22: 169-176
402
403        Debug = 177, //Bank 23: 177-184
404        TraceControl1 = 178,
405        TraceControl2 = 179,
406        UserTraceData = 180,
407        TraceBPC = 181,
408
409        DEPC = 185,//Bank 24: 185-192
410
411        PerfCnt0 = 193,//Bank 25: 193 - 200
412        PerfCnt1 = 194,
413        PerfCnt2 = 195,
414        PerfCnt3 = 196,
415        PerfCnt4 = 197,
416        PerfCnt5 = 198,
417        PerfCnt6 = 199,
418        PerfCnt7 = 200,
419
420        ErrCtl = 201, //Bank 26: 201 - 208
421
422        CacheErr0 = 209, //Bank 27: 209 - 216
423        CacheErr1 = 210,
424        CacheErr2 = 211,
425        CacheErr3 = 212,
426
427        TagLo0 = 217,//Bank 28: 217 - 224
428        DataLo1 = 218,
429        TagLo2 = 219,
430        DataLo3 = 220,
431        TagLo4 = 221,
432        DataLo5 = 222,
433        TagLo6 = 223,
434        DataLo7 = 234,
435
436        TagHi0 = 233,//Bank 29: 233 - 240
437        DataHi1 = 234,
438        TagHi2 = 235,
439        DataHi3 = 236,
440        TagHi4 = 237,
441        DataHi5 = 238,
442        TagHi6 = 239,
443        DataHi7 = 240,
444
445
446        ErrorEPC = 249,//Bank 30: 241 - 248
447
448        DESAVE = 257,//Bank 31: 249-256
449
450        //More Misc. Regs
451        Hi,
452        Lo,
453        FCSR,
454        FIR,
455        FPCR,
456
457        //Alpha Regs, but here now, for
458        //compiling sake
459        UNIQ,
460        LockAddr,
461        LockFlag
462    };
463
464extern const Addr PageShift;
465extern const Addr PageBytes;
466extern const Addr PageMask;
467extern const Addr PageOffset;
468
469#if FULL_SYSTEM
470
471    typedef uint64_t InternalProcReg;
472
473#include "arch/mips/isa_fullsys_traits.hh"
474
475#else
476    enum {
477        NumInternalProcRegs = 0
478    };
479#endif
480
481    typedef union {
482        IntReg  intreg;
483        FloatReg   fpreg;
484        MiscReg ctrlreg;
485    } AnyReg;
486
487    struct RegFile {
488        IntRegFile intRegFile;		// (signed) integer register file
489        FloatRegFile floatRegFile;	// floating point register file
490        MiscRegFile miscRegs;		// control register file
491
492
493        Addr pc;			// program counter
494        Addr npc;			// next-cycle program counter
495        Addr nnpc;			// next-next-cycle program counter
496                                        // used to implement branch delay slot
497                                        // not real register
498
499        MiscReg hi;                     // MIPS HI Register
500        MiscReg lo;                     // MIPS LO Register
501
502
503#if FULL_SYSTEM
504        IntReg palregs[NumIntRegs];	// PAL shadow registers
505        InternalProcReg ipr[NumInternalProcRegs]; // internal processor regs
506        int intrflag;			// interrupt flag
507        bool pal_shadow;		// using pal_shadow registers
508        inline int instAsid() { return MIPS34K::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); }
509        inline int dataAsid() { return MIPS34K::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); }
510#endif // FULL_SYSTEM
511
512        //void initCP0Regs();
513        void serialize(std::ostream &os);
514        void unserialize(Checkpoint *cp, const std::string &section);
515
516        void createCP0Regs();
517        void coldReset();
518    };
519
520    StaticInstPtr decodeInst(ExtMachInst);
521
522    // return a no-op instruction... used for instruction fetch faults
523    extern const MachInst NoopMachInst;
524
525    enum annotes {
526        ANNOTE_NONE = 0,
527        // An impossible number for instruction annotations
528        ITOUCH_ANNOTE = 0xffffffff,
529    };
530
531//void getMiscRegIdx(int reg_name,int &idx, int &sel);
532
533    static inline ExtMachInst
534    makeExtMI(MachInst inst, const uint64_t &pc) {
535#if FULL_SYSTEM
536        ExtMachInst ext_inst = inst;
537        if (pc && 0x1)
538            return ext_inst|=(static_cast<ExtMachInst>(pc & 0x1) << 32);
539        else
540            return ext_inst;
541#else
542        return ExtMachInst(inst);
543#endif
544    }
545
546    static inline bool isCallerSaveIntegerRegister(unsigned int reg) {
547        panic("register classification not implemented");
548        return (reg >= 1 && reg <= 8 || reg >= 22 && reg <= 25 || reg == 27);
549    }
550
551    static inline bool isCalleeSaveIntegerRegister(unsigned int reg) {
552        panic("register classification not implemented");
553        return (reg >= 9 && reg <= 15);
554    }
555
556    static inline bool isCallerSaveFloatRegister(unsigned int reg) {
557        panic("register classification not implemented");
558        return false;
559    }
560
561    static inline bool isCalleeSaveFloatRegister(unsigned int reg) {
562        panic("register classification not implemented");
563        return false;
564    }
565
566    static inline Addr alignAddress(const Addr &addr,
567                                         unsigned int nbytes) {
568        return (addr & ~(nbytes - 1));
569    }
570
571    // Instruction address compression hooks
572    static inline Addr realPCToFetchPC(const Addr &addr) {
573        return addr;
574    }
575
576    static inline Addr fetchPCToRealPC(const Addr &addr) {
577        return addr;
578    }
579
580    // the size of "fetched" instructions (not necessarily the size
581    // of real instructions for PISA)
582    static inline size_t fetchInstSize() {
583        return sizeof(MachInst);
584    }
585
586    static inline MachInst makeRegisterCopy(int dest, int src) {
587        panic("makeRegisterCopy not implemented");
588        return 0;
589    }
590
591    static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
592    {
593        if (return_value.successful()) {
594            // no error
595            regs->intRegFile[SyscallSuccessReg] = 0;
596            regs->intRegFile[ReturnValueReg1] = return_value.value();
597        } else {
598            // got an error, return details
599            regs->intRegFile[SyscallSuccessReg] = (IntReg) -1;
600            regs->intRegFile[ReturnValueReg1] = -return_value.value();
601        }
602    }
603
604    // Machine operations
605
606    void saveMachineReg(AnyReg &savereg, const RegFile &reg_file,
607                               int regnum);
608
609    void restoreMachineReg(RegFile &regs, const AnyReg &reg,
610                                  int regnum);
611
612#if 0
613    static void serializeSpecialRegs(const Serializable::Proxy &proxy,
614                                     const RegFile &regs);
615
616    static void unserializeSpecialRegs(const IniFile *db,
617                                       const std::string &category,
618                                       ConfigNode *node,
619                                       RegFile &regs);
620#endif
621
622    /**
623     * Function to insure ISA semantics about 0 registers.
624     * @param xc The execution context.
625     */
626    template <class XC>
627    void zeroRegisters(XC *xc);
628
629    const Addr MaxAddr = (Addr)-1;
630};
631
632#if FULL_SYSTEM
633//typedef TheISA::InternalProcReg InternalProcReg;
634//const int NumInternalProcRegs  = TheISA::NumInternalProcRegs;
635//const int NumInterruptLevels = TheISA::NumInterruptLevels;
636
637#include "arch/mips/mips34k.hh"
638#endif
639
640using namespace MipsISA;
641
642#endif // __ARCH_MIPS_ISA_TRAITS_HH__
643