isa_traits.hh revision 2264
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_ALPHA_ISA_TRAITS_HH__
30#define __ARCH_ALPHA_ISA_TRAITS_HH__
31
32namespace LittleEndianGuest {}
33using namespace LittleEndianGuest;
34
35//#include "arch/alpha/faults.hh"
36#include "base/misc.hh"
37#include "config/full_system.hh"
38#include "sim/host.hh"
39#include "sim/faults.hh"
40
41class ExecContext;
42class FastCPU;
43class FullCPU;
44class Checkpoint;
45
46#define TARGET_ALPHA
47
48class StaticInst;
49class StaticInstPtr;
50
51namespace EV5 {
52int DTB_ASN_ASN(uint64_t reg);
53int ITB_ASN_ASN(uint64_t reg);
54}
55
56#if !FULL_SYSTEM
57class SyscallReturn {
58        public:
59           template <class T>
60           SyscallReturn(T v, bool s)
61           {
62               retval = (uint64_t)v;
63               success = s;
64           }
65
66           template <class T>
67           SyscallReturn(T v)
68           {
69               success = (v >= 0);
70               retval = (uint64_t)v;
71           }
72
73           ~SyscallReturn() {}
74
75           SyscallReturn& operator=(const SyscallReturn& s) {
76               retval = s.retval;
77               success = s.success;
78               return *this;
79           }
80
81           bool successful() { return success; }
82           uint64_t value() { return retval; }
83
84
85       private:
86           uint64_t retval;
87           bool success;
88};
89
90#endif
91
92
93
94namespace AlphaISA
95{
96
97    typedef uint32_t MachInst;
98    typedef uint64_t ExtMachInst;
99    typedef uint8_t  RegIndex;
100
101    const int NumIntArchRegs = 32;
102    const int NumPALShadowRegs = 8;
103    const int NumFloatArchRegs = 32;
104    // @todo: Figure out what this number really should be.
105    const int NumMiscArchRegs = 32;
106
107    // Static instruction parameters
108    const int MaxInstSrcRegs = 3;
109    const int MaxInstDestRegs = 2;
110
111    // semantically meaningful register indices
112    const int ZeroReg = 31;	// architecturally meaningful
113    // the rest of these depend on the ABI
114    const int StackPointerReg = 30;
115    const int GlobalPointerReg = 29;
116    const int ProcedureValueReg = 27;
117    const int ReturnAddressReg = 26;
118    const int ReturnValueReg = 0;
119    const int FramePointerReg = 15;
120    const int ArgumentReg0 = 16;
121    const int ArgumentReg1 = 17;
122    const int ArgumentReg2 = 18;
123    const int ArgumentReg3 = 19;
124    const int ArgumentReg4 = 20;
125    const int ArgumentReg5 = 21;
126    const int SyscallNumReg = ReturnValueReg;
127    const int SyscallPseudoReturnReg = ArgumentReg4;
128    const int SyscallSuccessReg = 19;
129
130
131
132    const int LogVMPageSize = 13;	// 8K bytes
133    const int VMPageSize = (1 << LogVMPageSize);
134
135    const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned
136
137    const int WordBytes = 4;
138    const int HalfwordBytes = 2;
139    const int ByteBytes = 1;
140
141
142    const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs;
143    const int NumFloatRegs = NumFloatArchRegs;
144    const int NumMiscRegs = NumMiscArchRegs;
145
146    // These enumerate all the registers for dependence tracking.
147    enum DependenceTags {
148        // 0..31 are the integer regs 0..31
149        // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag)
150        FP_Base_DepTag = 40,
151        Ctrl_Base_DepTag = 72,
152        Fpcr_DepTag = 72,		// floating point control register
153        Uniq_DepTag = 73,
154        Lock_Flag_DepTag = 74,
155        Lock_Addr_DepTag = 75,
156        IPR_Base_DepTag = 76
157    };
158
159    typedef uint64_t IntReg;
160    typedef IntReg IntRegFile[NumIntRegs];
161
162    // floating point register file entry type
163    typedef union {
164        uint64_t q;
165        double d;
166    } FloatReg;
167
168    typedef union {
169        uint64_t q[NumFloatRegs];	// integer qword view
170        double d[NumFloatRegs];		// double-precision floating point view
171    } FloatRegFile;
172
173extern const Addr PageShift;
174extern const Addr PageBytes;
175extern const Addr PageMask;
176extern const Addr PageOffset;
177
178// redirected register map, really only used for the full system case.
179extern const int reg_redir[NumIntRegs];
180
181#if FULL_SYSTEM
182
183    typedef uint64_t InternalProcReg;
184
185#include "arch/alpha/isa_fullsys_traits.hh"
186
187#else
188    const int NumInternalProcRegs = 0;
189#endif
190
191    // control register file contents
192    typedef uint64_t MiscReg;
193    class MiscRegFile {
194      protected:
195        uint64_t	fpcr;		// floating point condition codes
196        uint64_t	uniq;		// process-unique register
197        bool		lock_flag;	// lock flag for LL/SC
198        Addr		lock_addr;	// lock address for LL/SC
199
200      public:
201        MiscReg readReg(int misc_reg);
202
203        //These functions should be removed once the simplescalar cpu model
204        //has been replaced.
205        int getInstAsid();
206        int getDataAsid();
207
208        MiscReg readRegWithEffect(int misc_reg, Fault &fault, ExecContext *xc);
209
210        Fault setReg(int misc_reg, const MiscReg &val);
211
212        Fault setRegWithEffect(int misc_reg, const MiscReg &val,
213                               ExecContext *xc);
214
215        void copyMiscRegs(ExecContext *xc);
216
217#if FULL_SYSTEM
218      protected:
219        InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
220
221      private:
222        MiscReg readIpr(int idx, Fault &fault, ExecContext *xc);
223
224        Fault setIpr(int idx, uint64_t val, ExecContext *xc);
225
226        void copyIprs(ExecContext *xc);
227#endif
228        friend class RegFile;
229    };
230
231    const int TotalNumRegs = NumIntRegs + NumFloatRegs +
232        NumMiscRegs + NumInternalProcRegs;
233
234    const int TotalDataRegs = NumIntRegs + NumFloatRegs;
235
236    typedef union {
237        IntReg  intreg;
238        FloatReg   fpreg;
239        MiscReg ctrlreg;
240    } AnyReg;
241
242    struct RegFile {
243        IntRegFile intRegFile;		// (signed) integer register file
244        FloatRegFile floatRegFile;	// floating point register file
245        MiscRegFile miscRegs;		// control register file
246        Addr pc;			// program counter
247        Addr npc;			// next-cycle program counter
248        Addr nnpc;
249
250#if FULL_SYSTEM
251        int intrflag;			// interrupt flag
252        inline int instAsid()
253        { return EV5::ITB_ASN_ASN(miscRegs.ipr[IPR_ITB_ASN]); }
254        inline int dataAsid()
255        { return EV5::DTB_ASN_ASN(miscRegs.ipr[IPR_DTB_ASN]); }
256#endif // FULL_SYSTEM
257
258        void serialize(std::ostream &os);
259        void unserialize(Checkpoint *cp, const std::string &section);
260    };
261
262    static inline ExtMachInst makeExtMI(MachInst inst, const uint64_t &pc);
263
264    StaticInstPtr decodeInst(ExtMachInst);
265
266    // return a no-op instruction... used for instruction fetch faults
267    extern const ExtMachInst NoopMachInst;
268
269    enum annotes {
270        ANNOTE_NONE = 0,
271        // An impossible number for instruction annotations
272        ITOUCH_ANNOTE = 0xffffffff,
273    };
274
275    static inline bool isCallerSaveIntegerRegister(unsigned int reg) {
276        panic("register classification not implemented");
277        return (reg >= 1 && reg <= 8 || reg >= 22 && reg <= 25 || reg == 27);
278    }
279
280    static inline bool isCalleeSaveIntegerRegister(unsigned int reg) {
281        panic("register classification not implemented");
282        return (reg >= 9 && reg <= 15);
283    }
284
285    static inline bool isCallerSaveFloatRegister(unsigned int reg) {
286        panic("register classification not implemented");
287        return false;
288    }
289
290    static inline bool isCalleeSaveFloatRegister(unsigned int reg) {
291        panic("register classification not implemented");
292        return false;
293    }
294
295    static inline Addr alignAddress(const Addr &addr,
296                                         unsigned int nbytes) {
297        return (addr & ~(nbytes - 1));
298    }
299
300    // Instruction address compression hooks
301    static inline Addr realPCToFetchPC(const Addr &addr) {
302        return addr;
303    }
304
305    static inline Addr fetchPCToRealPC(const Addr &addr) {
306        return addr;
307    }
308
309    // the size of "fetched" instructions (not necessarily the size
310    // of real instructions for PISA)
311    static inline size_t fetchInstSize() {
312        return sizeof(MachInst);
313    }
314
315    static inline MachInst makeRegisterCopy(int dest, int src) {
316        panic("makeRegisterCopy not implemented");
317        return 0;
318    }
319
320    // Machine operations
321
322    void saveMachineReg(AnyReg &savereg, const RegFile &reg_file,
323                               int regnum);
324
325    void restoreMachineReg(RegFile &regs, const AnyReg &reg,
326                                  int regnum);
327
328#if 0
329    static void serializeSpecialRegs(const Serializable::Proxy &proxy,
330                                     const RegFile &regs);
331
332    static void unserializeSpecialRegs(const IniFile *db,
333                                       const std::string &category,
334                                       ConfigNode *node,
335                                       RegFile &regs);
336#endif
337
338    /**
339     * Function to insure ISA semantics about 0 registers.
340     * @param xc The execution context.
341     */
342    template <class XC>
343    void zeroRegisters(XC *xc);
344
345    const Addr MaxAddr = (Addr)-1;
346
347    static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
348    {
349        // check for error condition.  Alpha syscall convention is to
350        // indicate success/failure in reg a3 (r19) and put the
351        // return value itself in the standard return value reg (v0).
352        if (return_value.successful()) {
353            // no error
354            regs->intRegFile[SyscallSuccessReg] = 0;
355            regs->intRegFile[ReturnValueReg] = return_value.value();
356        } else {
357            // got an error, return details
358            regs->intRegFile[SyscallSuccessReg] = (IntReg) -1;
359            regs->intRegFile[ReturnValueReg] = -return_value.value();
360        }
361    }
362};
363
364static inline AlphaISA::ExtMachInst
365AlphaISA::makeExtMI(AlphaISA::MachInst inst, const uint64_t &pc) {
366#if FULL_SYSTEM
367    AlphaISA::ExtMachInst ext_inst = inst;
368    if (pc && 0x1)
369        return ext_inst|=(static_cast<AlphaISA::ExtMachInst>(pc & 0x1) << 32);
370    else
371        return ext_inst;
372#else
373    return AlphaISA::ExtMachInst(inst);
374#endif
375}
376
377#if FULL_SYSTEM
378
379#include "arch/alpha/ev5.hh"
380#endif
381
382#endif // __ARCH_ALPHA_ISA_TRAITS_HH__
383