simple_thread.hh revision 13953
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    /** True if the memory access should be skipped for this instruction */
121    bool memAccPredicate;
122
123  public:
124    std::string name() const
125    {
126        return csprintf("%s.[tid:%i]", baseCpu->name(), threadId());
127    }
128
129    System *system;
130
131    BaseTLB *itb;
132    BaseTLB *dtb;
133
134    TheISA::Decoder decoder;
135
136    // constructor: initialize SimpleThread from given process structure
137    // FS
138    SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system,
139                 BaseTLB *_itb, BaseTLB *_dtb, TheISA::ISA *_isa,
140                 bool use_kernel_stats = true);
141    // SE
142    SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system,
143                 Process *_process, BaseTLB *_itb, BaseTLB *_dtb,
144                 TheISA::ISA *_isa);
145
146    virtual ~SimpleThread() {}
147
148    void takeOverFrom(ThreadContext *oldContext) override;
149
150    void regStats(const std::string &name) override;
151
152    void copyState(ThreadContext *oldContext);
153
154    void serialize(CheckpointOut &cp) const override;
155    void unserialize(CheckpointIn &cp) override;
156    void startup();
157
158    /***************************************************************
159     *  SimpleThread functions to provide CPU with access to various
160     *  state.
161     **************************************************************/
162
163    /** Returns the pointer to this SimpleThread's ThreadContext. Used
164     *  when a ThreadContext must be passed to objects outside of the
165     *  CPU.
166     */
167    ThreadContext *getTC() { return this; }
168
169    void demapPage(Addr vaddr, uint64_t asn)
170    {
171        itb->demapPage(vaddr, asn);
172        dtb->demapPage(vaddr, asn);
173    }
174
175    void demapInstPage(Addr vaddr, uint64_t asn)
176    {
177        itb->demapPage(vaddr, asn);
178    }
179
180    void demapDataPage(Addr vaddr, uint64_t asn)
181    {
182        dtb->demapPage(vaddr, asn);
183    }
184
185    void dumpFuncProfile() override;
186
187    /*******************************************
188     * ThreadContext interface functions.
189     ******************************************/
190
191    BaseCPU *getCpuPtr() override { return baseCpu; }
192
193    int cpuId() const override { return ThreadState::cpuId(); }
194    uint32_t socketId() const override { return ThreadState::socketId(); }
195    int threadId() const override { return ThreadState::threadId(); }
196    void setThreadId(int id) override { ThreadState::setThreadId(id); }
197    ContextID contextId() const override { return ThreadState::contextId(); }
198    void setContextId(ContextID id) override { ThreadState::setContextId(id); }
199
200    BaseTLB *getITBPtr() override { return itb; }
201
202    BaseTLB *getDTBPtr() override { return dtb; }
203
204    CheckerCPU *getCheckerCpuPtr() override { return NULL; }
205
206    TheISA::ISA *getIsaPtr() override { return isa; }
207
208    TheISA::Decoder *getDecoderPtr() override { return &decoder; }
209
210    System *getSystemPtr() override { return system; }
211
212    Kernel::Statistics *
213    getKernelStats() override
214    {
215        return ThreadState::getKernelStats();
216    }
217
218    PortProxy &getPhysProxy() override { return ThreadState::getPhysProxy(); }
219    FSTranslatingPortProxy &
220    getVirtProxy() override
221    {
222        return ThreadState::getVirtProxy();
223    }
224
225    void initMemProxies(ThreadContext *tc) override
226    {
227        ThreadState::initMemProxies(tc);
228    }
229
230    SETranslatingPortProxy &
231    getMemProxy() override
232    {
233        return ThreadState::getMemProxy();
234    }
235
236    Process *getProcessPtr() override { return ThreadState::getProcessPtr(); }
237    void setProcessPtr(Process *p) override { ThreadState::setProcessPtr(p); }
238
239    Status status() const override { return _status; }
240
241    void setStatus(Status newStatus) override { _status = newStatus; }
242
243    /// Set the status to Active.
244    void activate() override;
245
246    /// Set the status to Suspended.
247    void suspend() override;
248
249    /// Set the status to Halted.
250    void halt() override;
251
252    EndQuiesceEvent *
253    getQuiesceEvent() override
254    {
255        return ThreadState::getQuiesceEvent();
256    }
257
258    Tick
259    readLastActivate() override
260    {
261        return ThreadState::readLastActivate();
262    }
263    Tick
264    readLastSuspend() override
265    {
266        return ThreadState::readLastSuspend();
267    }
268
269    void profileClear() override { ThreadState::profileClear(); }
270    void profileSample() override { ThreadState::profileSample(); }
271
272    void copyArchRegs(ThreadContext *tc) override;
273
274    void clearArchRegs() override
275    {
276        _pcState = 0;
277        memset(intRegs, 0, sizeof(intRegs));
278        memset(floatRegs, 0, sizeof(floatRegs));
279        for (int i = 0; i < TheISA::NumVecRegs; i++) {
280            vecRegs[i].zero();
281        }
282        for (int i = 0; i < TheISA::NumVecPredRegs; i++) {
283            vecPredRegs[i].reset();
284        }
285#ifdef ISA_HAS_CC_REGS
286        memset(ccRegs, 0, sizeof(ccRegs));
287#endif
288        isa->clear();
289    }
290
291    //
292    // New accessors for new decoder.
293    //
294    RegVal
295    readIntReg(RegIndex reg_idx) const override
296    {
297        int flatIndex = isa->flattenIntIndex(reg_idx);
298        assert(flatIndex < TheISA::NumIntRegs);
299        uint64_t regVal(readIntRegFlat(flatIndex));
300        DPRINTF(IntRegs, "Reading int reg %d (%d) as %#x.\n",
301                reg_idx, flatIndex, regVal);
302        return regVal;
303    }
304
305    RegVal
306    readFloatReg(RegIndex reg_idx) const override
307    {
308        int flatIndex = isa->flattenFloatIndex(reg_idx);
309        assert(flatIndex < TheISA::NumFloatRegs);
310        RegVal regVal(readFloatRegFlat(flatIndex));
311        DPRINTF(FloatRegs, "Reading float reg %d (%d) bits as %#x.\n",
312                reg_idx, flatIndex, regVal);
313        return regVal;
314    }
315
316    const VecRegContainer&
317    readVecReg(const RegId& reg) const override
318    {
319        int flatIndex = isa->flattenVecIndex(reg.index());
320        assert(flatIndex < TheISA::NumVecRegs);
321        const VecRegContainer& regVal = readVecRegFlat(flatIndex);
322        DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s.\n",
323                reg.index(), flatIndex, regVal.print());
324        return regVal;
325    }
326
327    VecRegContainer&
328    getWritableVecReg(const RegId& reg) override
329    {
330        int flatIndex = isa->flattenVecIndex(reg.index());
331        assert(flatIndex < TheISA::NumVecRegs);
332        VecRegContainer& regVal = getWritableVecRegFlat(flatIndex);
333        DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s for modify.\n",
334                reg.index(), flatIndex, regVal.print());
335        return regVal;
336    }
337
338    /** Vector Register Lane Interfaces. */
339    /** @{ */
340    /** Reads source vector <T> operand. */
341    template <typename T>
342    VecLaneT<T, true>
343    readVecLane(const RegId& reg) const
344    {
345        int flatIndex = isa->flattenVecIndex(reg.index());
346        assert(flatIndex < TheISA::NumVecRegs);
347        auto regVal = readVecLaneFlat<T>(flatIndex, reg.elemIndex());
348        DPRINTF(VecRegs, "Reading vector lane %d (%d)[%d] as %lx.\n",
349                reg.index(), flatIndex, reg.elemIndex(), regVal);
350        return regVal;
351    }
352
353    /** Reads source vector 8bit operand. */
354    virtual ConstVecLane8
355    readVec8BitLaneReg(const RegId &reg) const override
356    {
357        return readVecLane<uint8_t>(reg);
358    }
359
360    /** Reads source vector 16bit operand. */
361    virtual ConstVecLane16
362    readVec16BitLaneReg(const RegId &reg) const override
363    {
364        return readVecLane<uint16_t>(reg);
365    }
366
367    /** Reads source vector 32bit operand. */
368    virtual ConstVecLane32
369    readVec32BitLaneReg(const RegId &reg) const override
370    {
371        return readVecLane<uint32_t>(reg);
372    }
373
374    /** Reads source vector 64bit operand. */
375    virtual ConstVecLane64
376    readVec64BitLaneReg(const RegId &reg) const override
377    {
378        return readVecLane<uint64_t>(reg);
379    }
380
381    /** Write a lane of the destination vector register. */
382    template <typename LD>
383    void
384    setVecLaneT(const RegId &reg, const LD &val)
385    {
386        int flatIndex = isa->flattenVecIndex(reg.index());
387        assert(flatIndex < TheISA::NumVecRegs);
388        setVecLaneFlat(flatIndex, reg.elemIndex(), val);
389        DPRINTF(VecRegs, "Reading vector lane %d (%d)[%d] to %lx.\n",
390                reg.index(), flatIndex, reg.elemIndex(), val);
391    }
392    virtual void
393    setVecLane(const RegId &reg, const LaneData<LaneSize::Byte> &val) override
394    {
395        return setVecLaneT(reg, val);
396    }
397    virtual void
398    setVecLane(const RegId &reg,
399               const LaneData<LaneSize::TwoByte> &val) override
400    {
401        return setVecLaneT(reg, val);
402    }
403    virtual void
404    setVecLane(const RegId &reg,
405               const LaneData<LaneSize::FourByte> &val) override
406    {
407        return setVecLaneT(reg, val);
408    }
409    virtual void
410    setVecLane(const RegId &reg,
411               const LaneData<LaneSize::EightByte> &val) override
412    {
413        return setVecLaneT(reg, val);
414    }
415    /** @} */
416
417    const VecElem &
418    readVecElem(const RegId &reg) const override
419    {
420        int flatIndex = isa->flattenVecElemIndex(reg.index());
421        assert(flatIndex < TheISA::NumVecRegs);
422        const VecElem& regVal = readVecElemFlat(flatIndex, reg.elemIndex());
423        DPRINTF(VecRegs, "Reading element %d of vector reg %d (%d) as"
424                " %#x.\n", reg.elemIndex(), reg.index(), flatIndex, regVal);
425        return regVal;
426    }
427
428    const VecPredRegContainer &
429    readVecPredReg(const RegId &reg) const override
430    {
431        int flatIndex = isa->flattenVecPredIndex(reg.index());
432        assert(flatIndex < TheISA::NumVecPredRegs);
433        const VecPredRegContainer& regVal = readVecPredRegFlat(flatIndex);
434        DPRINTF(VecPredRegs, "Reading predicate reg %d (%d) as %s.\n",
435                reg.index(), flatIndex, regVal.print());
436        return regVal;
437    }
438
439    VecPredRegContainer &
440    getWritableVecPredReg(const RegId &reg) override
441    {
442        int flatIndex = isa->flattenVecPredIndex(reg.index());
443        assert(flatIndex < TheISA::NumVecPredRegs);
444        VecPredRegContainer& regVal = getWritableVecPredRegFlat(flatIndex);
445        DPRINTF(VecPredRegs,
446                "Reading predicate reg %d (%d) as %s for modify.\n",
447                reg.index(), flatIndex, regVal.print());
448        return regVal;
449    }
450
451    RegVal
452    readCCReg(RegIndex reg_idx) const override
453    {
454#ifdef ISA_HAS_CC_REGS
455        int flatIndex = isa->flattenCCIndex(reg_idx);
456        assert(0 <= flatIndex);
457        assert(flatIndex < TheISA::NumCCRegs);
458        uint64_t regVal(readCCRegFlat(flatIndex));
459        DPRINTF(CCRegs, "Reading CC reg %d (%d) as %#x.\n",
460                reg_idx, flatIndex, regVal);
461        return regVal;
462#else
463        panic("Tried to read a CC register.");
464        return 0;
465#endif
466    }
467
468    void
469    setIntReg(RegIndex reg_idx, RegVal val) override
470    {
471        int flatIndex = isa->flattenIntIndex(reg_idx);
472        assert(flatIndex < TheISA::NumIntRegs);
473        DPRINTF(IntRegs, "Setting int reg %d (%d) to %#x.\n",
474                reg_idx, flatIndex, val);
475        setIntRegFlat(flatIndex, val);
476    }
477
478    void
479    setFloatReg(RegIndex reg_idx, RegVal val) override
480    {
481        int flatIndex = isa->flattenFloatIndex(reg_idx);
482        assert(flatIndex < TheISA::NumFloatRegs);
483        // XXX: Fix array out of bounds compiler error for gem5.fast
484        // when checkercpu enabled
485        if (flatIndex < TheISA::NumFloatRegs)
486            setFloatRegFlat(flatIndex, val);
487        DPRINTF(FloatRegs, "Setting float reg %d (%d) bits to %#x.\n",
488                reg_idx, flatIndex, val);
489    }
490
491    void
492    setVecReg(const RegId &reg, const VecRegContainer &val) override
493    {
494        int flatIndex = isa->flattenVecIndex(reg.index());
495        assert(flatIndex < TheISA::NumVecRegs);
496        setVecRegFlat(flatIndex, val);
497        DPRINTF(VecRegs, "Setting vector reg %d (%d) to %s.\n",
498                reg.index(), flatIndex, val.print());
499    }
500
501    void
502    setVecElem(const RegId &reg, const VecElem &val) override
503    {
504        int flatIndex = isa->flattenVecElemIndex(reg.index());
505        assert(flatIndex < TheISA::NumVecRegs);
506        setVecElemFlat(flatIndex, reg.elemIndex(), val);
507        DPRINTF(VecRegs, "Setting element %d of vector reg %d (%d) to"
508                " %#x.\n", reg.elemIndex(), reg.index(), flatIndex, val);
509    }
510
511    void
512    setVecPredReg(const RegId &reg, const VecPredRegContainer &val) override
513    {
514        int flatIndex = isa->flattenVecPredIndex(reg.index());
515        assert(flatIndex < TheISA::NumVecPredRegs);
516        setVecPredRegFlat(flatIndex, val);
517        DPRINTF(VecPredRegs, "Setting predicate reg %d (%d) to %s.\n",
518                reg.index(), flatIndex, val.print());
519    }
520
521    void
522    setCCReg(RegIndex reg_idx, RegVal val) override
523    {
524#ifdef ISA_HAS_CC_REGS
525        int flatIndex = isa->flattenCCIndex(reg_idx);
526        assert(flatIndex < TheISA::NumCCRegs);
527        DPRINTF(CCRegs, "Setting CC reg %d (%d) to %#x.\n",
528                reg_idx, flatIndex, val);
529        setCCRegFlat(flatIndex, val);
530#else
531        panic("Tried to set a CC register.");
532#endif
533    }
534
535    TheISA::PCState pcState() const override { return _pcState; }
536    void pcState(const TheISA::PCState &val) override { _pcState = val; }
537
538    void
539    pcStateNoRecord(const TheISA::PCState &val) override
540    {
541        _pcState = val;
542    }
543
544    Addr instAddr() const override  { return _pcState.instAddr(); }
545    Addr nextInstAddr() const override { return _pcState.nextInstAddr(); }
546    MicroPC microPC() const override { return _pcState.microPC(); }
547    bool readPredicate() const { return predicate; }
548    void setPredicate(bool val) { predicate = val; }
549
550    RegVal
551    readMiscRegNoEffect(RegIndex misc_reg) const override
552    {
553        return isa->readMiscRegNoEffect(misc_reg);
554    }
555
556    RegVal
557    readMiscReg(RegIndex misc_reg) override
558    {
559        return isa->readMiscReg(misc_reg, this);
560    }
561
562    void
563    setMiscRegNoEffect(RegIndex misc_reg, RegVal val) override
564    {
565        return isa->setMiscRegNoEffect(misc_reg, val);
566    }
567
568    void
569    setMiscReg(RegIndex misc_reg, RegVal val) override
570    {
571        return isa->setMiscReg(misc_reg, val, this);
572    }
573
574    RegId
575    flattenRegId(const RegId& regId) const override
576    {
577        return isa->flattenRegId(regId);
578    }
579
580    unsigned readStCondFailures() const override { return storeCondFailures; }
581
582    bool
583    readMemAccPredicate()
584    {
585        return memAccPredicate;
586    }
587
588    void
589    setMemAccPredicate(bool val)
590    {
591        memAccPredicate = val;
592    }
593
594    void
595    setStCondFailures(unsigned sc_failures) override
596    {
597        storeCondFailures = sc_failures;
598    }
599
600    Counter
601    readFuncExeInst() const override
602    {
603        return ThreadState::readFuncExeInst();
604    }
605
606    void
607    syscall(int64_t callnum, Fault *fault) override
608    {
609        process->syscall(callnum, this, fault);
610    }
611
612    RegVal readIntRegFlat(RegIndex idx) const override { return intRegs[idx]; }
613    void
614    setIntRegFlat(RegIndex idx, RegVal val) override
615    {
616        intRegs[idx] = val;
617    }
618
619    RegVal
620    readFloatRegFlat(RegIndex idx) const override
621    {
622        return floatRegs[idx];
623    }
624    void
625    setFloatRegFlat(RegIndex idx, RegVal val) override
626    {
627        floatRegs[idx] = val;
628    }
629
630    const VecRegContainer &
631    readVecRegFlat(RegIndex reg) const override
632    {
633        return vecRegs[reg];
634    }
635
636    VecRegContainer &
637    getWritableVecRegFlat(RegIndex reg) override
638    {
639        return vecRegs[reg];
640    }
641
642    void
643    setVecRegFlat(RegIndex reg, const VecRegContainer &val) override
644    {
645        vecRegs[reg] = val;
646    }
647
648    template <typename T>
649    VecLaneT<T, true>
650    readVecLaneFlat(RegIndex reg, int lId) const
651    {
652        return vecRegs[reg].laneView<T>(lId);
653    }
654
655    template <typename LD>
656    void
657    setVecLaneFlat(RegIndex reg, int lId, const LD &val)
658    {
659        vecRegs[reg].laneView<typename LD::UnderlyingType>(lId) = val;
660    }
661
662    const VecElem &
663    readVecElemFlat(RegIndex reg, const ElemIndex &elemIndex) const override
664    {
665        return vecRegs[reg].as<TheISA::VecElem>()[elemIndex];
666    }
667
668    void
669    setVecElemFlat(RegIndex reg, const ElemIndex &elemIndex,
670                   const VecElem &val) override
671    {
672        vecRegs[reg].as<TheISA::VecElem>()[elemIndex] = val;
673    }
674
675    const VecPredRegContainer &
676    readVecPredRegFlat(RegIndex reg) const override
677    {
678        return vecPredRegs[reg];
679    }
680
681    VecPredRegContainer &
682    getWritableVecPredRegFlat(RegIndex reg) override
683    {
684        return vecPredRegs[reg];
685    }
686
687    void
688    setVecPredRegFlat(RegIndex reg, const VecPredRegContainer &val) override
689    {
690        vecPredRegs[reg] = val;
691    }
692
693#ifdef ISA_HAS_CC_REGS
694    RegVal readCCRegFlat(RegIndex idx) const override { return ccRegs[idx]; }
695    void setCCRegFlat(RegIndex idx, RegVal val) override { ccRegs[idx] = val; }
696#else
697    RegVal
698    readCCRegFlat(RegIndex idx) const override
699    {
700        panic("readCCRegFlat w/no CC regs!\n");
701    }
702
703    void
704    setCCRegFlat(RegIndex idx, RegVal val) override
705    {
706        panic("setCCRegFlat w/no CC regs!\n");
707    }
708#endif
709};
710
711
712#endif // __CPU_CPU_EXEC_CONTEXT_HH__
713