isa_traits.hh revision 2428
13537SN/A/*
27400SAli.Saidi@ARM.com * Copyright (c) 2003-2005 The Regents of The University of Michigan
37400SAli.Saidi@ARM.com * All rights reserved.
47400SAli.Saidi@ARM.com *
57400SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without
67400SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are
77400SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright
87400SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer;
97400SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright
107400SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the
117400SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution;
127400SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its
137400SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from
143537SN/A * this software without specific prior written permission.
153537SN/A *
163537SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173537SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183537SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193537SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203537SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213537SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223537SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233537SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243537SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253537SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263537SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273537SN/A */
283537SN/A
293537SN/A#ifndef __ARCH_ALPHA_ISA_TRAITS_HH__
303537SN/A#define __ARCH_ALPHA_ISA_TRAITS_HH__
313537SN/A
323537SN/Anamespace LittleEndianGuest {}
333537SN/Ausing namespace LittleEndianGuest;
343537SN/A
353537SN/A#include "arch/alpha/types.hh"
363537SN/A#include "base/misc.hh"
373537SN/A#include "config/full_system.hh"
383537SN/A#include "sim/host.hh"
394103SN/A#include "sim/faults.hh"
404103SN/A
413537SN/Aclass ExecContext;
423537SN/Aclass FastCPU;
436757SAli.Saidi@ARM.comclass FullCPU;
446757SAli.Saidi@ARM.comclass Checkpoint;
453537SN/A
466757SAli.Saidi@ARM.comclass StaticInst;
476757SAli.Saidi@ARM.comclass StaticInstPtr;
487400SAli.Saidi@ARM.com
496757SAli.Saidi@ARM.comnamespace EV5 {
503827SN/Aint DTB_ASN_ASN(uint64_t reg);
516757SAli.Saidi@ARM.comint ITB_ASN_ASN(uint64_t reg);
525647SN/A}
533827SN/A
546757SAli.Saidi@ARM.com#if !FULL_SYSTEM
553537SN/Aclass SyscallReturn {
563894SN/A        public:
575647SN/A           template <class T>
584009SN/A           SyscallReturn(T v, bool s)
595810SN/A           {
605810SN/A               retval = (uint64_t)v;
614009SN/A               success = s;
627400SAli.Saidi@ARM.com           }
634103SN/A
644009SN/A           template <class T>
654009SN/A           SyscallReturn(T v)
665810SN/A           {
675810SN/A               success = (v >= 0);
685810SN/A               retval = (uint64_t)v;
695810SN/A           }
705810SN/A
715810SN/A           ~SyscallReturn() {}
725810SN/A
736757SAli.Saidi@ARM.com           SyscallReturn& operator=(const SyscallReturn& s) {
745647SN/A               retval = s.retval;
755647SN/A               success = s.success;
765647SN/A               return *this;
775647SN/A           }
785647SN/A
795647SN/A           bool successful() { return success; }
805647SN/A           uint64_t value() { return retval; }
815810SN/A
824009SN/A
835704SN/A       private:
844009SN/A           uint64_t retval;
854009SN/A           bool success;
864009SN/A};
875704SN/A
885704SN/A#endif
893537SN/A
907400SAli.Saidi@ARM.com
917400SAli.Saidi@ARM.com
927400SAli.Saidi@ARM.comnamespace AlphaISA
937400SAli.Saidi@ARM.com{
947400SAli.Saidi@ARM.com
957400SAli.Saidi@ARM.com    const int NumIntArchRegs = 32;
967400SAli.Saidi@ARM.com    const int NumPALShadowRegs = 8;
977400SAli.Saidi@ARM.com    const int NumFloatArchRegs = 32;
987400SAli.Saidi@ARM.com    // @todo: Figure out what this number really should be.
997400SAli.Saidi@ARM.com    const int NumMiscArchRegs = 32;
1004009SN/A
1013894SN/A    // Static instruction parameters
1025704SN/A    const int MaxInstSrcRegs = 3;
1035704SN/A    const int MaxInstDestRegs = 2;
1044009SN/A
1057847Sminkyu.jeong@arm.com    // semantically meaningful register indices
1067400SAli.Saidi@ARM.com    const int ZeroReg = 31;	// architecturally meaningful
1077400SAli.Saidi@ARM.com    // the rest of these depend on the ABI
1087400SAli.Saidi@ARM.com    const int StackPointerReg = 30;
1097400SAli.Saidi@ARM.com    const int GlobalPointerReg = 29;
1107400SAli.Saidi@ARM.com    const int ProcedureValueReg = 27;
1117400SAli.Saidi@ARM.com    const int ReturnAddressReg = 26;
1127400SAli.Saidi@ARM.com    const int ReturnValueReg = 0;
1137400SAli.Saidi@ARM.com    const int FramePointerReg = 15;
1147400SAli.Saidi@ARM.com    const int ArgumentReg0 = 16;
1154009SN/A    const int ArgumentReg1 = 17;
1163827SN/A    const int ArgumentReg2 = 18;
1175704SN/A    const int ArgumentReg3 = 19;
1185704SN/A    const int ArgumentReg4 = 20;
1194009SN/A    const int ArgumentReg5 = 21;
1207400SAli.Saidi@ARM.com    const int SyscallNumReg = ReturnValueReg;
1214103SN/A    const int SyscallPseudoReturnReg = ArgumentReg4;
1227400SAli.Saidi@ARM.com    const int SyscallSuccessReg = 19;
1234009SN/A
1243537SN/A
1255704SN/A
1265704SN/A    const int LogVMPageSize = 13;	// 8K bytes
1274009SN/A    const int VMPageSize = (1 << LogVMPageSize);
1287400SAli.Saidi@ARM.com
1297400SAli.Saidi@ARM.com    const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned
1307400SAli.Saidi@ARM.com
1317400SAli.Saidi@ARM.com    const int WordBytes = 4;
1327400SAli.Saidi@ARM.com    const int HalfwordBytes = 2;
1337400SAli.Saidi@ARM.com    const int ByteBytes = 1;
1347400SAli.Saidi@ARM.com
1357400SAli.Saidi@ARM.com
1367400SAli.Saidi@ARM.com    const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs;
1374009SN/A    const int NumFloatRegs = NumFloatArchRegs;
1383537SN/A    const int NumMiscRegs = NumMiscArchRegs;
1395704SN/A
1405704SN/A    typedef IntReg IntRegFile[NumIntRegs];
1414009SN/A
1427400SAli.Saidi@ARM.com    typedef union {
1437400SAli.Saidi@ARM.com        uint64_t q[NumFloatRegs];	// integer qword view
1447400SAli.Saidi@ARM.com        double d[NumFloatRegs];		// double-precision floating point view
1457400SAli.Saidi@ARM.com    } FloatRegFile;
1467400SAli.Saidi@ARM.com
1477400SAli.Saidi@ARM.comextern const Addr PageShift;
1487400SAli.Saidi@ARM.comextern const Addr PageBytes;
1497400SAli.Saidi@ARM.comextern const Addr PageMask;
1507400SAli.Saidi@ARM.comextern const Addr PageOffset;
1517400SAli.Saidi@ARM.com
1527400SAli.Saidi@ARM.com// redirected register map, really only used for the full system case.
1537400SAli.Saidi@ARM.comextern const int reg_redir[NumIntRegs];
1547400SAli.Saidi@ARM.com
1557400SAli.Saidi@ARM.com#if FULL_SYSTEM
1567400SAli.Saidi@ARM.com
1577400SAli.Saidi@ARM.com#include "arch/alpha/isa_fullsys_traits.hh"
1584009SN/A
1593537SN/A#else
1605704SN/A    const int NumInternalProcRegs = 0;
1615704SN/A#endif
1624009SN/A    class MiscRegFile {
1637400SAli.Saidi@ARM.com      protected:
1644009SN/A        uint64_t	fpcr;		// floating point condition codes
1653654SN/A        uint64_t	uniq;		// process-unique register
1665704SN/A        bool		lock_flag;	// lock flag for LL/SC
1675704SN/A        Addr		lock_addr;	// lock address for LL/SC
1684009SN/A
1697400SAli.Saidi@ARM.com      public:
1707400SAli.Saidi@ARM.com        MiscReg readReg(int misc_reg);
1714009SN/A
1723537SN/A        //These functions should be removed once the simplescalar cpu model
1735704SN/A        //has been replaced.
1745704SN/A        int getInstAsid();
1754009SN/A        int getDataAsid();
1767400SAli.Saidi@ARM.com
1777400SAli.Saidi@ARM.com        MiscReg readRegWithEffect(int misc_reg, Fault &fault, ExecContext *xc);
1784009SN/A
1794009SN/A        Fault setReg(int misc_reg, const MiscReg &val);
1806757SAli.Saidi@ARM.com
1813537SN/A        Fault setRegWithEffect(int misc_reg, const MiscReg &val,
1826757SAli.Saidi@ARM.com                               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