simple_thread.hh revision 2521
12686Sksewell@umich.edu/*
25254Sksewell@umich.edu * Copyright (c) 2001-2006 The Regents of The University of Michigan
35254Sksewell@umich.edu * All rights reserved.
42686Sksewell@umich.edu *
55254Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without
65254Sksewell@umich.edu * modification, are permitted provided that the following conditions are
75254Sksewell@umich.edu * met: redistributions of source code must retain the above copyright
85254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer;
95254Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright
105254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the
115254Sksewell@umich.edu * documentation and/or other materials provided with the distribution;
125254Sksewell@umich.edu * neither the name of the copyright holders nor the names of its
135254Sksewell@umich.edu * contributors may be used to endorse or promote products derived from
145254Sksewell@umich.edu * this software without specific prior written permission.
152686Sksewell@umich.edu *
165254Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175254Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185254Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195254Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205254Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215254Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225254Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235254Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245254Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255254Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265254Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272706Sksewell@umich.edu */
285254Sksewell@umich.edu
292686Sksewell@umich.edu#ifndef __CPU_CPU_EXEC_CONTEXT_HH__
302686Sksewell@umich.edu#define __CPU_CPU_EXEC_CONTEXT_HH__
314661Sksewell@umich.edu
322686Sksewell@umich.edu#include "arch/isa_traits.hh"
334661Sksewell@umich.edu#include "config/full_system.hh"
344661Sksewell@umich.edu#include "cpu/exec_context.hh"
354661Sksewell@umich.edu#include "mem/physical.hh"
364661Sksewell@umich.edu#include "mem/request.hh"
374661Sksewell@umich.edu#include "sim/byteswap.hh"
382980Sgblack@eecs.umich.edu#include "sim/eventq.hh"
392686Sksewell@umich.edu#include "sim/host.hh"
405222Sksewell@umich.edu#include "sim/serialize.hh"
415222Sksewell@umich.edu
425222Sksewell@umich.educlass BaseCPU;
435222Sksewell@umich.edu
445222Sksewell@umich.edu#if FULL_SYSTEM
455222Sksewell@umich.edu
462686Sksewell@umich.edu#include "sim/system.hh"
474661Sksewell@umich.edu#include "arch/tlb.hh"
482686Sksewell@umich.edu
495222Sksewell@umich.educlass FunctionProfile;
505222Sksewell@umich.educlass ProfileNode;
512686Sksewell@umich.educlass FunctionalPort;
525222Sksewell@umich.educlass PhysicalPort;
535222Sksewell@umich.edu
545222Sksewell@umich.edu
555222Sksewell@umich.edu#else // !FULL_SYSTEM
565222Sksewell@umich.edu
575222Sksewell@umich.edu#include "sim/process.hh"
585222Sksewell@umich.edu#include "mem/page_table.hh"
595222Sksewell@umich.educlass TranslatingPort;
605222Sksewell@umich.edu
615222Sksewell@umich.edu
625222Sksewell@umich.edu#endif // FULL_SYSTEM
635222Sksewell@umich.edu
645222Sksewell@umich.edu//
655222Sksewell@umich.edu// The CPUExecContext object represents a functional context for
665222Sksewell@umich.edu// instruction execution.  It incorporates everything required for
675222Sksewell@umich.edu// architecture-level functional simulation of a single thread.
685222Sksewell@umich.edu//
695222Sksewell@umich.edu
705222Sksewell@umich.educlass CPUExecContext
715222Sksewell@umich.edu{
725222Sksewell@umich.edu  protected:
735222Sksewell@umich.edu    typedef TheISA::RegFile RegFile;
745222Sksewell@umich.edu    typedef TheISA::MachInst MachInst;
755222Sksewell@umich.edu    typedef TheISA::MiscRegFile MiscRegFile;
762686Sksewell@umich.edu    typedef TheISA::MiscReg MiscReg;
772686Sksewell@umich.edu    typedef TheISA::FloatReg FloatReg;
782686Sksewell@umich.edu    typedef TheISA::FloatRegBits FloatRegBits;
792686Sksewell@umich.edu  public:
802686Sksewell@umich.edu    typedef ExecContext::Status Status;
812686Sksewell@umich.edu
822686Sksewell@umich.edu  private:
832686Sksewell@umich.edu    Status _status;
842686Sksewell@umich.edu
852686Sksewell@umich.edu  public:
862686Sksewell@umich.edu    Status status() const { return _status; }
872686Sksewell@umich.edu
882686Sksewell@umich.edu    void setStatus(Status newStatus) { _status = newStatus; }
892686Sksewell@umich.edu
902686Sksewell@umich.edu    /// Set the status to Active.  Optional delay indicates number of
912686Sksewell@umich.edu    /// cycles to wait before beginning execution.
922686Sksewell@umich.edu    void activate(int delay = 1);
932686Sksewell@umich.edu
942686Sksewell@umich.edu    /// Set the status to Suspended.
952686Sksewell@umich.edu    void suspend();
962686Sksewell@umich.edu
972686Sksewell@umich.edu    /// Set the status to Unallocated.
982686Sksewell@umich.edu    void deallocate();
992686Sksewell@umich.edu
1002686Sksewell@umich.edu    /// Set the status to Halted.
1012686Sksewell@umich.edu    void halt();
1022686Sksewell@umich.edu
1032686Sksewell@umich.edu  protected:
1042686Sksewell@umich.edu    RegFile regs;	// correct-path register context
1052686Sksewell@umich.edu
1062686Sksewell@umich.edu  public:
1072686Sksewell@umich.edu    // pointer to CPU associated with this context
1082686Sksewell@umich.edu    BaseCPU *cpu;
1092686Sksewell@umich.edu
1102686Sksewell@umich.edu    ProxyExecContext<CPUExecContext> *proxy;
1112686Sksewell@umich.edu
1122686Sksewell@umich.edu    // Current instruction
1132686Sksewell@umich.edu    MachInst inst;
1142686Sksewell@umich.edu
1152686Sksewell@umich.edu    // Index of hardware thread context on the CPU that this represents.
1162686Sksewell@umich.edu    int thread_num;
1172686Sksewell@umich.edu
1182686Sksewell@umich.edu    // ID of this context w.r.t. the System or Process object to which
1195222Sksewell@umich.edu    // it belongs.  For full-system mode, this is the system CPU ID.
1202686Sksewell@umich.edu    int cpu_id;
1212686Sksewell@umich.edu
1222686Sksewell@umich.edu    Tick lastActivate;
1232686Sksewell@umich.edu    Tick lastSuspend;
1242686Sksewell@umich.edu
1252686Sksewell@umich.edu    System *system;
1262686Sksewell@umich.edu
1272686Sksewell@umich.edu
1282686Sksewell@umich.edu#if FULL_SYSTEM
1292686Sksewell@umich.edu    AlphaITB *itb;
1305222Sksewell@umich.edu    AlphaDTB *dtb;
1312686Sksewell@umich.edu
1322686Sksewell@umich.edu    /** A functional port outgoing only for functional accesses to physical
1332686Sksewell@umich.edu     * addresses.*/
1342686Sksewell@umich.edu    FunctionalPort *physPort;
1352686Sksewell@umich.edu
1362686Sksewell@umich.edu    /** A functional port, outgoing only, for functional accesse to virtual
1375222Sksewell@umich.edu     * addresses. That doen't require execution context information */
1382686Sksewell@umich.edu    VirtualPort *virtPort;
1392686Sksewell@umich.edu
1402686Sksewell@umich.edu    FunctionProfile *profile;
1412686Sksewell@umich.edu    ProfileNode *profileNode;
1422686Sksewell@umich.edu    Addr profilePC;
1432686Sksewell@umich.edu    void dumpFuncProfile();
1442686Sksewell@umich.edu
1455222Sksewell@umich.edu    /** Event for timing out quiesce instruction */
1462686Sksewell@umich.edu    struct EndQuiesceEvent : public Event
1472686Sksewell@umich.edu    {
1482686Sksewell@umich.edu        /** A pointer to the execution context that is quiesced */
1492686Sksewell@umich.edu        CPUExecContext *cpuXC;
1502686Sksewell@umich.edu
1512686Sksewell@umich.edu        EndQuiesceEvent(CPUExecContext *_cpuXC);
1522686Sksewell@umich.edu
1532686Sksewell@umich.edu        /** Event process to occur at interrupt*/
1542686Sksewell@umich.edu        virtual void process();
1552686Sksewell@umich.edu
1562686Sksewell@umich.edu        /** Event description */
1575222Sksewell@umich.edu        virtual const char *description();
1582686Sksewell@umich.edu    };
1592686Sksewell@umich.edu    EndQuiesceEvent quiesceEvent;
1602686Sksewell@umich.edu
1612686Sksewell@umich.edu    Event *getQuiesceEvent() { return &quiesceEvent; }
1622686Sksewell@umich.edu
1632686Sksewell@umich.edu    Tick readLastActivate() { return lastActivate; }
1642686Sksewell@umich.edu
1652686Sksewell@umich.edu    Tick readLastSuspend() { return lastSuspend; }
1662686Sksewell@umich.edu
1672686Sksewell@umich.edu    void profileClear();
1682686Sksewell@umich.edu
1692686Sksewell@umich.edu    void profileSample();
1702686Sksewell@umich.edu
1715222Sksewell@umich.edu#else
1722686Sksewell@umich.edu    /// Port that syscalls can use to access memory (provides translation step).
1732686Sksewell@umich.edu    TranslatingPort *port;
1742686Sksewell@umich.edu
1752686Sksewell@umich.edu    Process *process;
1762686Sksewell@umich.edu
1772686Sksewell@umich.edu    // Address space ID.  Note that this is used for TIMING cache
1782686Sksewell@umich.edu    // simulation only; all functional memory accesses should use
1792686Sksewell@umich.edu    // one of the FunctionalMemory pointers above.
1802686Sksewell@umich.edu    short asid;
1812686Sksewell@umich.edu
1822686Sksewell@umich.edu#endif
1832686Sksewell@umich.edu
1842686Sksewell@umich.edu    /**
1852686Sksewell@umich.edu     * Temporary storage to pass the source address from copy_load to
1862686Sksewell@umich.edu     * copy_store.
1872686Sksewell@umich.edu     * @todo Remove this temporary when we have a better way to do it.
1882686Sksewell@umich.edu     */
1892686Sksewell@umich.edu    Addr copySrcAddr;
1902686Sksewell@umich.edu    /**
1912686Sksewell@umich.edu     * Temp storage for the physical source address of a copy.
1922686Sksewell@umich.edu     * @todo Remove this temporary when we have a better way to do it.
1932686Sksewell@umich.edu     */
1945222Sksewell@umich.edu    Addr copySrcPhysAddr;
1952686Sksewell@umich.edu
1962686Sksewell@umich.edu
1972686Sksewell@umich.edu    /*
1982686Sksewell@umich.edu     * number of executed instructions, for matching with syscall trace
1992686Sksewell@umich.edu     * points in EIO files.
2002686Sksewell@umich.edu     */
2012686Sksewell@umich.edu    Counter func_exe_inst;
2022686Sksewell@umich.edu
2032686Sksewell@umich.edu    //
2042686Sksewell@umich.edu    // Count failed store conditionals so we can warn of apparent
2052686Sksewell@umich.edu    // application deadlock situations.
2062686Sksewell@umich.edu    unsigned storeCondFailures;
2072686Sksewell@umich.edu
2082686Sksewell@umich.edu    // constructor: initialize context from given process structure
2092686Sksewell@umich.edu#if FULL_SYSTEM
2102686Sksewell@umich.edu    CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_system,
2112686Sksewell@umich.edu                   AlphaITB *_itb, AlphaDTB *_dtb);
2122686Sksewell@umich.edu#else
2132686Sksewell@umich.edu    CPUExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid,
2142686Sksewell@umich.edu            MemObject *memobj);
2152686Sksewell@umich.edu    // Constructor to use XC to pass reg file around.  Not used for anything
2165222Sksewell@umich.edu    // else.
2172686Sksewell@umich.edu    CPUExecContext(RegFile *regFile);
2182686Sksewell@umich.edu#endif
2192686Sksewell@umich.edu    virtual ~CPUExecContext();
2202686Sksewell@umich.edu
2212686Sksewell@umich.edu    virtual void takeOverFrom(ExecContext *oldContext);
2222686Sksewell@umich.edu
2232686Sksewell@umich.edu    void regStats(const std::string &name);
2242686Sksewell@umich.edu
2252686Sksewell@umich.edu    void serialize(std::ostream &os);
2262686Sksewell@umich.edu    void unserialize(Checkpoint *cp, const std::string &section);
2272686Sksewell@umich.edu
2282686Sksewell@umich.edu    BaseCPU *getCpuPtr() { return cpu; }
2292686Sksewell@umich.edu
2302686Sksewell@umich.edu    ExecContext *getProxy() { return proxy; }
2312686Sksewell@umich.edu
2322686Sksewell@umich.edu    int getThreadNum() { return thread_num; }
2332686Sksewell@umich.edu
2342686Sksewell@umich.edu#if FULL_SYSTEM
2352686Sksewell@umich.edu    System *getSystemPtr() { return system; }
2364661Sksewell@umich.edu
2374661Sksewell@umich.edu    AlphaITB *getITBPtr() { return itb; }
2385222Sksewell@umich.edu
2394661Sksewell@umich.edu    AlphaDTB *getDTBPtr() { return dtb; }
2405222Sksewell@umich.edu
2414661Sksewell@umich.edu    int getInstAsid() { return regs.instAsid(); }
2425222Sksewell@umich.edu    int getDataAsid() { return regs.dataAsid(); }
2435222Sksewell@umich.edu
2445222Sksewell@umich.edu    Fault translateInstReq(CpuRequestPtr &req)
2455222Sksewell@umich.edu    {
2465222Sksewell@umich.edu        return itb->translate(req, proxy);
2475222Sksewell@umich.edu    }
2485222Sksewell@umich.edu
2495222Sksewell@umich.edu    Fault translateDataReadReq(CpuRequestPtr &req)
2505222Sksewell@umich.edu    {
2515222Sksewell@umich.edu        return dtb->translate(req, proxy, false);
2525222Sksewell@umich.edu    }
2535222Sksewell@umich.edu
2545222Sksewell@umich.edu    Fault translateDataWriteReq(CpuRequestPtr &req)
2555222Sksewell@umich.edu    {
2565222Sksewell@umich.edu        return dtb->translate(req, proxy, true);
2575222Sksewell@umich.edu    }
2585222Sksewell@umich.edu
2595222Sksewell@umich.edu    FunctionalPort *getPhysPort() { return physPort; }
2605222Sksewell@umich.edu
2615222Sksewell@umich.edu    /** Return a virtual port. If no exec context is specified then a static
2625222Sksewell@umich.edu     * port is returned. Otherwise a port is created and returned. It must be
2635222Sksewell@umich.edu     * deleted by deleteVirtPort(). */
2645222Sksewell@umich.edu    VirtualPort *getVirtPort(ExecContext *xc);
2655222Sksewell@umich.edu
2665222Sksewell@umich.edu    void delVirtPort(VirtualPort *vp);
267
268#else
269    TranslatingPort *getMemPort() { return port; }
270
271    Process *getProcessPtr() { return process; }
272
273    int getInstAsid() { return asid; }
274    int getDataAsid() { return asid; }
275
276    Fault translateInstReq(CpuRequestPtr &req)
277    {
278        return process->pTable->translate(req);
279    }
280
281    Fault translateDataReadReq(CpuRequestPtr &req)
282    {
283        return process->pTable->translate(req);
284    }
285
286    Fault translateDataWriteReq(CpuRequestPtr &req)
287    {
288        return process->pTable->translate(req);
289    }
290
291#endif
292
293/*
294    template <class T>
295    Fault read(CpuRequestPtr &req, T &data)
296    {
297#if FULL_SYSTEM && THE_ISA == ALPHA_ISA
298        if (req->flags & LOCKED) {
299            req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr);
300            req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true);
301        }
302#endif
303
304        Fault error;
305        error = mem->prot_read(req->paddr, data, req->size);
306        data = LittleEndianGuest::gtoh(data);
307        return error;
308    }
309
310    template <class T>
311    Fault write(CpuRequestPtr &req, T &data)
312    {
313#if FULL_SYSTEM && THE_ISA == ALPHA_ISA
314        ExecContext *xc;
315
316        // If this is a store conditional, act appropriately
317        if (req->flags & LOCKED) {
318            xc = req->xc;
319
320            if (req->flags & UNCACHEABLE) {
321                // Don't update result register (see stq_c in isa_desc)
322                req->result = 2;
323                xc->setStCondFailures(0);//Needed? [RGD]
324            } else {
325                bool lock_flag = xc->readMiscReg(TheISA::Lock_Flag_DepTag);
326                Addr lock_addr = xc->readMiscReg(TheISA::Lock_Addr_DepTag);
327                req->result = lock_flag;
328                if (!lock_flag ||
329                    ((lock_addr & ~0xf) != (req->paddr & ~0xf))) {
330                    xc->setMiscReg(TheISA::Lock_Flag_DepTag, false);
331                    xc->setStCondFailures(xc->readStCondFailures() + 1);
332                    if (((xc->readStCondFailures()) % 100000) == 0) {
333                        std::cerr << "Warning: "
334                                  << xc->readStCondFailures()
335                                  << " consecutive store conditional failures "
336                                  << "on cpu " << req->xc->readCpuId()
337                                  << std::endl;
338                    }
339                    return NoFault;
340                }
341                else xc->setStCondFailures(0);
342            }
343        }
344
345        // Need to clear any locked flags on other proccessors for
346        // this address.  Only do this for succsful Store Conditionals
347        // and all other stores (WH64?).  Unsuccessful Store
348        // Conditionals would have returned above, and wouldn't fall
349        // through.
350        for (int i = 0; i < system->execContexts.size(); i++){
351            xc = system->execContexts[i];
352            if ((xc->readMiscReg(TheISA::Lock_Addr_DepTag) & ~0xf) ==
353                (req->paddr & ~0xf)) {
354                xc->setMiscReg(TheISA::Lock_Flag_DepTag, false);
355            }
356        }
357
358#endif
359        return mem->prot_write(req->paddr, (T)htog(data), req->size);
360    }
361*/
362    virtual bool misspeculating();
363
364
365    MachInst getInst() { return inst; }
366
367    void setInst(MachInst new_inst)
368    {
369        inst = new_inst;
370    }
371
372    Fault instRead(CpuRequestPtr &req)
373    {
374        panic("instRead not implemented");
375        // return funcPhysMem->read(req, inst);
376        return NoFault;
377    }
378
379    void setCpuId(int id) { cpu_id = id; }
380
381    int readCpuId() { return cpu_id; }
382
383    void copyArchRegs(ExecContext *xc);
384
385    //
386    // New accessors for new decoder.
387    //
388    uint64_t readIntReg(int reg_idx)
389    {
390        return regs.intRegFile[reg_idx];
391    }
392
393    FloatReg readFloatReg(int reg_idx, int width)
394    {
395        return regs.floatRegFile.readReg(reg_idx, width);
396    }
397
398    FloatReg readFloatReg(int reg_idx)
399    {
400        return regs.floatRegFile.readReg(reg_idx);
401    }
402
403    FloatRegBits readFloatRegBits(int reg_idx, int width)
404    {
405        return regs.floatRegFile.readRegBits(reg_idx, width);
406    }
407
408    FloatRegBits readFloatRegBits(int reg_idx)
409    {
410        return regs.floatRegFile.readRegBits(reg_idx);
411    }
412
413    void setIntReg(int reg_idx, uint64_t val)
414    {
415        regs.intRegFile[reg_idx] = val;
416    }
417
418    void setFloatReg(int reg_idx, FloatReg val, int width)
419    {
420        regs.floatRegFile.setReg(reg_idx, val, width);
421    }
422
423    void setFloatReg(int reg_idx, FloatReg val)
424    {
425        regs.floatRegFile.setReg(reg_idx, val);
426    }
427
428    void setFloatRegBits(int reg_idx, FloatRegBits val, int width)
429    {
430        regs.floatRegFile.setRegBits(reg_idx, val, width);
431    }
432
433    void setFloatRegBits(int reg_idx, FloatRegBits val)
434    {
435        regs.floatRegFile.setRegBits(reg_idx, val);
436    }
437
438    uint64_t readPC()
439    {
440        return regs.pc;
441    }
442
443    void setPC(uint64_t val)
444    {
445        regs.pc = val;
446    }
447
448    uint64_t readNextPC()
449    {
450        return regs.npc;
451    }
452
453    void setNextPC(uint64_t val)
454    {
455        regs.npc = val;
456    }
457
458    uint64_t readNextNPC()
459    {
460        return regs.nnpc;
461    }
462
463    void setNextNPC(uint64_t val)
464    {
465        regs.nnpc = val;
466    }
467
468
469    MiscReg readMiscReg(int misc_reg)
470    {
471        return regs.miscRegs.readReg(misc_reg);
472    }
473
474    MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
475    {
476        return regs.miscRegs.readRegWithEffect(misc_reg, fault, proxy);
477    }
478
479    Fault setMiscReg(int misc_reg, const MiscReg &val)
480    {
481        return regs.miscRegs.setReg(misc_reg, val);
482    }
483
484    Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
485    {
486        return regs.miscRegs.setRegWithEffect(misc_reg, val, proxy);
487    }
488
489    unsigned readStCondFailures() { return storeCondFailures; }
490
491    void setStCondFailures(unsigned sc_failures)
492    { storeCondFailures = sc_failures; }
493
494    void clearArchRegs() { memset(&regs, 0, sizeof(regs)); }
495
496#if FULL_SYSTEM
497    int readIntrFlag() { return regs.intrflag; }
498    void setIntrFlag(int val) { regs.intrflag = val; }
499    Fault hwrei();
500    bool inPalMode() { return AlphaISA::PcPAL(regs.pc); }
501    bool simPalCheck(int palFunc);
502#endif
503
504#if !FULL_SYSTEM
505    TheISA::IntReg getSyscallArg(int i)
506    {
507        return regs.intRegFile[TheISA::ArgumentReg0 + i];
508    }
509
510    // used to shift args for indirect syscall
511    void setSyscallArg(int i, TheISA::IntReg val)
512    {
513        regs.intRegFile[TheISA::ArgumentReg0 + i] = val;
514    }
515
516    void setSyscallReturn(SyscallReturn return_value)
517    {
518        TheISA::setSyscallReturn(return_value, &regs);
519    }
520
521    void syscall()
522    {
523        process->syscall(proxy);
524    }
525
526    Counter readFuncExeInst() { return func_exe_inst; }
527
528    void setFuncExeInst(Counter new_val) { func_exe_inst = new_val; }
529#endif
530};
531
532
533// for non-speculative execution context, spec_mode is always false
534inline bool
535CPUExecContext::misspeculating()
536{
537    return false;
538}
539
540#endif // __CPU_CPU_EXEC_CONTEXT_HH__
541