simple_thread.hh revision 13910:d5deee7b4279
1/*
2 * Copyright (c) 2011-2012, 2016-2018 ARM Limited
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
4 * All rights reserved
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder.  You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
14 *
15 * Copyright (c) 2001-2006 The Regents of The University of Michigan
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Authors: Steve Reinhardt
42 *          Nathan Binkert
43 */
44
45#ifndef __CPU_SIMPLE_THREAD_HH__
46#define __CPU_SIMPLE_THREAD_HH__
47
48#include "arch/decoder.hh"
49#include "arch/generic/tlb.hh"
50#include "arch/isa.hh"
51#include "arch/isa_traits.hh"
52#include "arch/registers.hh"
53#include "arch/types.hh"
54#include "base/types.hh"
55#include "config/the_isa.hh"
56#include "cpu/thread_context.hh"
57#include "cpu/thread_state.hh"
58#include "debug/CCRegs.hh"
59#include "debug/FloatRegs.hh"
60#include "debug/IntRegs.hh"
61#include "debug/VecPredRegs.hh"
62#include "debug/VecRegs.hh"
63#include "mem/page_table.hh"
64#include "mem/request.hh"
65#include "sim/byteswap.hh"
66#include "sim/eventq.hh"
67#include "sim/process.hh"
68#include "sim/serialize.hh"
69#include "sim/system.hh"
70
71class BaseCPU;
72class CheckerCPU;
73
74class FunctionProfile;
75class ProfileNode;
76
77namespace Kernel {
78    class Statistics;
79}
80
81/**
82 * The SimpleThread object provides a combination of the ThreadState
83 * object and the ThreadContext interface. It implements the
84 * ThreadContext interface and adds to the ThreadState object by adding all
85 * the objects needed for simple functional execution, including a
86 * simple architectural register file, and pointers to the ITB and DTB
87 * in full system mode. For CPU models that do not need more advanced
88 * ways to hold state (i.e. a separate physical register file, or
89 * separate fetch and commit PC's), this SimpleThread class provides
90 * all the necessary state for full architecture-level functional
91 * simulation.  See the AtomicSimpleCPU or TimingSimpleCPU for
92 * examples.
93 */
94
95class SimpleThread : public ThreadState, public ThreadContext
96{
97  protected:
98    typedef TheISA::MachInst MachInst;
99    using VecRegContainer = TheISA::VecRegContainer;
100    using VecElem = TheISA::VecElem;
101    using VecPredRegContainer = TheISA::VecPredRegContainer;
102  public:
103    typedef ThreadContext::Status Status;
104
105  protected:
106    RegVal floatRegs[TheISA::NumFloatRegs];
107    RegVal intRegs[TheISA::NumIntRegs];
108    VecRegContainer vecRegs[TheISA::NumVecRegs];
109    VecPredRegContainer vecPredRegs[TheISA::NumVecPredRegs];
110#ifdef ISA_HAS_CC_REGS
111    RegVal ccRegs[TheISA::NumCCRegs];
112#endif
113    TheISA::ISA *const isa;    // one "instance" of the current ISA.
114
115    TheISA::PCState _pcState;
116
117    /** Did this instruction execute or is it predicated false */
118    bool predicate;
119
120  public:
121    std::string name() const
122    {
123        return csprintf("%s.[tid:%i]", baseCpu->name(), threadId());
124    }
125
126    System *system;
127
128    BaseTLB *itb;
129    BaseTLB *dtb;
130
131    TheISA::Decoder decoder;
132
133    // constructor: initialize SimpleThread from given process structure
134    // FS
135    SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system,
136                 BaseTLB *_itb, BaseTLB *_dtb, TheISA::ISA *_isa,
137                 bool use_kernel_stats = true);
138    // SE
139    SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system,
140                 Process *_process, BaseTLB *_itb, BaseTLB *_dtb,
141                 TheISA::ISA *_isa);
142
143    virtual ~SimpleThread() {}
144
145    void takeOverFrom(ThreadContext *oldContext) override;
146
147    void regStats(const std::string &name) override;
148
149    void copyState(ThreadContext *oldContext);
150
151    void serialize(CheckpointOut &cp) const override;
152    void unserialize(CheckpointIn &cp) override;
153    void startup();
154
155    /***************************************************************
156     *  SimpleThread functions to provide CPU with access to various
157     *  state.
158     **************************************************************/
159
160    /** Returns the pointer to this SimpleThread's ThreadContext. Used
161     *  when a ThreadContext must be passed to objects outside of the
162     *  CPU.
163     */
164    ThreadContext *getTC() { return this; }
165
166    void demapPage(Addr vaddr, uint64_t asn)
167    {
168        itb->demapPage(vaddr, asn);
169        dtb->demapPage(vaddr, asn);
170    }
171
172    void demapInstPage(Addr vaddr, uint64_t asn)
173    {
174        itb->demapPage(vaddr, asn);
175    }
176
177    void demapDataPage(Addr vaddr, uint64_t asn)
178    {
179        dtb->demapPage(vaddr, asn);
180    }
181
182    void dumpFuncProfile() override;
183
184    /*******************************************
185     * ThreadContext interface functions.
186     ******************************************/
187
188    BaseCPU *getCpuPtr() override { return baseCpu; }
189
190    int cpuId() const override { return ThreadState::cpuId(); }
191    uint32_t socketId() const override { return ThreadState::socketId(); }
192    int threadId() const override { return ThreadState::threadId(); }
193    void setThreadId(int id) override { ThreadState::setThreadId(id); }
194    ContextID contextId() const override { return ThreadState::contextId(); }
195    void setContextId(ContextID id) override { ThreadState::setContextId(id); }
196
197    BaseTLB *getITBPtr() override { return itb; }
198
199    BaseTLB *getDTBPtr() override { return dtb; }
200
201    CheckerCPU *getCheckerCpuPtr() override { return NULL; }
202
203    TheISA::ISA *getIsaPtr() override { return isa; }
204
205    TheISA::Decoder *getDecoderPtr() override { return &decoder; }
206
207    System *getSystemPtr() override { return system; }
208
209    Kernel::Statistics *
210    getKernelStats() override
211    {
212        return ThreadState::getKernelStats();
213    }
214
215    PortProxy &getPhysProxy() override { return ThreadState::getPhysProxy(); }
216    FSTranslatingPortProxy &
217    getVirtProxy() override
218    {
219        return ThreadState::getVirtProxy();
220    }
221
222    void initMemProxies(ThreadContext *tc) override
223    {
224        ThreadState::initMemProxies(tc);
225    }
226
227    SETranslatingPortProxy &
228    getMemProxy() override
229    {
230        return ThreadState::getMemProxy();
231    }
232
233    Process *getProcessPtr() override { return ThreadState::getProcessPtr(); }
234    void setProcessPtr(Process *p) override { ThreadState::setProcessPtr(p); }
235
236    Status status() const override { return _status; }
237
238    void setStatus(Status newStatus) override { _status = newStatus; }
239
240    /// Set the status to Active.
241    void activate() override;
242
243    /// Set the status to Suspended.
244    void suspend() override;
245
246    /// Set the status to Halted.
247    void halt() override;
248
249    EndQuiesceEvent *
250    getQuiesceEvent() override
251    {
252        return ThreadState::getQuiesceEvent();
253    }
254
255    Tick
256    readLastActivate() override
257    {
258        return ThreadState::readLastActivate();
259    }
260    Tick
261    readLastSuspend() override
262    {
263        return ThreadState::readLastSuspend();
264    }
265
266    void profileClear() override { ThreadState::profileClear(); }
267    void profileSample() override { ThreadState::profileSample(); }
268
269    void copyArchRegs(ThreadContext *tc) override;
270
271    void clearArchRegs() override
272    {
273        _pcState = 0;
274        memset(intRegs, 0, sizeof(intRegs));
275        memset(floatRegs, 0, sizeof(floatRegs));
276        for (int i = 0; i < TheISA::NumVecRegs; i++) {
277            vecRegs[i].zero();
278        }
279        for (int i = 0; i < TheISA::NumVecPredRegs; i++) {
280            vecPredRegs[i].reset();
281        }
282#ifdef ISA_HAS_CC_REGS
283        memset(ccRegs, 0, sizeof(ccRegs));
284#endif
285        isa->clear();
286    }
287
288    //
289    // New accessors for new decoder.
290    //
291    RegVal
292    readIntReg(RegIndex reg_idx) const override
293    {
294        int flatIndex = isa->flattenIntIndex(reg_idx);
295        assert(flatIndex < TheISA::NumIntRegs);
296        uint64_t regVal(readIntRegFlat(flatIndex));
297        DPRINTF(IntRegs, "Reading int reg %d (%d) as %#x.\n",
298                reg_idx, flatIndex, regVal);
299        return regVal;
300    }
301
302    RegVal
303    readFloatReg(RegIndex reg_idx) const override
304    {
305        int flatIndex = isa->flattenFloatIndex(reg_idx);
306        assert(flatIndex < TheISA::NumFloatRegs);
307        RegVal regVal(readFloatRegFlat(flatIndex));
308        DPRINTF(FloatRegs, "Reading float reg %d (%d) bits as %#x.\n",
309                reg_idx, flatIndex, regVal);
310        return regVal;
311    }
312
313    const VecRegContainer&
314    readVecReg(const RegId& reg) const override
315    {
316        int flatIndex = isa->flattenVecIndex(reg.index());
317        assert(flatIndex < TheISA::NumVecRegs);
318        const VecRegContainer& regVal = readVecRegFlat(flatIndex);
319        DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s.\n",
320                reg.index(), flatIndex, regVal.print());
321        return regVal;
322    }
323
324    VecRegContainer&
325    getWritableVecReg(const RegId& reg) override
326    {
327        int flatIndex = isa->flattenVecIndex(reg.index());
328        assert(flatIndex < TheISA::NumVecRegs);
329        VecRegContainer& regVal = getWritableVecRegFlat(flatIndex);
330        DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s for modify.\n",
331                reg.index(), flatIndex, regVal.print());
332        return regVal;
333    }
334
335    /** Vector Register Lane Interfaces. */
336    /** @{ */
337    /** Reads source vector <T> operand. */
338    template <typename T>
339    VecLaneT<T, true>
340    readVecLane(const RegId& reg) const
341    {
342        int flatIndex = isa->flattenVecIndex(reg.index());
343        assert(flatIndex < TheISA::NumVecRegs);
344        auto regVal = readVecLaneFlat<T>(flatIndex, reg.elemIndex());
345        DPRINTF(VecRegs, "Reading vector lane %d (%d)[%d] as %lx.\n",
346                reg.index(), flatIndex, reg.elemIndex(), regVal);
347        return regVal;
348    }
349
350    /** Reads source vector 8bit operand. */
351    virtual ConstVecLane8
352    readVec8BitLaneReg(const RegId &reg) const override
353    {
354        return readVecLane<uint8_t>(reg);
355    }
356
357    /** Reads source vector 16bit operand. */
358    virtual ConstVecLane16
359    readVec16BitLaneReg(const RegId &reg) const override
360    {
361        return readVecLane<uint16_t>(reg);
362    }
363
364    /** Reads source vector 32bit operand. */
365    virtual ConstVecLane32
366    readVec32BitLaneReg(const RegId &reg) const override
367    {
368        return readVecLane<uint32_t>(reg);
369    }
370
371    /** Reads source vector 64bit operand. */
372    virtual ConstVecLane64
373    readVec64BitLaneReg(const RegId &reg) const override
374    {
375        return readVecLane<uint64_t>(reg);
376    }
377
378    /** Write a lane of the destination vector register. */
379    template <typename LD>
380    void
381    setVecLaneT(const RegId &reg, const LD &val)
382    {
383        int flatIndex = isa->flattenVecIndex(reg.index());
384        assert(flatIndex < TheISA::NumVecRegs);
385        setVecLaneFlat(flatIndex, reg.elemIndex(), val);
386        DPRINTF(VecRegs, "Reading vector lane %d (%d)[%d] to %lx.\n",
387                reg.index(), flatIndex, reg.elemIndex(), val);
388    }
389    virtual void
390    setVecLane(const RegId &reg, const LaneData<LaneSize::Byte> &val) override
391    {
392        return setVecLaneT(reg, val);
393    }
394    virtual void
395    setVecLane(const RegId &reg,
396               const LaneData<LaneSize::TwoByte> &val) override
397    {
398        return setVecLaneT(reg, val);
399    }
400    virtual void
401    setVecLane(const RegId &reg,
402               const LaneData<LaneSize::FourByte> &val) override
403    {
404        return setVecLaneT(reg, val);
405    }
406    virtual void
407    setVecLane(const RegId &reg,
408               const LaneData<LaneSize::EightByte> &val) override
409    {
410        return setVecLaneT(reg, val);
411    }
412    /** @} */
413
414    const VecElem &
415    readVecElem(const RegId &reg) const override
416    {
417        int flatIndex = isa->flattenVecElemIndex(reg.index());
418        assert(flatIndex < TheISA::NumVecRegs);
419        const VecElem& regVal = readVecElemFlat(flatIndex, reg.elemIndex());
420        DPRINTF(VecRegs, "Reading element %d of vector reg %d (%d) as"
421                " %#x.\n", reg.elemIndex(), reg.index(), flatIndex, regVal);
422        return regVal;
423    }
424
425    const VecPredRegContainer &
426    readVecPredReg(const RegId &reg) const override
427    {
428        int flatIndex = isa->flattenVecPredIndex(reg.index());
429        assert(flatIndex < TheISA::NumVecPredRegs);
430        const VecPredRegContainer& regVal = readVecPredRegFlat(flatIndex);
431        DPRINTF(VecPredRegs, "Reading predicate reg %d (%d) as %s.\n",
432                reg.index(), flatIndex, regVal.print());
433        return regVal;
434    }
435
436    VecPredRegContainer &
437    getWritableVecPredReg(const RegId &reg) override
438    {
439        int flatIndex = isa->flattenVecPredIndex(reg.index());
440        assert(flatIndex < TheISA::NumVecPredRegs);
441        VecPredRegContainer& regVal = getWritableVecPredRegFlat(flatIndex);
442        DPRINTF(VecPredRegs,
443                "Reading predicate reg %d (%d) as %s for modify.\n",
444                reg.index(), flatIndex, regVal.print());
445        return regVal;
446    }
447
448    RegVal
449    readCCReg(RegIndex reg_idx) const override
450    {
451#ifdef ISA_HAS_CC_REGS
452        int flatIndex = isa->flattenCCIndex(reg_idx);
453        assert(0 <= flatIndex);
454        assert(flatIndex < TheISA::NumCCRegs);
455        uint64_t regVal(readCCRegFlat(flatIndex));
456        DPRINTF(CCRegs, "Reading CC reg %d (%d) as %#x.\n",
457                reg_idx, flatIndex, regVal);
458        return regVal;
459#else
460        panic("Tried to read a CC register.");
461        return 0;
462#endif
463    }
464
465    void
466    setIntReg(RegIndex reg_idx, RegVal val) override
467    {
468        int flatIndex = isa->flattenIntIndex(reg_idx);
469        assert(flatIndex < TheISA::NumIntRegs);
470        DPRINTF(IntRegs, "Setting int reg %d (%d) to %#x.\n",
471                reg_idx, flatIndex, val);
472        setIntRegFlat(flatIndex, val);
473    }
474
475    void
476    setFloatReg(RegIndex reg_idx, RegVal val) override
477    {
478        int flatIndex = isa->flattenFloatIndex(reg_idx);
479        assert(flatIndex < TheISA::NumFloatRegs);
480        // XXX: Fix array out of bounds compiler error for gem5.fast
481        // when checkercpu enabled
482        if (flatIndex < TheISA::NumFloatRegs)
483            setFloatRegFlat(flatIndex, val);
484        DPRINTF(FloatRegs, "Setting float reg %d (%d) bits to %#x.\n",
485                reg_idx, flatIndex, val);
486    }
487
488    void
489    setVecReg(const RegId &reg, const VecRegContainer &val) override
490    {
491        int flatIndex = isa->flattenVecIndex(reg.index());
492        assert(flatIndex < TheISA::NumVecRegs);
493        setVecRegFlat(flatIndex, val);
494        DPRINTF(VecRegs, "Setting vector reg %d (%d) to %s.\n",
495                reg.index(), flatIndex, val.print());
496    }
497
498    void
499    setVecElem(const RegId &reg, const VecElem &val) override
500    {
501        int flatIndex = isa->flattenVecElemIndex(reg.index());
502        assert(flatIndex < TheISA::NumVecRegs);
503        setVecElemFlat(flatIndex, reg.elemIndex(), val);
504        DPRINTF(VecRegs, "Setting element %d of vector reg %d (%d) to"
505                " %#x.\n", reg.elemIndex(), reg.index(), flatIndex, val);
506    }
507
508    void
509    setVecPredReg(const RegId &reg, const VecPredRegContainer &val) override
510    {
511        int flatIndex = isa->flattenVecPredIndex(reg.index());
512        assert(flatIndex < TheISA::NumVecPredRegs);
513        setVecPredRegFlat(flatIndex, val);
514        DPRINTF(VecPredRegs, "Setting predicate reg %d (%d) to %s.\n",
515                reg.index(), flatIndex, val.print());
516    }
517
518    void
519    setCCReg(RegIndex reg_idx, RegVal val) override
520    {
521#ifdef ISA_HAS_CC_REGS
522        int flatIndex = isa->flattenCCIndex(reg_idx);
523        assert(flatIndex < TheISA::NumCCRegs);
524        DPRINTF(CCRegs, "Setting CC reg %d (%d) to %#x.\n",
525                reg_idx, flatIndex, val);
526        setCCRegFlat(flatIndex, val);
527#else
528        panic("Tried to set a CC register.");
529#endif
530    }
531
532    TheISA::PCState pcState() const override { return _pcState; }
533    void pcState(const TheISA::PCState &val) override { _pcState = val; }
534
535    void
536    pcStateNoRecord(const TheISA::PCState &val) override
537    {
538        _pcState = val;
539    }
540
541    Addr instAddr() const override  { return _pcState.instAddr(); }
542    Addr nextInstAddr() const override { return _pcState.nextInstAddr(); }
543    MicroPC microPC() const override { return _pcState.microPC(); }
544    bool readPredicate() const { return predicate; }
545    void setPredicate(bool val) { predicate = val; }
546
547    RegVal
548    readMiscRegNoEffect(RegIndex misc_reg) const override
549    {
550        return isa->readMiscRegNoEffect(misc_reg);
551    }
552
553    RegVal
554    readMiscReg(RegIndex misc_reg) override
555    {
556        return isa->readMiscReg(misc_reg, this);
557    }
558
559    void
560    setMiscRegNoEffect(RegIndex misc_reg, RegVal val) override
561    {
562        return isa->setMiscRegNoEffect(misc_reg, val);
563    }
564
565    void
566    setMiscReg(RegIndex misc_reg, RegVal val) override
567    {
568        return isa->setMiscReg(misc_reg, val, this);
569    }
570
571    RegId
572    flattenRegId(const RegId& regId) const override
573    {
574        return isa->flattenRegId(regId);
575    }
576
577    unsigned readStCondFailures() const override { return storeCondFailures; }
578
579    void
580    setStCondFailures(unsigned sc_failures) override
581    {
582        storeCondFailures = sc_failures;
583    }
584
585    Counter
586    readFuncExeInst() const override
587    {
588        return ThreadState::readFuncExeInst();
589    }
590
591    void
592    syscall(int64_t callnum, Fault *fault) override
593    {
594        process->syscall(callnum, this, fault);
595    }
596
597    RegVal readIntRegFlat(RegIndex idx) const override { return intRegs[idx]; }
598    void
599    setIntRegFlat(RegIndex idx, RegVal val) override
600    {
601        intRegs[idx] = val;
602    }
603
604    RegVal
605    readFloatRegFlat(RegIndex idx) const override
606    {
607        return floatRegs[idx];
608    }
609    void
610    setFloatRegFlat(RegIndex idx, RegVal val) override
611    {
612        floatRegs[idx] = val;
613    }
614
615    const VecRegContainer &
616    readVecRegFlat(RegIndex reg) const override
617    {
618        return vecRegs[reg];
619    }
620
621    VecRegContainer &
622    getWritableVecRegFlat(RegIndex reg) override
623    {
624        return vecRegs[reg];
625    }
626
627    void
628    setVecRegFlat(RegIndex reg, const VecRegContainer &val) override
629    {
630        vecRegs[reg] = val;
631    }
632
633    template <typename T>
634    VecLaneT<T, true>
635    readVecLaneFlat(RegIndex reg, int lId) const
636    {
637        return vecRegs[reg].laneView<T>(lId);
638    }
639
640    template <typename LD>
641    void
642    setVecLaneFlat(RegIndex reg, int lId, const LD &val)
643    {
644        vecRegs[reg].laneView<typename LD::UnderlyingType>(lId) = val;
645    }
646
647    const VecElem &
648    readVecElemFlat(RegIndex reg, const ElemIndex &elemIndex) const override
649    {
650        return vecRegs[reg].as<TheISA::VecElem>()[elemIndex];
651    }
652
653    void
654    setVecElemFlat(RegIndex reg, const ElemIndex &elemIndex,
655                   const VecElem &val) override
656    {
657        vecRegs[reg].as<TheISA::VecElem>()[elemIndex] = val;
658    }
659
660    const VecPredRegContainer &
661    readVecPredRegFlat(RegIndex reg) const override
662    {
663        return vecPredRegs[reg];
664    }
665
666    VecPredRegContainer &
667    getWritableVecPredRegFlat(RegIndex reg) override
668    {
669        return vecPredRegs[reg];
670    }
671
672    void
673    setVecPredRegFlat(RegIndex reg, const VecPredRegContainer &val) override
674    {
675        vecPredRegs[reg] = val;
676    }
677
678#ifdef ISA_HAS_CC_REGS
679    RegVal readCCRegFlat(RegIndex idx) const override { return ccRegs[idx]; }
680    void setCCRegFlat(RegIndex idx, RegVal val) override { ccRegs[idx] = val; }
681#else
682    RegVal
683    readCCRegFlat(RegIndex idx) const override
684    {
685        panic("readCCRegFlat w/no CC regs!\n");
686    }
687
688    void
689    setCCRegFlat(RegIndex idx, RegVal val) override
690    {
691        panic("setCCRegFlat w/no CC regs!\n");
692    }
693#endif
694};
695
696
697#endif // __CPU_CPU_EXEC_CONTEXT_HH__
698