2 * Copyright (c) 2011-2014, 2016-2018 ARM Limited
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
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.
15 * Copyright (c) 2002-2005 The Regents of The University of Michigan
16 * All rights reserved.
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.
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.
41 * Authors: Steve Reinhardt
50 * ExecContext bears the exec_context interface for Minor.
53 #ifndef __CPU_MINOR_EXEC_CONTEXT_HH__
54 #define __CPU_MINOR_EXEC_CONTEXT_HH__
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"
67 /* Forward declaration of Execute */
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.
74 class ExecContext : public ::ExecContext
79 /** ThreadState object, provides all the architectural state. */
82 /** The execute stage so we can peek at its contents. */
85 /** Instruction for the benefit of memory operations and for PC */
90 SimpleThread &thread_, Execute &execute_,
91 MinorDynInstPtr inst_) :
97 DPRINTF(MinorExecute, "ExecContext setting PC: %s\n", 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);
109 inst->setPredicate(readPredicate());
110 inst->setMemAccPredicate(readMemAccPredicate());
114 initiateMemRead(Addr addr, unsigned int size,
115 Request::Flags flags,
116 const std::vector<bool>& byteEnable = std::vector<bool>())
119 return execute.getLSQ().pushRequest(inst, true /* load */, nullptr,
120 size, addr, flags, nullptr, nullptr, byteEnable);
124 writeMem(uint8_t *data, unsigned int size, Addr addr,
125 Request::Flags flags, uint64_t *res,
126 const std::vector<bool>& byteEnable = std::vector<bool>())
129 assert(byteEnable.empty() || byteEnable.size() == size);
130 return execute.getLSQ().pushRequest(inst, false /* store */, data,
131 size, addr, flags, res, nullptr, byteEnable);
135 initiateMemAMO(Addr addr, unsigned int size, Request::Flags flags,
136 AtomicOpFunctorPtr amo_op) override
138 // AMO requests are pushed through the store path
139 return execute.getLSQ().pushRequest(inst, false /* amo */, nullptr,
140 size, addr, flags, nullptr, std::move(amo_op));
144 readIntRegOperand(const StaticInst *si, int idx) override
146 const RegId& reg = si->srcRegIdx(idx);
147 assert(reg.isIntReg());
148 return thread.readIntReg(reg.index());
152 readFloatRegOperandBits(const StaticInst *si, int idx) override
154 const RegId& reg = si->srcRegIdx(idx);
155 assert(reg.isFloatReg());
156 return thread.readFloatReg(reg.index());
159 const TheISA::VecRegContainer &
160 readVecRegOperand(const StaticInst *si, int idx) const override
162 const RegId& reg = si->srcRegIdx(idx);
163 assert(reg.isVecReg());
164 return thread.readVecReg(reg);
167 TheISA::VecRegContainer &
168 getWritableVecRegOperand(const StaticInst *si, int idx) override
170 const RegId& reg = si->destRegIdx(idx);
171 assert(reg.isVecReg());
172 return thread.getWritableVecReg(reg);
176 readVecElemOperand(const StaticInst *si, int idx) const override
178 const RegId& reg = si->srcRegIdx(idx);
179 assert(reg.isVecElem());
180 return thread.readVecElem(reg);
183 const TheISA::VecPredRegContainer&
184 readVecPredRegOperand(const StaticInst *si, int idx) const override
186 const RegId& reg = si->srcRegIdx(idx);
187 assert(reg.isVecPredReg());
188 return thread.readVecPredReg(reg);
191 TheISA::VecPredRegContainer&
192 getWritableVecPredRegOperand(const StaticInst *si, int idx) override
194 const RegId& reg = si->destRegIdx(idx);
195 assert(reg.isVecPredReg());
196 return thread.getWritableVecPredReg(reg);
200 setIntRegOperand(const StaticInst *si, int idx, RegVal val) override
202 const RegId& reg = si->destRegIdx(idx);
203 assert(reg.isIntReg());
204 thread.setIntReg(reg.index(), val);
208 setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override
210 const RegId& reg = si->destRegIdx(idx);
211 assert(reg.isFloatReg());
212 thread.setFloatReg(reg.index(), val);
216 setVecRegOperand(const StaticInst *si, int idx,
217 const TheISA::VecRegContainer& val) override
219 const RegId& reg = si->destRegIdx(idx);
220 assert(reg.isVecReg());
221 thread.setVecReg(reg, val);
225 setVecPredRegOperand(const StaticInst *si, int idx,
226 const TheISA::VecPredRegContainer& val) override
228 const RegId& reg = si->destRegIdx(idx);
229 assert(reg.isVecPredReg());
230 thread.setVecPredReg(reg, val);
233 /** Vector Register Lane Interfaces. */
235 /** Reads source vector 8bit operand. */
237 readVec8BitLaneOperand(const StaticInst *si, int idx) const
240 const RegId& reg = si->srcRegIdx(idx);
241 assert(reg.isVecReg());
242 return thread.readVec8BitLaneReg(reg);
245 /** Reads source vector 16bit operand. */
247 readVec16BitLaneOperand(const StaticInst *si, int idx) const
250 const RegId& reg = si->srcRegIdx(idx);
251 assert(reg.isVecReg());
252 return thread.readVec16BitLaneReg(reg);
255 /** Reads source vector 32bit operand. */
257 readVec32BitLaneOperand(const StaticInst *si, int idx) const
260 const RegId& reg = si->srcRegIdx(idx);
261 assert(reg.isVecReg());
262 return thread.readVec32BitLaneReg(reg);
265 /** Reads source vector 64bit operand. */
267 readVec64BitLaneOperand(const StaticInst *si, int idx) const
270 const RegId& reg = si->srcRegIdx(idx);
271 assert(reg.isVecReg());
272 return thread.readVec64BitLaneReg(reg);
275 /** Write a lane of the destination vector operand. */
276 template <typename LD>
278 setVecLaneOperandT(const StaticInst *si, int idx, const LD& val)
280 const RegId& reg = si->destRegIdx(idx);
281 assert(reg.isVecReg());
282 return thread.setVecLane(reg, val);
285 setVecLaneOperand(const StaticInst *si, int idx,
286 const LaneData<LaneSize::Byte>& val) override
288 setVecLaneOperandT(si, idx, val);
291 setVecLaneOperand(const StaticInst *si, int idx,
292 const LaneData<LaneSize::TwoByte>& val) override
294 setVecLaneOperandT(si, idx, val);
297 setVecLaneOperand(const StaticInst *si, int idx,
298 const LaneData<LaneSize::FourByte>& val) override
300 setVecLaneOperandT(si, idx, val);
303 setVecLaneOperand(const StaticInst *si, int idx,
304 const LaneData<LaneSize::EightByte>& val) override
306 setVecLaneOperandT(si, idx, val);
311 setVecElemOperand(const StaticInst *si, int idx,
312 const TheISA::VecElem val) override
314 const RegId& reg = si->destRegIdx(idx);
315 assert(reg.isVecElem());
316 thread.setVecElem(reg, val);
320 readPredicate() const override
322 return thread.readPredicate();
326 setPredicate(bool val) override
328 thread.setPredicate(val);
332 readMemAccPredicate() const override
334 return thread.readMemAccPredicate();
338 setMemAccPredicate(bool val) override
340 thread.setMemAccPredicate(val);
344 pcState() const override
346 return thread.pcState();
350 pcState(const TheISA::PCState &val) override
356 readMiscRegNoEffect(int misc_reg) const
358 return thread.readMiscRegNoEffect(misc_reg);
362 readMiscReg(int misc_reg) override
364 return thread.readMiscReg(misc_reg);
368 setMiscReg(int misc_reg, RegVal val) override
370 thread.setMiscReg(misc_reg, val);
374 readMiscRegOperand(const StaticInst *si, int idx) override
376 const RegId& reg = si->srcRegIdx(idx);
377 assert(reg.isMiscReg());
378 return thread.readMiscReg(reg.index());
382 setMiscRegOperand(const StaticInst *si, int idx, RegVal val) override
384 const RegId& reg = si->destRegIdx(idx);
385 assert(reg.isMiscReg());
386 return thread.setMiscReg(reg.index(), val);
390 syscall(Fault *fault) override
392 thread.syscall(fault);
395 ThreadContext *tcBase() override { return thread.getTC(); }
397 /* @todo, should make stCondFailures persistent somewhere */
398 unsigned int readStCondFailures() const override { return 0; }
399 void setStCondFailures(unsigned int st_cond_failures) override {}
401 ContextID contextId() { return thread.contextId(); }
402 /* ISA-specific (or at least currently ISA singleton) functions */
404 /* X86: TLB twiddling */
406 demapPage(Addr vaddr, uint64_t asn) override
408 thread.getITBPtr()->demapPage(vaddr, asn);
409 thread.getDTBPtr()->demapPage(vaddr, asn);
413 readCCRegOperand(const StaticInst *si, int idx) override
415 const RegId& reg = si->srcRegIdx(idx);
416 assert(reg.isCCReg());
417 return thread.readCCReg(reg.index());
421 setCCRegOperand(const StaticInst *si, int idx, RegVal val) override
423 const RegId& reg = si->destRegIdx(idx);
424 assert(reg.isCCReg());
425 thread.setCCReg(reg.index(), val);
429 demapInstPage(Addr vaddr, uint64_t asn)
431 thread.getITBPtr()->demapPage(vaddr, asn);
435 demapDataPage(Addr vaddr, uint64_t asn)
437 thread.getDTBPtr()->demapPage(vaddr, asn);
440 BaseCPU *getCpuPtr() { return &cpu; }
443 // monitor/mwait funtions
444 void armMonitor(Addr address) override
445 { getCpuPtr()->armMonitor(inst->id.threadId, address); }
447 bool mwait(PacketPtr pkt) override
448 { return getCpuPtr()->mwait(inst->id.threadId, pkt); }
450 void mwaitAtomic(ThreadContext *tc) override
451 { return getCpuPtr()->mwaitAtomic(inst->id.threadId, tc, thread.dtb); }
453 AddressMonitor *getAddrMonitor() override
454 { return getCpuPtr()->getCpuAddrMonitor(inst->id.threadId); }
459 #endif /* __CPU_MINOR_EXEC_CONTEXT_HH__ */