exec_context.hh revision 13954
1/*
2 * Copyright (c) 2011-2014, 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) 2002-2005 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 *          Dave Greene
43 *          Nathan Binkert
44 *          Andrew Bardsley
45 */
46
47/**
48 * @file
49 *
50 *  ExecContext bears the exec_context interface for Minor.
51 */
52
53#ifndef __CPU_MINOR_EXEC_CONTEXT_HH__
54#define __CPU_MINOR_EXEC_CONTEXT_HH__
55
56#include "cpu/exec_context.hh"
57#include "cpu/minor/execute.hh"
58#include "cpu/minor/pipeline.hh"
59#include "cpu/base.hh"
60#include "cpu/simple_thread.hh"
61#include "mem/request.hh"
62#include "debug/MinorExecute.hh"
63
64namespace Minor
65{
66
67/* Forward declaration of Execute */
68class Execute;
69
70/** ExecContext bears the exec_context interface for Minor.  This nicely
71 *  separates that interface from other classes such as Pipeline, MinorCPU
72 *  and DynMinorInst and makes it easier to see what state is accessed by it.
73 */
74class ExecContext : public ::ExecContext
75{
76  public:
77    MinorCPU &cpu;
78
79    /** ThreadState object, provides all the architectural state. */
80    SimpleThread &thread;
81
82    /** The execute stage so we can peek at its contents. */
83    Execute &execute;
84
85    /** Instruction for the benefit of memory operations and for PC */
86    MinorDynInstPtr inst;
87
88    ExecContext (
89        MinorCPU &cpu_,
90        SimpleThread &thread_, Execute &execute_,
91        MinorDynInstPtr inst_) :
92        cpu(cpu_),
93        thread(thread_),
94        execute(execute_),
95        inst(inst_)
96    {
97        DPRINTF(MinorExecute, "ExecContext setting PC: %s\n", inst->pc);
98        pcState(inst->pc);
99        setPredicate(inst->readPredicate());
100        setMemAccPredicate(inst->readMemAccPredicate());
101        thread.setIntReg(TheISA::ZeroReg, 0);
102#if THE_ISA == ALPHA_ISA
103        thread.setFloatReg(TheISA::ZeroReg, 0);
104#endif
105    }
106
107    ~ExecContext()
108    {
109        inst->setPredicate(readPredicate());
110        inst->setMemAccPredicate(readMemAccPredicate());
111    }
112
113    Fault
114    initiateMemRead(Addr addr, unsigned int size,
115                    Request::Flags flags,
116                    const std::vector<bool>& byteEnable = std::vector<bool>())
117        override
118    {
119        execute.getLSQ().pushRequest(inst, true /* load */, nullptr,
120            size, addr, flags, nullptr, nullptr, byteEnable);
121        return NoFault;
122    }
123
124    Fault
125    writeMem(uint8_t *data, unsigned int size, Addr addr,
126             Request::Flags flags, uint64_t *res,
127             const std::vector<bool>& byteEnable = std::vector<bool>())
128        override
129    {
130        assert(byteEnable.empty() || byteEnable.size() == size);
131        execute.getLSQ().pushRequest(inst, false /* store */, data,
132            size, addr, flags, res, nullptr, byteEnable);
133        return NoFault;
134    }
135
136    Fault
137    initiateMemAMO(Addr addr, unsigned int size, Request::Flags flags,
138                   AtomicOpFunctor *amo_op) override
139    {
140        // AMO requests are pushed through the store path
141        execute.getLSQ().pushRequest(inst, false /* amo */, nullptr,
142            size, addr, flags, nullptr, amo_op);
143        return NoFault;
144    }
145
146    RegVal
147    readIntRegOperand(const StaticInst *si, int idx) override
148    {
149        const RegId& reg = si->srcRegIdx(idx);
150        assert(reg.isIntReg());
151        return thread.readIntReg(reg.index());
152    }
153
154    RegVal
155    readFloatRegOperandBits(const StaticInst *si, int idx) override
156    {
157        const RegId& reg = si->srcRegIdx(idx);
158        assert(reg.isFloatReg());
159        return thread.readFloatReg(reg.index());
160    }
161
162    const TheISA::VecRegContainer &
163    readVecRegOperand(const StaticInst *si, int idx) const override
164    {
165        const RegId& reg = si->srcRegIdx(idx);
166        assert(reg.isVecReg());
167        return thread.readVecReg(reg);
168    }
169
170    TheISA::VecRegContainer &
171    getWritableVecRegOperand(const StaticInst *si, int idx) override
172    {
173        const RegId& reg = si->destRegIdx(idx);
174        assert(reg.isVecReg());
175        return thread.getWritableVecReg(reg);
176    }
177
178    TheISA::VecElem
179    readVecElemOperand(const StaticInst *si, int idx) const override
180    {
181        const RegId& reg = si->srcRegIdx(idx);
182        assert(reg.isVecElem());
183        return thread.readVecElem(reg);
184    }
185
186    const TheISA::VecPredRegContainer&
187    readVecPredRegOperand(const StaticInst *si, int idx) const override
188    {
189        const RegId& reg = si->srcRegIdx(idx);
190        assert(reg.isVecPredReg());
191        return thread.readVecPredReg(reg);
192    }
193
194    TheISA::VecPredRegContainer&
195    getWritableVecPredRegOperand(const StaticInst *si, int idx) override
196    {
197        const RegId& reg = si->destRegIdx(idx);
198        assert(reg.isVecPredReg());
199        return thread.getWritableVecPredReg(reg);
200    }
201
202    void
203    setIntRegOperand(const StaticInst *si, int idx, RegVal val) override
204    {
205        const RegId& reg = si->destRegIdx(idx);
206        assert(reg.isIntReg());
207        thread.setIntReg(reg.index(), val);
208    }
209
210    void
211    setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override
212    {
213        const RegId& reg = si->destRegIdx(idx);
214        assert(reg.isFloatReg());
215        thread.setFloatReg(reg.index(), val);
216    }
217
218    void
219    setVecRegOperand(const StaticInst *si, int idx,
220                     const TheISA::VecRegContainer& val) override
221    {
222        const RegId& reg = si->destRegIdx(idx);
223        assert(reg.isVecReg());
224        thread.setVecReg(reg, val);
225    }
226
227    void
228    setVecPredRegOperand(const StaticInst *si, int idx,
229                         const TheISA::VecPredRegContainer& val) override
230    {
231        const RegId& reg = si->destRegIdx(idx);
232        assert(reg.isVecPredReg());
233        thread.setVecPredReg(reg, val);
234    }
235
236    /** Vector Register Lane Interfaces. */
237    /** @{ */
238    /** Reads source vector 8bit operand. */
239    ConstVecLane8
240    readVec8BitLaneOperand(const StaticInst *si, int idx) const
241                            override
242    {
243        const RegId& reg = si->srcRegIdx(idx);
244        assert(reg.isVecReg());
245        return thread.readVec8BitLaneReg(reg);
246    }
247
248    /** Reads source vector 16bit operand. */
249    ConstVecLane16
250    readVec16BitLaneOperand(const StaticInst *si, int idx) const
251                            override
252    {
253        const RegId& reg = si->srcRegIdx(idx);
254        assert(reg.isVecReg());
255        return thread.readVec16BitLaneReg(reg);
256    }
257
258    /** Reads source vector 32bit operand. */
259    ConstVecLane32
260    readVec32BitLaneOperand(const StaticInst *si, int idx) const
261                            override
262    {
263        const RegId& reg = si->srcRegIdx(idx);
264        assert(reg.isVecReg());
265        return thread.readVec32BitLaneReg(reg);
266    }
267
268    /** Reads source vector 64bit operand. */
269    ConstVecLane64
270    readVec64BitLaneOperand(const StaticInst *si, int idx) const
271                            override
272    {
273        const RegId& reg = si->srcRegIdx(idx);
274        assert(reg.isVecReg());
275        return thread.readVec64BitLaneReg(reg);
276    }
277
278    /** Write a lane of the destination vector operand. */
279    template <typename LD>
280    void
281    setVecLaneOperandT(const StaticInst *si, int idx, const LD& val)
282    {
283        const RegId& reg = si->destRegIdx(idx);
284        assert(reg.isVecReg());
285        return thread.setVecLane(reg, val);
286    }
287    virtual void
288    setVecLaneOperand(const StaticInst *si, int idx,
289            const LaneData<LaneSize::Byte>& val) override
290    {
291        setVecLaneOperandT(si, idx, val);
292    }
293    virtual void
294    setVecLaneOperand(const StaticInst *si, int idx,
295            const LaneData<LaneSize::TwoByte>& val) override
296    {
297        setVecLaneOperandT(si, idx, val);
298    }
299    virtual void
300    setVecLaneOperand(const StaticInst *si, int idx,
301            const LaneData<LaneSize::FourByte>& val) override
302    {
303        setVecLaneOperandT(si, idx, val);
304    }
305    virtual void
306    setVecLaneOperand(const StaticInst *si, int idx,
307            const LaneData<LaneSize::EightByte>& val) override
308    {
309        setVecLaneOperandT(si, idx, val);
310    }
311    /** @} */
312
313    void
314    setVecElemOperand(const StaticInst *si, int idx,
315                      const TheISA::VecElem val) override
316    {
317        const RegId& reg = si->destRegIdx(idx);
318        assert(reg.isVecElem());
319        thread.setVecElem(reg, val);
320    }
321
322    bool
323    readPredicate() const override
324    {
325        return thread.readPredicate();
326    }
327
328    void
329    setPredicate(bool val) override
330    {
331        thread.setPredicate(val);
332    }
333
334    bool
335    readMemAccPredicate() const override
336    {
337        return thread.readMemAccPredicate();
338    }
339
340    void
341    setMemAccPredicate(bool val) override
342    {
343        thread.setMemAccPredicate(val);
344    }
345
346    TheISA::PCState
347    pcState() const override
348    {
349        return thread.pcState();
350    }
351
352    void
353    pcState(const TheISA::PCState &val) override
354    {
355        thread.pcState(val);
356    }
357
358    RegVal
359    readMiscRegNoEffect(int misc_reg) const
360    {
361        return thread.readMiscRegNoEffect(misc_reg);
362    }
363
364    RegVal
365    readMiscReg(int misc_reg) override
366    {
367        return thread.readMiscReg(misc_reg);
368    }
369
370    void
371    setMiscReg(int misc_reg, RegVal val) override
372    {
373        thread.setMiscReg(misc_reg, val);
374    }
375
376    RegVal
377    readMiscRegOperand(const StaticInst *si, int idx) override
378    {
379        const RegId& reg = si->srcRegIdx(idx);
380        assert(reg.isMiscReg());
381        return thread.readMiscReg(reg.index());
382    }
383
384    void
385    setMiscRegOperand(const StaticInst *si, int idx, RegVal val) override
386    {
387        const RegId& reg = si->destRegIdx(idx);
388        assert(reg.isMiscReg());
389        return thread.setMiscReg(reg.index(), val);
390    }
391
392    void
393    syscall(int64_t callnum, Fault *fault) override
394    {
395        if (FullSystem)
396            panic("Syscall emulation isn't available in FS mode.\n");
397
398        thread.syscall(callnum, fault);
399    }
400
401    ThreadContext *tcBase() override { return thread.getTC(); }
402
403    /* @todo, should make stCondFailures persistent somewhere */
404    unsigned int readStCondFailures() const override { return 0; }
405    void setStCondFailures(unsigned int st_cond_failures) override {}
406
407    ContextID contextId() { return thread.contextId(); }
408    /* ISA-specific (or at least currently ISA singleton) functions */
409
410    /* X86: TLB twiddling */
411    void
412    demapPage(Addr vaddr, uint64_t asn) override
413    {
414        thread.getITBPtr()->demapPage(vaddr, asn);
415        thread.getDTBPtr()->demapPage(vaddr, asn);
416    }
417
418    RegVal
419    readCCRegOperand(const StaticInst *si, int idx) override
420    {
421        const RegId& reg = si->srcRegIdx(idx);
422        assert(reg.isCCReg());
423        return thread.readCCReg(reg.index());
424    }
425
426    void
427    setCCRegOperand(const StaticInst *si, int idx, RegVal val) override
428    {
429        const RegId& reg = si->destRegIdx(idx);
430        assert(reg.isCCReg());
431        thread.setCCReg(reg.index(), val);
432    }
433
434    void
435    demapInstPage(Addr vaddr, uint64_t asn)
436    {
437        thread.getITBPtr()->demapPage(vaddr, asn);
438    }
439
440    void
441    demapDataPage(Addr vaddr, uint64_t asn)
442    {
443        thread.getDTBPtr()->demapPage(vaddr, asn);
444    }
445
446    BaseCPU *getCpuPtr() { return &cpu; }
447
448  public:
449    // monitor/mwait funtions
450    void armMonitor(Addr address) override
451    { getCpuPtr()->armMonitor(inst->id.threadId, address); }
452
453    bool mwait(PacketPtr pkt) override
454    { return getCpuPtr()->mwait(inst->id.threadId, pkt); }
455
456    void mwaitAtomic(ThreadContext *tc) override
457    { return getCpuPtr()->mwaitAtomic(inst->id.threadId, tc, thread.dtb); }
458
459    AddressMonitor *getAddrMonitor() override
460    { return getCpuPtr()->getCpuAddrMonitor(inst->id.threadId); }
461};
462
463}
464
465#endif /* __CPU_MINOR_EXEC_CONTEXT_HH__ */
466