exec_context.hh revision 10319
113207Sgabeblack@google.com/*
213207Sgabeblack@google.com * Copyright (c) 2011-2014 ARM Limited
313207Sgabeblack@google.com * Copyright (c) 2013 Advanced Micro Devices, Inc.
413207Sgabeblack@google.com * All rights reserved
513207Sgabeblack@google.com *
613207Sgabeblack@google.com * The license below extends only to copyright in the software and shall
713207Sgabeblack@google.com * not be construed as granting a license to any other intellectual
813207Sgabeblack@google.com * property including but not limited to intellectual property relating
913207Sgabeblack@google.com * to a hardware implementation of the functionality of the software
1013207Sgabeblack@google.com * licensed hereunder.  You may use the software subject to the license
1113207Sgabeblack@google.com * terms below provided that you ensure that this notice is replicated
1213207Sgabeblack@google.com * unmodified and in its entirety in all distributions of the software,
1313207Sgabeblack@google.com * modified or unmodified, in source code or in binary form.
1413207Sgabeblack@google.com *
1513207Sgabeblack@google.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
1613207Sgabeblack@google.com * All rights reserved.
1713207Sgabeblack@google.com *
1813207Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
1913207Sgabeblack@google.com * modification, are permitted provided that the following conditions are
2013207Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
2113207Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
2213207Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
2313207Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
2413207Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
2513207Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
2613207Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
2713207Sgabeblack@google.com * this software without specific prior written permission.
2813207Sgabeblack@google.com *
2913207Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3013207Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3113207Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3213207Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3313207Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3413207Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3513207Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3613239Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3713207Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3813207Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3913207Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4013207Sgabeblack@google.com *
4113207Sgabeblack@google.com * Authors: Steve Reinhardt
4213207Sgabeblack@google.com *          Dave Greene
4313207Sgabeblack@google.com *          Nathan Binkert
4413207Sgabeblack@google.com *          Andrew Bardsley
4513260Sgabeblack@google.com */
4613207Sgabeblack@google.com
4713207Sgabeblack@google.com/**
4813207Sgabeblack@google.com * @file
4913207Sgabeblack@google.com *
5013207Sgabeblack@google.com *  ExecContext bears the exec_context interface for Minor.
5113207Sgabeblack@google.com */
5213207Sgabeblack@google.com
5313207Sgabeblack@google.com#ifndef __CPU_MINOR_EXEC_CONTEXT_HH__
5413207Sgabeblack@google.com#define __CPU_MINOR_EXEC_CONTEXT_HH__
5513207Sgabeblack@google.com
5613207Sgabeblack@google.com#include "cpu/exec_context.hh"
5713207Sgabeblack@google.com#include "cpu/minor/execute.hh"
5813207Sgabeblack@google.com#include "cpu/minor/pipeline.hh"
5913207Sgabeblack@google.com#include "cpu/base.hh"
6013207Sgabeblack@google.com#include "cpu/simple_thread.hh"
6113207Sgabeblack@google.com#include "debug/MinorExecute.hh"
6213260Sgabeblack@google.com
6313207Sgabeblack@google.comnamespace Minor
6413207Sgabeblack@google.com{
6513239Sgabeblack@google.com
6613207Sgabeblack@google.com/* Forward declaration of Execute */
6713239Sgabeblack@google.comclass Execute;
6813239Sgabeblack@google.com
6913239Sgabeblack@google.com/** ExecContext bears the exec_context interface for Minor.  This nicely
7013239Sgabeblack@google.com *  separates that interface from other classes such as Pipeline, MinorCPU
7113239Sgabeblack@google.com *  and DynMinorInst and makes it easier to see what state is accessed by it.
7213239Sgabeblack@google.com */
7313239Sgabeblack@google.comclass ExecContext : public ::ExecContext
7413239Sgabeblack@google.com{
7513239Sgabeblack@google.com  public:
7613207Sgabeblack@google.com    MinorCPU &cpu;
7713239Sgabeblack@google.com
7813207Sgabeblack@google.com    /** ThreadState object, provides all the architectural state. */
7913207Sgabeblack@google.com    SimpleThread &thread;
8013207Sgabeblack@google.com
8113207Sgabeblack@google.com    /** The execute stage so we can peek at its contents. */
8213207Sgabeblack@google.com    Execute &execute;
8313207Sgabeblack@google.com
8413207Sgabeblack@google.com    /** Instruction for the benefit of memory operations and for PC */
8513207Sgabeblack@google.com    MinorDynInstPtr inst;
8613207Sgabeblack@google.com
8713207Sgabeblack@google.com    ExecContext (
8813207Sgabeblack@google.com        MinorCPU &cpu_,
8913207Sgabeblack@google.com        SimpleThread &thread_, Execute &execute_,
9013207Sgabeblack@google.com        MinorDynInstPtr inst_) :
9113207Sgabeblack@google.com        cpu(cpu_),
9213207Sgabeblack@google.com        thread(thread_),
9313207Sgabeblack@google.com        execute(execute_),
9413207Sgabeblack@google.com        inst(inst_)
9513207Sgabeblack@google.com    {
9613207Sgabeblack@google.com        DPRINTF(MinorExecute, "ExecContext setting PC: %s\n", inst->pc);
9713207Sgabeblack@google.com        pcState(inst->pc);
9813207Sgabeblack@google.com        setPredicate(true);
9913207Sgabeblack@google.com        thread.setIntReg(TheISA::ZeroReg, 0);
10013207Sgabeblack@google.com#if THE_ISA == ALPHA_ISA
10113207Sgabeblack@google.com        thread.setFloatReg(TheISA::ZeroReg, 0.0);
10213207Sgabeblack@google.com#endif
10313207Sgabeblack@google.com    }
10413207Sgabeblack@google.com
10513207Sgabeblack@google.com    Fault
10613207Sgabeblack@google.com    readMem(Addr addr, uint8_t *data, unsigned int size,
10713207Sgabeblack@google.com        unsigned int flags)
10813207Sgabeblack@google.com    {
10913207Sgabeblack@google.com        execute.getLSQ().pushRequest(inst, true /* load */, data,
11013260Sgabeblack@google.com            size, addr, flags, NULL);
11113207Sgabeblack@google.com        return NoFault;
11213207Sgabeblack@google.com    }
11313207Sgabeblack@google.com
11413260Sgabeblack@google.com    Fault
11513260Sgabeblack@google.com    writeMem(uint8_t *data, unsigned int size, Addr addr,
11613260Sgabeblack@google.com        unsigned int flags, uint64_t *res)
11713260Sgabeblack@google.com    {
11813260Sgabeblack@google.com        execute.getLSQ().pushRequest(inst, false /* store */, data,
11913207Sgabeblack@google.com            size, addr, flags, res);
12013207Sgabeblack@google.com        return NoFault;
12113207Sgabeblack@google.com    }
12213207Sgabeblack@google.com
12313260Sgabeblack@google.com    IntReg
12413207Sgabeblack@google.com    readIntRegOperand(const StaticInst *si, int idx)
12513207Sgabeblack@google.com    {
12613207Sgabeblack@google.com        return thread.readIntReg(si->srcRegIdx(idx));
12713207Sgabeblack@google.com    }
12813207Sgabeblack@google.com
12913207Sgabeblack@google.com    TheISA::FloatReg
13013207Sgabeblack@google.com    readFloatRegOperand(const StaticInst *si, int idx)
13113207Sgabeblack@google.com    {
13213207Sgabeblack@google.com        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
13313207Sgabeblack@google.com        return thread.readFloatReg(reg_idx);
13413207Sgabeblack@google.com    }
13513207Sgabeblack@google.com
13613207Sgabeblack@google.com    TheISA::FloatRegBits
13713207Sgabeblack@google.com    readFloatRegOperandBits(const StaticInst *si, int idx)
13813207Sgabeblack@google.com    {
13913207Sgabeblack@google.com        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
14013207Sgabeblack@google.com        return thread.readFloatRegBits(reg_idx);
14113207Sgabeblack@google.com    }
14213207Sgabeblack@google.com
14313207Sgabeblack@google.com    void
14413207Sgabeblack@google.com    setIntRegOperand(const StaticInst *si, int idx, IntReg val)
14513207Sgabeblack@google.com    {
14613207Sgabeblack@google.com        thread.setIntReg(si->destRegIdx(idx), val);
14713270Sgabeblack@google.com    }
14813270Sgabeblack@google.com
14913270Sgabeblack@google.com    void
15013270Sgabeblack@google.com    setFloatRegOperand(const StaticInst *si, int idx,
15113207Sgabeblack@google.com        TheISA::FloatReg val)
15213207Sgabeblack@google.com    {
15313207Sgabeblack@google.com        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
15413207Sgabeblack@google.com        thread.setFloatReg(reg_idx, val);
15513207Sgabeblack@google.com    }
15613207Sgabeblack@google.com
15713207Sgabeblack@google.com    void
15813207Sgabeblack@google.com    setFloatRegOperandBits(const StaticInst *si, int idx,
15913207Sgabeblack@google.com        TheISA::FloatRegBits val)
16013207Sgabeblack@google.com    {
16113260Sgabeblack@google.com        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
16213207Sgabeblack@google.com        thread.setFloatRegBits(reg_idx, val);
16313207Sgabeblack@google.com    }
16413207Sgabeblack@google.com
16513207Sgabeblack@google.com    bool
16613207Sgabeblack@google.com    readPredicate()
16713207Sgabeblack@google.com    {
16813207Sgabeblack@google.com        return thread.readPredicate();
16913207Sgabeblack@google.com    }
17013207Sgabeblack@google.com
17113207Sgabeblack@google.com    void
172    setPredicate(bool val)
173    {
174        thread.setPredicate(val);
175    }
176
177    TheISA::PCState
178    pcState() const
179    {
180        return thread.pcState();
181    }
182
183    void
184    pcState(const TheISA::PCState &val)
185    {
186        thread.pcState(val);
187    }
188
189    TheISA::MiscReg
190    readMiscRegNoEffect(int misc_reg)
191    {
192        return thread.readMiscRegNoEffect(misc_reg);
193    }
194
195    TheISA::MiscReg
196    readMiscReg(int misc_reg)
197    {
198        return thread.readMiscReg(misc_reg);
199    }
200
201    void
202    setMiscReg(int misc_reg, const TheISA::MiscReg &val)
203    {
204        thread.setMiscReg(misc_reg, val);
205    }
206
207    TheISA::MiscReg
208    readMiscRegOperand(const StaticInst *si, int idx)
209    {
210        int reg_idx = si->srcRegIdx(idx) - TheISA::Misc_Reg_Base;
211        return thread.readMiscReg(reg_idx);
212    }
213
214    void
215    setMiscRegOperand(const StaticInst *si, int idx,
216        const TheISA::MiscReg &val)
217    {
218        int reg_idx = si->destRegIdx(idx) - TheISA::Misc_Reg_Base;
219        return thread.setMiscReg(reg_idx, val);
220    }
221
222    Fault
223    hwrei()
224    {
225#if THE_ISA == ALPHA_ISA
226        return thread.hwrei();
227#else
228        return NoFault;
229#endif
230    }
231
232    bool
233    simPalCheck(int palFunc)
234    {
235#if THE_ISA == ALPHA_ISA
236        return thread.simPalCheck(palFunc);
237#else
238        return false;
239#endif
240    }
241
242    void
243    syscall(int64_t callnum)
244    {
245        if (FullSystem)
246            panic("Syscall emulation isn't available in FS mode.\n");
247
248        thread.syscall(callnum);
249    }
250
251    ThreadContext *tcBase() { return thread.getTC(); }
252
253    /* @todo, should make stCondFailures persistent somewhere */
254    unsigned int readStCondFailures() const { return 0; }
255    void setStCondFailures(unsigned int st_cond_failures) {}
256
257    int contextId() { return thread.contextId(); }
258    /* ISA-specific (or at least currently ISA singleton) functions */
259
260    /* X86: TLB twiddling */
261    void
262    demapPage(Addr vaddr, uint64_t asn)
263    {
264        thread.getITBPtr()->demapPage(vaddr, asn);
265        thread.getDTBPtr()->demapPage(vaddr, asn);
266    }
267
268    TheISA::CCReg
269    readCCRegOperand(const StaticInst *si, int idx)
270    {
271        int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base;
272        return thread.readCCReg(reg_idx);
273    }
274
275    void
276    setCCRegOperand(const StaticInst *si, int idx, TheISA::CCReg val)
277    {
278        int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base;
279        thread.setCCReg(reg_idx, val);
280    }
281
282    void
283    demapInstPage(Addr vaddr, uint64_t asn)
284    {
285        thread.getITBPtr()->demapPage(vaddr, asn);
286    }
287
288    void
289    demapDataPage(Addr vaddr, uint64_t asn)
290    {
291        thread.getDTBPtr()->demapPage(vaddr, asn);
292    }
293
294    /* ALPHA/POWER: Effective address storage */
295    void setEA(Addr ea)
296    {
297        inst->ea = ea;
298    }
299
300    BaseCPU *getCpuPtr() { return &cpu; }
301
302    /* POWER: Effective address storage */
303    Addr getEA() const
304    {
305        return inst->ea;
306    }
307
308    /* MIPS: other thread register reading/writing */
309    uint64_t
310    readRegOtherThread(int idx, ThreadID tid = InvalidThreadID)
311    {
312        SimpleThread *other_thread = (tid == InvalidThreadID
313            ? &thread : cpu.threads[tid]);
314
315        if (idx < TheISA::FP_Reg_Base) { /* Integer */
316            return other_thread->readIntReg(idx);
317        } else if (idx < TheISA::Misc_Reg_Base) { /* Float */
318            return other_thread->readFloatRegBits(idx
319                - TheISA::FP_Reg_Base);
320        } else { /* Misc */
321            return other_thread->readMiscReg(idx
322                - TheISA::Misc_Reg_Base);
323        }
324    }
325
326    void
327    setRegOtherThread(int idx, const TheISA::MiscReg &val,
328        ThreadID tid = InvalidThreadID)
329    {
330        SimpleThread *other_thread = (tid == InvalidThreadID
331            ? &thread : cpu.threads[tid]);
332
333        if (idx < TheISA::FP_Reg_Base) { /* Integer */
334            return other_thread->setIntReg(idx, val);
335        } else if (idx < TheISA::Misc_Reg_Base) { /* Float */
336            return other_thread->setFloatRegBits(idx
337                - TheISA::FP_Reg_Base, val);
338        } else { /* Misc */
339            return other_thread->setMiscReg(idx
340                - TheISA::Misc_Reg_Base, val);
341        }
342    }
343};
344
345}
346
347#endif /* __CPU_MINOR_EXEC_CONTEXT_HH__ */
348