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