simple_thread.hh revision 2251
12SN/A/*
21762SN/A * Copyright (c) 2001-2006 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/A *
162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu */
282665Ssaidi@eecs.umich.edu
292665Ssaidi@eecs.umich.edu#ifndef __CPU_EXEC_CONTEXT_HH__
302SN/A#define __CPU_EXEC_CONTEXT_HH__
312SN/A
321388SN/A#include "config/full_system.hh"
332SN/A#include "mem/functional/functional.hh"
342SN/A#include "mem/mem_req.hh"
352SN/A#include "sim/eventq.hh"
361191SN/A#include "sim/host.hh"
371191SN/A#include "sim/serialize.hh"
381191SN/A#include "arch/isa_traits.hh"
391388SN/A//#include "arch/isa_registers.hh"
405529Snate@binkert.org#include "sim/byteswap.hh"
411717SN/A
422651Ssaidi@eecs.umich.edu// forward declaration: see functional_memory.hh
432680Sktlim@umich.educlass FunctionalMemory;
441977SN/Aclass PhysicalMemory;
455529Snate@binkert.orgclass BaseCPU;
463144Shsul@eecs.umich.edu
472190SN/A#if FULL_SYSTEM
4856SN/A
492190SN/A#include "sim/system.hh"
502SN/A#include "arch/tlb.hh"
512359SN/A
522359SN/Aclass FunctionProfile;
532359SN/Aclass ProfileNode;
542SN/Aclass MemoryController;
552SN/Anamespace Kernel { class Binning; class Statistics; }
562SN/A
572SN/A#else // !FULL_SYSTEM
582SN/A
592SN/A#include "sim/process.hh"
602SN/A
612SN/A#endif // FULL_SYSTEM
622SN/A
635606Snate@binkert.org//
646144Sksewell@umich.edu// The ExecContext object represents a functional context for
656144Sksewell@umich.edu// instruction execution.  It incorporates everything required for
663126Sktlim@umich.edu// architecture-level functional simulation of a single thread.
676144Sksewell@umich.edu//
686144Sksewell@umich.edu
693126Sktlim@umich.educlass ExecContext
703126Sktlim@umich.edu{
712356SN/A  protected:
722356SN/A    typedef TheISA::RegFile RegFile;
732356SN/A    typedef TheISA::MachInst MachInst;
742367SN/A    typedef TheISA::MiscRegFile MiscRegFile;
752356SN/A    typedef TheISA::MiscReg MiscReg;
766144Sksewell@umich.edu  public:
772367SN/A    enum Status
786144Sksewell@umich.edu    {
796144Sksewell@umich.edu        /// Initialized but not running yet.  All CPUs start in
806144Sksewell@umich.edu        /// this state, but most transition to Active on cycle 1.
812356SN/A        /// In MP or SMT systems, non-primary contexts will stay
822367SN/A        /// in this state until a thread is assigned to them.
836144Sksewell@umich.edu        Unallocated,
846144Sksewell@umich.edu
856144Sksewell@umich.edu        /// Running.  Instructions should be executed only when
862367SN/A        /// the context is in this state.
872356SN/A        Active,
886144Sksewell@umich.edu
896144Sksewell@umich.edu        /// Temporarily inactive.  Entered while waiting for
906144Sksewell@umich.edu        /// initialization,synchronization, etc.
912356SN/A        Suspended,
922356SN/A
932356SN/A        /// Permanently shut down.  Entered when target executes
945336Shines@cs.fsu.edu        /// m5exit pseudo-instruction.  When all contexts enter
952356SN/A        /// this state, the simulation will terminate.
964873Sstever@eecs.umich.edu        Halted
972356SN/A    };
982356SN/A
991858SN/A  private:
1001400SN/A    Status _status;
1015712Shsul@eecs.umich.edu
1025712Shsul@eecs.umich.edu  public:
1036221Snate@binkert.org    Status status() const { return _status; }
1043661Srdreslin@umich.edu
1052SN/A    void setStatus(Status newStatus) { _status = newStatus; }
1061400SN/A
1075712Shsul@eecs.umich.edu    /// Set the status to Active.  Optional delay indicates number of
1086221Snate@binkert.org    /// cycles to wait before beginning execution.
1093661Srdreslin@umich.edu    void activate(int delay = 1);
1102SN/A
1112SN/A    /// Set the status to Suspended.
1122359SN/A    void suspend();
1131062SN/A
1145712Shsul@eecs.umich.edu    /// Set the status to Unallocated.
1155712Shsul@eecs.umich.edu    void deallocate();
1165712Shsul@eecs.umich.edu
1175712Shsul@eecs.umich.edu    /// Set the status to Halted.
1185712Shsul@eecs.umich.edu    void halt();
1192SN/A
1202SN/A  public:
1212SN/A    RegFile regs;	// correct-path register context
1225712Shsul@eecs.umich.edu
1235712Shsul@eecs.umich.edu    // pointer to CPU associated with this context
1246221Snate@binkert.org    BaseCPU *cpu;
1256221Snate@binkert.org
1262SN/A    // Current instruction
1272SN/A    MachInst inst;
1286221Snate@binkert.org
1296221Snate@binkert.org    // Index of hardware thread context on the CPU that this represents.
1306221Snate@binkert.org    int thread_num;
1316221Snate@binkert.org
1322SN/A    // ID of this context w.r.t. the System or Process object to which
1332SN/A    // it belongs.  For full-system mode, this is the system CPU ID.
1342SN/A    int cpu_id;
1352SN/A
1365606Snate@binkert.org    Tick lastActivate;
1375606Snate@binkert.org    Tick lastSuspend;
1386221Snate@binkert.org
1395606Snate@binkert.org#if FULL_SYSTEM
1406221Snate@binkert.org    FunctionalMemory *mem;
1415606Snate@binkert.org    AlphaITB *itb;
1425606Snate@binkert.org    AlphaDTB *dtb;
1432SN/A    System *system;
1441400SN/A
1455606Snate@binkert.org    // the following two fields are redundant, since we can always
1465606Snate@binkert.org    // look them up through the system pointer, but we'll leave them
1472SN/A    // here for now for convenience
1482SN/A    MemoryController *memctrl;
1492SN/A    PhysicalMemory *physmem;
1502SN/A
1516221Snate@binkert.org    Kernel::Binning *kernelBinning;
1526221Snate@binkert.org    Kernel::Statistics *kernelStats;
1535606Snate@binkert.org    bool bin;
1546221Snate@binkert.org    bool fnbin;
1555606Snate@binkert.org
1562SN/A    FunctionProfile *profile;
1572SN/A    ProfileNode *profileNode;
158124SN/A    Addr profilePC;
1596221Snate@binkert.org    void dumpFuncProfile();
1606221Snate@binkert.org
1616221Snate@binkert.org    /** Event for timing out quiesce instruction */
162124SN/A    struct EndQuiesceEvent : public Event
163124SN/A    {
164124SN/A        /** A pointer to the execution context that is quiesced */
165124SN/A        ExecContext *xc;
1665606Snate@binkert.org
1675606Snate@binkert.org        EndQuiesceEvent(ExecContext *_xc);
1686221Snate@binkert.org
1695606Snate@binkert.org        /** Event process to occur at interrupt*/
1706221Snate@binkert.org        virtual void process();
1715606Snate@binkert.org
1725606Snate@binkert.org        /** Event description */
173124SN/A        virtual const char *description();
1741400SN/A    };
1755606Snate@binkert.org    EndQuiesceEvent quiesceEvent;
176124SN/A
177124SN/A#else
178124SN/A    Process *process;
179124SN/A
1806221Snate@binkert.org    FunctionalMemory *mem;	// functional storage for process address space
1816221Snate@binkert.org
1825606Snate@binkert.org    // Address space ID.  Note that this is used for TIMING cache
1836221Snate@binkert.org    // simulation only; all functional memory accesses should use
1845606Snate@binkert.org    // one of the FunctionalMemory pointers above.
185124SN/A    short asid;
186124SN/A
1871191SN/A#endif
1885529Snate@binkert.org
1891388SN/A    /**
1901191SN/A     * Temporary storage to pass the source address from copy_load to
1915529Snate@binkert.org     * copy_store.
1921191SN/A     * @todo Remove this temporary when we have a better way to do it.
1935529Snate@binkert.org     */
1941191SN/A    Addr copySrcAddr;
1951191SN/A    /**
1965606Snate@binkert.org     * Temp storage for the physical source address of a copy.
1975606Snate@binkert.org     * @todo Remove this temporary when we have a better way to do it.
1985606Snate@binkert.org     */
1991191SN/A    Addr copySrcPhysAddr;
2001191SN/A
2011917SN/A
2025810Sgblack@eecs.umich.edu    /*
2035810Sgblack@eecs.umich.edu     * number of executed instructions, for matching with syscall trace
2041917SN/A     * points in EIO files.
2055529Snate@binkert.org     */
2065529Snate@binkert.org    Counter func_exe_inst;
2071917SN/A
2085529Snate@binkert.org    //
2091917SN/A    // Count failed store conditionals so we can warn of apparent
2101191SN/A    // application deadlock situations.
2111191SN/A    unsigned storeCondFailures;
2121191SN/A
2131191SN/A    // constructor: initialize context from given process structure
2141191SN/A#if FULL_SYSTEM
2151191SN/A    ExecContext(BaseCPU *_cpu, int _thread_num, System *_system,
2161191SN/A                AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_dem);
2171191SN/A#else
2181191SN/A    ExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid);
2191191SN/A    ExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem,
2201191SN/A                int _asid);
2211129SN/A#endif
2221129SN/A    virtual ~ExecContext();
2231129SN/A
2245529Snate@binkert.org    virtual void takeOverFrom(ExecContext *oldContext);
2252680Sktlim@umich.edu
2261129SN/A    void regStats(const std::string &name);
227180SN/A
2282SN/A    void serialize(std::ostream &os);
2291917SN/A    void unserialize(Checkpoint *cp, const std::string &section);
2301917SN/A
2311917SN/A#if FULL_SYSTEM
2325529Snate@binkert.org    bool validInstAddr(Addr addr) { return true; }
2335606Snate@binkert.org    bool validDataAddr(Addr addr) { return true; }
2341917SN/A    int getInstAsid() { return regs.instAsid(); }
2352356SN/A    int getDataAsid() { return regs.dataAsid(); }
2365529Snate@binkert.org
2375606Snate@binkert.org    Fault translateInstReq(MemReqPtr &req)
2386144Sksewell@umich.edu    {
2396144Sksewell@umich.edu        return itb->translate(req);
2406144Sksewell@umich.edu    }
2412356SN/A
2421917SN/A    Fault translateDataReadReq(MemReqPtr &req)
2431917SN/A    {
2441917SN/A        return dtb->translate(req, false);
2451917SN/A    }
2462SN/A
2472SN/A    Fault translateDataWriteReq(MemReqPtr &req)
248729SN/A    {
249707SN/A        return dtb->translate(req, true);
250707SN/A    }
251707SN/A
252707SN/A#else
253707SN/A    bool validInstAddr(Addr addr)
254707SN/A    { return process->validInstAddr(addr); }
2552680Sktlim@umich.edu
2562SN/A    bool validDataAddr(Addr addr)
2572SN/A    { return process->validDataAddr(addr); }
2582SN/A
2592SN/A    int getInstAsid() { return asid; }
2602680Sktlim@umich.edu    int getDataAsid() { return asid; }
2612SN/A
2622SN/A    Fault dummyTranslation(MemReqPtr &req)
2632680Sktlim@umich.edu    {
2642190SN/A#if 0
2652190SN/A        assert((req->vaddr >> 48 & 0xffff) == 0);
2662190SN/A#endif
2672SN/A
2682SN/A        // put the asid in the upper 16 bits of the paddr
2693495Sktlim@umich.edu        req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16);
2703495Sktlim@umich.edu        req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16;
2713495Sktlim@umich.edu        return NoFault;
2723661Srdreslin@umich.edu    }
2733495Sktlim@umich.edu    Fault translateInstReq(MemReqPtr &req)
2743661Srdreslin@umich.edu    {
2753495Sktlim@umich.edu        return dummyTranslation(req);
2763495Sktlim@umich.edu    }
2773495Sktlim@umich.edu    Fault translateDataReadReq(MemReqPtr &req)
2783495Sktlim@umich.edu    {
2793495Sktlim@umich.edu        return dummyTranslation(req);
2803495Sktlim@umich.edu    }
2813495Sktlim@umich.edu    Fault translateDataWriteReq(MemReqPtr &req)
2824599Sacolyte@umich.edu    {
2834599Sacolyte@umich.edu        return dummyTranslation(req);
2843661Srdreslin@umich.edu    }
2853495Sktlim@umich.edu
2863495Sktlim@umich.edu#endif
2873495Sktlim@umich.edu
2883495Sktlim@umich.edu    template <class T>
289180SN/A    Fault read(MemReqPtr &req, T &data)
290180SN/A    {
2912680Sktlim@umich.edu#if FULL_SYSTEM && defined(TARGET_ALPHA)
292180SN/A        if (req->flags & LOCKED) {
2936221Snate@binkert.org            MiscRegFile *cregs = &req->xc->regs.miscRegs;
2946221Snate@binkert.org            cregs->setReg(TheISA::Lock_Addr_DepTag, req->paddr);
2956221Snate@binkert.org            cregs->setReg(TheISA::Lock_Flag_DepTag, true);
2962378SN/A        }
2975718Shsul@eecs.umich.edu#endif
2985718Shsul@eecs.umich.edu
2995718Shsul@eecs.umich.edu        Fault error;
3005718Shsul@eecs.umich.edu        error = mem->read(req, data);
3015718Shsul@eecs.umich.edu        data = LittleEndianGuest::gtoh(data);
3025718Shsul@eecs.umich.edu        return error;
3035718Shsul@eecs.umich.edu    }
3046221Snate@binkert.org
3055718Shsul@eecs.umich.edu    template <class T>
3065718Shsul@eecs.umich.edu    Fault write(MemReqPtr &req, T &data)
3075718Shsul@eecs.umich.edu    {
3085713Shsul@eecs.umich.edu#if FULL_SYSTEM && defined(TARGET_ALPHA)
3095714Shsul@eecs.umich.edu
310180SN/A        MiscRegFile *cregs;
311180SN/A
312180SN/A        // If this is a store conditional, act appropriately
313180SN/A        if (req->flags & LOCKED) {
314180SN/A            cregs = &req->xc->regs.miscRegs;
3154000Ssaidi@eecs.umich.edu
3164000Ssaidi@eecs.umich.edu            if (req->flags & UNCACHEABLE) {
3174000Ssaidi@eecs.umich.edu                // Don't update result register (see stq_c in isa_desc)
3186221Snate@binkert.org                req->result = 2;
3196221Snate@binkert.org                req->xc->storeCondFailures = 0;//Needed? [RGD]
3206221Snate@binkert.org            } else {
3216221Snate@binkert.org                bool lock_flag = cregs->readReg(TheISA::Lock_Flag_DepTag);
3224000Ssaidi@eecs.umich.edu                Addr lock_addr = cregs->readReg(TheISA::Lock_Addr_DepTag);
3234000Ssaidi@eecs.umich.edu                req->result = lock_flag;
3244000Ssaidi@eecs.umich.edu                if (!lock_flag ||
3254000Ssaidi@eecs.umich.edu                    ((lock_addr & ~0xf) != (req->paddr & ~0xf))) {
326180SN/A                    cregs->setReg(TheISA::Lock_Flag_DepTag, false);
3272798Sktlim@umich.edu                    if (((++req->xc->storeCondFailures) % 100000) == 0) {
328180SN/A                        std::cerr << "Warning: "
3292359SN/A                                  << req->xc->storeCondFailures
3302359SN/A                                  << " consecutive store conditional failures "
3312359SN/A                                  << "on cpu " << req->xc->cpu_id
3325606Snate@binkert.org                                  << std::endl;
3332359SN/A                    }
334180SN/A                    return NoFault;
335180SN/A                }
336180SN/A                else req->xc->storeCondFailures = 0;
3374192Sktlim@umich.edu            }
338180SN/A        }
3392680Sktlim@umich.edu
340180SN/A        // Need to clear any locked flags on other proccessors for
3415712Shsul@eecs.umich.edu        // this address.  Only do this for succsful Store Conditionals
3425712Shsul@eecs.umich.edu        // and all other stores (WH64?).  Unsuccessful Store
3436221Snate@binkert.org        // Conditionals would have returned above, and wouldn't fall
3446221Snate@binkert.org        // through.
3452680Sktlim@umich.edu        for (int i = 0; i < system->execContexts.size(); i++){
3462680Sktlim@umich.edu            cregs = &system->execContexts[i]->regs.miscRegs;
347180SN/A            if ((cregs->readReg(TheISA::Lock_Addr_DepTag) & ~0xf) ==
3482680Sktlim@umich.edu                (req->paddr & ~0xf)) {
3492651Ssaidi@eecs.umich.edu                cregs->setReg(TheISA::Lock_Flag_DepTag, false);
3502680Sktlim@umich.edu            }
3512651Ssaidi@eecs.umich.edu        }
3525714Shsul@eecs.umich.edu
3535715Shsul@eecs.umich.edu#endif
3545714Shsul@eecs.umich.edu        return mem->write(req, (T)LittleEndianGuest::htog(data));
3552359SN/A    }
3565875Ssteve.reinhardt@amd.com
3575875Ssteve.reinhardt@amd.com    virtual bool misspeculating();
3585875Ssteve.reinhardt@amd.com
3595875Ssteve.reinhardt@amd.com
3605217Ssaidi@eecs.umich.edu    MachInst getInst() { return inst; }
3615875Ssteve.reinhardt@amd.com
362180SN/A    void setInst(MachInst new_inst)
363605SN/A    {
3641858SN/A        inst = new_inst;
3653520Sgblack@eecs.umich.edu    }
3665810Sgblack@eecs.umich.edu
3672254SN/A    Fault instRead(MemReqPtr &req)
3686221Snate@binkert.org    {
3692680Sktlim@umich.edu        return mem->read(req, inst);
3702254SN/A    }
3714947Snate@binkert.org
3725606Snate@binkert.org    //
373612SN/A    // New accessors for new decoder.
3744192Sktlim@umich.edu    //
3754192Sktlim@umich.edu    uint64_t readIntReg(int reg_idx)
3764192Sktlim@umich.edu    {
3774192Sktlim@umich.edu        return regs.intRegFile[reg_idx];
3785476Snate@binkert.org    }
3795476Snate@binkert.org
3804192Sktlim@umich.edu    float readFloatRegSingle(int reg_idx)
3815476Snate@binkert.org    {
3824192Sktlim@umich.edu        return (float)regs.floatRegFile.d[reg_idx];
3834192Sktlim@umich.edu    }
3845476Snate@binkert.org
3855476Snate@binkert.org    double readFloatRegDouble(int reg_idx)
3864192Sktlim@umich.edu    {
3875476Snate@binkert.org        return regs.floatRegFile.d[reg_idx];
3884192Sktlim@umich.edu    }
389180SN/A
390180SN/A    uint64_t readFloatRegInt(int reg_idx)
391180SN/A    {
3921858SN/A        return regs.floatRegFile.q[reg_idx];
3935536Srstrong@hp.com    }
3945606Snate@binkert.org
3951917SN/A    void setIntReg(int reg_idx, uint64_t val)
3961917SN/A    {
3971917SN/A        regs.intRegFile[reg_idx] = val;
3981917SN/A    }
3991917SN/A
4006221Snate@binkert.org    void setFloatRegSingle(int reg_idx, float val)
4016221Snate@binkert.org    {
4022680Sktlim@umich.edu        regs.floatRegFile.d[reg_idx] = (double)val;
4032680Sktlim@umich.edu    }
4041917SN/A
4052254SN/A    void setFloatRegDouble(int reg_idx, double val)
4065606Snate@binkert.org    {
4071917SN/A        regs.floatRegFile.d[reg_idx] = val;
4081917SN/A    }
4092SN/A
410921SN/A    void setFloatRegInt(int reg_idx, uint64_t val)
411921SN/A    {
4124000Ssaidi@eecs.umich.edu        regs.floatRegFile.q[reg_idx] = val;
4135647Sgblack@eecs.umich.edu    }
414921SN/A
415921SN/A    uint64_t readPC()
416921SN/A    {
417921SN/A        return regs.pc;
418921SN/A    }
4194000Ssaidi@eecs.umich.edu
4205647Sgblack@eecs.umich.edu    void setNextPC(uint64_t val)
421921SN/A    {
422921SN/A        regs.npc = val;
4232SN/A    }
4242SN/A
4251191SN/A    void setNextNPC(uint64_t val)
4261191SN/A    {
4271191SN/A        regs.nnpc = val;
4281191SN/A    }
4291191SN/A
4301191SN/A
4311191SN/A    MiscReg readMiscReg(int misc_reg)
4321191SN/A    {
4331191SN/A        return regs.miscRegs.readReg(misc_reg);
4341191SN/A    }
4351191SN/A
4361191SN/A    MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
4371191SN/A    {
4381191SN/A        return regs.miscRegs.readRegWithEffect(misc_reg, fault, this);
4391191SN/A    }
4401191SN/A
4411191SN/A    Fault setMiscReg(int misc_reg, const MiscReg &val)
4421191SN/A    {
4431191SN/A        return regs.miscRegs.setReg(misc_reg, val);
4441191SN/A    }
4451191SN/A
4461191SN/A    Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
4471191SN/A    {
4481191SN/A        return regs.miscRegs.setRegWithEffect(misc_reg, val, this);
4491191SN/A    }
4501191SN/A
451#if FULL_SYSTEM
452    int readIntrFlag() { return regs.intrflag; }
453    void setIntrFlag(int val) { regs.intrflag = val; }
454    Fault hwrei();
455    bool inPalMode() { return AlphaISA::PcPAL(regs.pc); }
456    bool simPalCheck(int palFunc);
457#endif
458
459#if !FULL_SYSTEM
460    TheISA::IntReg getSyscallArg(int i)
461    {
462        return regs.intRegFile[TheISA::ArgumentReg0 + i];
463    }
464
465    // used to shift args for indirect syscall
466    void setSyscallArg(int i, TheISA::IntReg val)
467    {
468        regs.intRegFile[TheISA::ArgumentReg0 + i] = val;
469    }
470
471    void setSyscallReturn(SyscallReturn return_value)
472    {
473        // check for error condition.  Alpha syscall convention is to
474        // indicate success/failure in reg a3 (r19) and put the
475        // return value itself in the standard return value reg (v0).
476        const int RegA3 = 19;	// only place this is used
477        if (return_value.successful()) {
478            // no error
479            regs.intRegFile[RegA3] = 0;
480            regs.intRegFile[TheISA::ReturnValueReg] = return_value.value();
481        } else {
482            // got an error, return details
483            regs.intRegFile[RegA3] = (TheISA::IntReg) -1;
484            regs.intRegFile[TheISA::ReturnValueReg] = -return_value.value();
485        }
486    }
487
488    void syscall()
489    {
490        process->syscall(this);
491    }
492#endif
493};
494
495
496// for non-speculative execution context, spec_mode is always false
497inline bool
498ExecContext::misspeculating()
499{
500    return false;
501}
502
503#endif // __CPU_EXEC_CONTEXT_HH__
504