Deleted Added
sdiff udiff text old ( 13500:6e0a2a7c6d8c ) new ( 13557:fc33e6048b25 )
full compact
1/*
2 * Copyright (c) 2011-2014, 2016 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(true);
100 thread.setIntReg(TheISA::ZeroReg, 0);
101#if THE_ISA == ALPHA_ISA
102 thread.setFloatRegBits(TheISA::ZeroReg, 0);
103#endif
104 }
105
106 Fault
107 initiateMemRead(Addr addr, unsigned int size,
108 Request::Flags flags) override
109 {
110 execute.getLSQ().pushRequest(inst, true /* load */, nullptr,
111 size, addr, flags, NULL);
112 return NoFault;
113 }
114
115 Fault
116 writeMem(uint8_t *data, unsigned int size, Addr addr,
117 Request::Flags flags, uint64_t *res) override
118 {
119 execute.getLSQ().pushRequest(inst, false /* store */, data,
120 size, addr, flags, res);
121 return NoFault;
122 }
123
124 IntReg
125 readIntRegOperand(const StaticInst *si, int idx) override
126 {
127 const RegId& reg = si->srcRegIdx(idx);
128 assert(reg.isIntReg());
129 return thread.readIntReg(reg.index());
130 }
131
132 TheISA::FloatRegBits
133 readFloatRegOperandBits(const StaticInst *si, int idx) override
134 {
135 const RegId& reg = si->srcRegIdx(idx);
136 assert(reg.isFloatReg());
137 return thread.readFloatRegBits(reg.index());
138 }
139
140 const TheISA::VecRegContainer&
141 readVecRegOperand(const StaticInst *si, int idx) const override
142 {
143 const RegId& reg = si->srcRegIdx(idx);
144 assert(reg.isVecReg());
145 return thread.readVecReg(reg);
146 }
147
148 TheISA::VecRegContainer&
149 getWritableVecRegOperand(const StaticInst *si, int idx) override
150 {
151 const RegId& reg = si->destRegIdx(idx);
152 assert(reg.isVecReg());
153 return thread.getWritableVecReg(reg);
154 }
155
156 TheISA::VecElem
157 readVecElemOperand(const StaticInst *si, int idx) const override
158 {
159 const RegId& reg = si->srcRegIdx(idx);
160 assert(reg.isVecReg());
161 return thread.readVecElem(reg);
162 }
163
164 void
165 setIntRegOperand(const StaticInst *si, int idx, IntReg val) override
166 {
167 const RegId& reg = si->destRegIdx(idx);
168 assert(reg.isIntReg());
169 thread.setIntReg(reg.index(), val);
170 }
171
172 void
173 setFloatRegOperandBits(const StaticInst *si, int idx,
174 TheISA::FloatRegBits val) override
175 {
176 const RegId& reg = si->destRegIdx(idx);
177 assert(reg.isFloatReg());
178 thread.setFloatRegBits(reg.index(), val);
179 }
180
181 void
182 setVecRegOperand(const StaticInst *si, int idx,
183 const TheISA::VecRegContainer& val) override
184 {
185 const RegId& reg = si->destRegIdx(idx);
186 assert(reg.isVecReg());
187 thread.setVecReg(reg, val);
188 }
189
190 /** Vector Register Lane Interfaces. */
191 /** @{ */
192 /** Reads source vector 8bit operand. */
193 ConstVecLane8
194 readVec8BitLaneOperand(const StaticInst *si, int idx) const
195 override
196 {
197 const RegId& reg = si->srcRegIdx(idx);
198 assert(reg.isVecReg());
199 return thread.readVec8BitLaneReg(reg);
200 }
201
202 /** Reads source vector 16bit operand. */
203 ConstVecLane16
204 readVec16BitLaneOperand(const StaticInst *si, int idx) const
205 override
206 {
207 const RegId& reg = si->srcRegIdx(idx);
208 assert(reg.isVecReg());
209 return thread.readVec16BitLaneReg(reg);
210 }
211
212 /** Reads source vector 32bit operand. */
213 ConstVecLane32
214 readVec32BitLaneOperand(const StaticInst *si, int idx) const
215 override
216 {
217 const RegId& reg = si->srcRegIdx(idx);
218 assert(reg.isVecReg());
219 return thread.readVec32BitLaneReg(reg);
220 }
221
222 /** Reads source vector 64bit operand. */
223 ConstVecLane64
224 readVec64BitLaneOperand(const StaticInst *si, int idx) const
225 override
226 {
227 const RegId& reg = si->srcRegIdx(idx);
228 assert(reg.isVecReg());
229 return thread.readVec64BitLaneReg(reg);
230 }
231
232 /** Write a lane of the destination vector operand. */
233 template <typename LD>
234 void
235 setVecLaneOperandT(const StaticInst *si, int idx,
236 const LD& val)
237 {
238 const RegId& reg = si->destRegIdx(idx);
239 assert(reg.isVecReg());
240 return thread.setVecLane(reg, val);
241 }
242 virtual void
243 setVecLaneOperand(const StaticInst *si, int idx,
244 const LaneData<LaneSize::Byte>& val) override
245 {
246 setVecLaneOperandT(si, idx, val);
247 }
248 virtual void
249 setVecLaneOperand(const StaticInst *si, int idx,
250 const LaneData<LaneSize::TwoByte>& val) override
251 {
252 setVecLaneOperandT(si, idx, val);
253 }
254 virtual void
255 setVecLaneOperand(const StaticInst *si, int idx,
256 const LaneData<LaneSize::FourByte>& val) override
257 {
258 setVecLaneOperandT(si, idx, val);
259 }
260 virtual void
261 setVecLaneOperand(const StaticInst *si, int idx,
262 const LaneData<LaneSize::EightByte>& val) override
263 {
264 setVecLaneOperandT(si, idx, val);
265 }
266 /** @} */
267
268 void
269 setVecElemOperand(const StaticInst *si, int idx,
270 const TheISA::VecElem val) override
271 {
272 const RegId& reg = si->destRegIdx(idx);
273 assert(reg.isVecReg());
274 thread.setVecElem(reg, val);
275 }
276
277 bool
278 readPredicate() const override
279 {
280 return thread.readPredicate();
281 }
282
283 void
284 setPredicate(bool val) override
285 {
286 thread.setPredicate(val);
287 }
288
289 TheISA::PCState
290 pcState() const override
291 {
292 return thread.pcState();
293 }
294
295 void
296 pcState(const TheISA::PCState &val) override
297 {
298 thread.pcState(val);
299 }
300
301 TheISA::MiscReg
302 readMiscRegNoEffect(int misc_reg) const
303 {
304 return thread.readMiscRegNoEffect(misc_reg);
305 }
306
307 TheISA::MiscReg
308 readMiscReg(int misc_reg) override
309 {
310 return thread.readMiscReg(misc_reg);
311 }
312
313 void
314 setMiscReg(int misc_reg, const TheISA::MiscReg &val) override
315 {
316 thread.setMiscReg(misc_reg, val);
317 }
318
319 TheISA::MiscReg
320 readMiscRegOperand(const StaticInst *si, int idx) override
321 {
322 const RegId& reg = si->srcRegIdx(idx);
323 assert(reg.isMiscReg());
324 return thread.readMiscReg(reg.index());
325 }
326
327 void
328 setMiscRegOperand(const StaticInst *si, int idx,
329 const TheISA::MiscReg &val) override
330 {
331 const RegId& reg = si->destRegIdx(idx);
332 assert(reg.isMiscReg());
333 return thread.setMiscReg(reg.index(), val);
334 }
335
336 Fault
337 hwrei() override
338 {
339#if THE_ISA == ALPHA_ISA
340 return thread.hwrei();
341#else
342 return NoFault;
343#endif
344 }
345
346 bool
347 simPalCheck(int palFunc) override
348 {
349#if THE_ISA == ALPHA_ISA
350 return thread.simPalCheck(palFunc);
351#else
352 return false;
353#endif
354 }
355
356 void
357 syscall(int64_t callnum, Fault *fault) override
358 {
359 if (FullSystem)
360 panic("Syscall emulation isn't available in FS mode.\n");
361
362 thread.syscall(callnum, fault);
363 }
364
365 ThreadContext *tcBase() override { return thread.getTC(); }
366
367 /* @todo, should make stCondFailures persistent somewhere */
368 unsigned int readStCondFailures() const override { return 0; }
369 void setStCondFailures(unsigned int st_cond_failures) override {}
370
371 ContextID contextId() { return thread.contextId(); }
372 /* ISA-specific (or at least currently ISA singleton) functions */
373
374 /* X86: TLB twiddling */
375 void
376 demapPage(Addr vaddr, uint64_t asn) override
377 {
378 thread.getITBPtr()->demapPage(vaddr, asn);
379 thread.getDTBPtr()->demapPage(vaddr, asn);
380 }
381
382 TheISA::CCReg
383 readCCRegOperand(const StaticInst *si, int idx) override
384 {
385 const RegId& reg = si->srcRegIdx(idx);
386 assert(reg.isCCReg());
387 return thread.readCCReg(reg.index());
388 }
389
390 void
391 setCCRegOperand(const StaticInst *si, int idx, TheISA::CCReg val) override
392 {
393 const RegId& reg = si->destRegIdx(idx);
394 assert(reg.isCCReg());
395 thread.setCCReg(reg.index(), val);
396 }
397
398 void
399 demapInstPage(Addr vaddr, uint64_t asn)
400 {
401 thread.getITBPtr()->demapPage(vaddr, asn);
402 }
403
404 void
405 demapDataPage(Addr vaddr, uint64_t asn)
406 {
407 thread.getDTBPtr()->demapPage(vaddr, asn);
408 }
409
410 BaseCPU *getCpuPtr() { return &cpu; }
411
412 /* MIPS: other thread register reading/writing */
413 uint64_t
414 readRegOtherThread(const RegId& reg, ThreadID tid = InvalidThreadID)
415 {
416 SimpleThread *other_thread = (tid == InvalidThreadID
417 ? &thread : cpu.threads[tid]);
418
419 switch (reg.classValue()) {
420 case IntRegClass:
421 return other_thread->readIntReg(reg.index());
422 break;
423 case FloatRegClass:
424 return other_thread->readFloatRegBits(reg.index());
425 break;
426 case MiscRegClass:
427 return other_thread->readMiscReg(reg.index());
428 default:
429 panic("Unexpected reg class! (%s)",
430 reg.className());
431 return 0;
432 }
433 }
434
435 void
436 setRegOtherThread(const RegId& reg, const TheISA::MiscReg &val,
437 ThreadID tid = InvalidThreadID)
438 {
439 SimpleThread *other_thread = (tid == InvalidThreadID
440 ? &thread : cpu.threads[tid]);
441
442 switch (reg.classValue()) {
443 case IntRegClass:
444 return other_thread->setIntReg(reg.index(), val);
445 break;
446 case FloatRegClass:
447 return other_thread->setFloatRegBits(reg.index(), val);
448 break;
449 case MiscRegClass:
450 return other_thread->setMiscReg(reg.index(), val);
451 default:
452 panic("Unexpected reg class! (%s)",
453 reg.className());
454 }
455 }
456
457 public:
458 // monitor/mwait funtions
459 void armMonitor(Addr address) override
460 { getCpuPtr()->armMonitor(inst->id.threadId, address); }
461
462 bool mwait(PacketPtr pkt) override
463 { return getCpuPtr()->mwait(inst->id.threadId, pkt); }
464
465 void mwaitAtomic(ThreadContext *tc) override
466 { return getCpuPtr()->mwaitAtomic(inst->id.threadId, tc, thread.dtb); }
467
468 AddressMonitor *getAddrMonitor() override
469 { return getCpuPtr()->getCpuAddrMonitor(inst->id.threadId); }
470};
471
472}
473
474#endif /* __CPU_MINOR_EXEC_CONTEXT_HH__ */