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