diff options
Diffstat (limited to 'src/cpu/minor/exec_context.hh')
-rw-r--r-- | src/cpu/minor/exec_context.hh | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/src/cpu/minor/exec_context.hh b/src/cpu/minor/exec_context.hh new file mode 100644 index 000000000..df909a95c --- /dev/null +++ b/src/cpu/minor/exec_context.hh @@ -0,0 +1,350 @@ +/* + * Copyright (c) 2011-2014 ARM Limited + * Copyright (c) 2013 Advanced Micro Devices, Inc. + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Steve Reinhardt + * Dave Greene + * Nathan Binkert + * Andrew Bardsley + */ + +/** + * @file + * + * ExecContext bears the exec_context interface for Minor. + */ + +#ifndef __CPU_MINOR_EXEC_CONTEXT_HH__ +#define __CPU_MINOR_EXEC_CONTEXT_HH__ + +#include "cpu/minor/execute.hh" +#include "cpu/minor/pipeline.hh" +#include "cpu/base.hh" +#include "cpu/simple_thread.hh" +#include "debug/MinorExecute.hh" + +namespace Minor +{ + +/* Forward declaration of Execute */ +class Execute; + +/** ExecContext bears the exec_context interface for Minor. This nicely + * separates that interface from other classes such as Pipeline, MinorCPU + * and DynMinorInst and makes it easier to see what state is accessed by it. + */ +class ExecContext +{ + public: + MinorCPU &cpu; + + /** ThreadState object, provides all the architectural state. */ + SimpleThread &thread; + + /** The execute stage so we can peek at its contents. */ + Execute &execute; + + /** Instruction for the benefit of memory operations and for PC */ + MinorDynInstPtr inst; + + ExecContext ( + MinorCPU &cpu_, + SimpleThread &thread_, Execute &execute_, + MinorDynInstPtr inst_) : + cpu(cpu_), + thread(thread_), + execute(execute_), + inst(inst_) + { + DPRINTF(MinorExecute, "ExecContext setting PC: %s\n", inst->pc); + pcState(inst->pc); + setPredicate(true); + thread.setIntReg(TheISA::ZeroReg, 0); +#if THE_ISA == ALPHA_ISA + thread.setFloatReg(TheISA::ZeroReg, 0.0); +#endif + } + + Fault + readMem(Addr addr, uint8_t *data, unsigned int size, + unsigned int flags) + { + execute.getLSQ().pushRequest(inst, true /* load */, data, + size, addr, flags, NULL); + return NoFault; + } + + Fault + writeMem(uint8_t *data, unsigned int size, Addr addr, + unsigned int flags, uint64_t *res) + { + execute.getLSQ().pushRequest(inst, false /* store */, data, + size, addr, flags, res); + return NoFault; + } + + uint64_t + readIntRegOperand(const StaticInst *si, int idx) + { + return thread.readIntReg(si->srcRegIdx(idx)); + } + + TheISA::FloatReg + readFloatRegOperand(const StaticInst *si, int idx) + { + int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base; + return thread.readFloatReg(reg_idx); + } + + TheISA::FloatRegBits + readFloatRegOperandBits(const StaticInst *si, int idx) + { + int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base; + return thread.readFloatRegBits(reg_idx); + } + + void + setIntRegOperand(const StaticInst *si, int idx, uint64_t val) + { + thread.setIntReg(si->destRegIdx(idx), val); + } + + void + setFloatRegOperand(const StaticInst *si, int idx, + TheISA::FloatReg val) + { + int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base; + thread.setFloatReg(reg_idx, val); + } + + void + setFloatRegOperandBits(const StaticInst *si, int idx, + TheISA::FloatRegBits val) + { + int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base; + thread.setFloatRegBits(reg_idx, val); + } + + bool + readPredicate() + { + return thread.readPredicate(); + } + + void + setPredicate(bool val) + { + thread.setPredicate(val); + } + + TheISA::PCState + pcState() + { + return thread.pcState(); + } + + void + pcState(const TheISA::PCState &val) + { + thread.pcState(val); + } + + TheISA::MiscReg + readMiscRegNoEffect(int misc_reg) + { + return thread.readMiscRegNoEffect(misc_reg); + } + + TheISA::MiscReg + readMiscReg(int misc_reg) + { + return thread.readMiscReg(misc_reg); + } + + void + setMiscReg(int misc_reg, const TheISA::MiscReg &val) + { + thread.setMiscReg(misc_reg, val); + } + + TheISA::MiscReg + readMiscRegOperand(const StaticInst *si, int idx) + { + int reg_idx = si->srcRegIdx(idx) - TheISA::Misc_Reg_Base; + return thread.readMiscReg(reg_idx); + } + + void + setMiscRegOperand(const StaticInst *si, int idx, + const TheISA::MiscReg &val) + { + int reg_idx = si->destRegIdx(idx) - TheISA::Misc_Reg_Base; + return thread.setMiscReg(reg_idx, val); + } + + Fault + hwrei() + { +#if THE_ISA == ALPHA_ISA + return thread.hwrei(); +#else + return NoFault; +#endif + } + + bool + simPalCheck(int palFunc) + { +#if THE_ISA == ALPHA_ISA + return thread.simPalCheck(palFunc); +#else + return false; +#endif + } + + void + syscall(int64_t callnum) + { + if (FullSystem) + panic("Syscall emulation isn't available in FS mode.\n"); + + thread.syscall(callnum); + } + + ThreadContext *tcBase() { return thread.getTC(); } + + /* @todo, should make stCondFailures persistent somewhere */ + unsigned int readStCondFailures() { return 0; } + unsigned int + setStCondFailures(unsigned int st_cond_failures) + { + return 0; + } + + int contextId() { return thread.contextId(); } + /* ISA-specific (or at least currently ISA singleton) functions */ + + /* X86: TLB twiddling */ + void + demapPage(Addr vaddr, uint64_t asn) + { + thread.getITBPtr()->demapPage(vaddr, asn); + thread.getDTBPtr()->demapPage(vaddr, asn); + } + + TheISA::CCReg + readCCRegOperand(const StaticInst *si, int idx) + { + int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base; + return thread.readCCReg(reg_idx); + } + + void + setCCRegOperand(const StaticInst *si, int idx, TheISA::CCReg val) + { + int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base; + thread.setCCReg(reg_idx, val); + } + + void + demapInstPage(Addr vaddr, uint64_t asn) + { + thread.getITBPtr()->demapPage(vaddr, asn); + } + + void + demapDataPage(Addr vaddr, uint64_t asn) + { + thread.getDTBPtr()->demapPage(vaddr, asn); + } + + /* ALPHA/POWER: Effective address storage */ + void setEA(Addr &ea) + { + inst->ea = ea; + } + + BaseCPU *getCpuPtr() { return &cpu; } + + /* POWER: Effective address storage */ + Addr getEA() + { + return inst->ea; + } + + /* MIPS: other thread register reading/writing */ + uint64_t + readRegOtherThread(unsigned idx, ThreadID tid = InvalidThreadID) + { + SimpleThread *other_thread = (tid == InvalidThreadID + ? &thread : cpu.threads[tid]); + + if (idx < TheISA::FP_Reg_Base) { /* Integer */ + return other_thread->readIntReg(idx); + } else if (idx < TheISA::Misc_Reg_Base) { /* Float */ + return other_thread->readFloatRegBits(idx + - TheISA::FP_Reg_Base); + } else { /* Misc */ + return other_thread->readMiscReg(idx + - TheISA::Misc_Reg_Base); + } + } + + void + setRegOtherThread(unsigned idx, const TheISA::MiscReg &val, + ThreadID tid = InvalidThreadID) + { + SimpleThread *other_thread = (tid == InvalidThreadID + ? &thread : cpu.threads[tid]); + + if (idx < TheISA::FP_Reg_Base) { /* Integer */ + return other_thread->setIntReg(idx, val); + } else if (idx < TheISA::Misc_Reg_Base) { /* Float */ + return other_thread->setFloatRegBits(idx + - TheISA::FP_Reg_Base, val); + } else { /* Misc */ + return other_thread->setMiscReg(idx + - TheISA::Misc_Reg_Base, val); + } + } +}; + +} + +#endif /* __CPU_MINOR_EXEC_CONTEXT_HH__ */ |