184dd29101ba86f5b3872670e8988cb1c42fd008
[gem5.git] / src / cpu / minor / exec_context.hh
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
64 namespace Minor
65 {
66
67 /* Forward declaration of Execute */
68 class 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 */
74 class 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 return execute.getLSQ().pushRequest(inst, true /* load */, nullptr,
120 size, addr, flags, nullptr, nullptr, byteEnable);
121 }
122
123 Fault
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>())
127 override
128 {
129 assert(byteEnable.empty() || byteEnable.size() == size);
130 return execute.getLSQ().pushRequest(inst, false /* store */, data,
131 size, addr, flags, res, nullptr, byteEnable);
132 }
133
134 Fault
135 initiateMemAMO(Addr addr, unsigned int size, Request::Flags flags,
136 AtomicOpFunctorPtr amo_op) override
137 {
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));
141 }
142
143 RegVal
144 readIntRegOperand(const StaticInst *si, int idx) override
145 {
146 const RegId& reg = si->srcRegIdx(idx);
147 assert(reg.isIntReg());
148 return thread.readIntReg(reg.index());
149 }
150
151 RegVal
152 readFloatRegOperandBits(const StaticInst *si, int idx) override
153 {
154 const RegId& reg = si->srcRegIdx(idx);
155 assert(reg.isFloatReg());
156 return thread.readFloatReg(reg.index());
157 }
158
159 const TheISA::VecRegContainer &
160 readVecRegOperand(const StaticInst *si, int idx) const override
161 {
162 const RegId& reg = si->srcRegIdx(idx);
163 assert(reg.isVecReg());
164 return thread.readVecReg(reg);
165 }
166
167 TheISA::VecRegContainer &
168 getWritableVecRegOperand(const StaticInst *si, int idx) override
169 {
170 const RegId& reg = si->destRegIdx(idx);
171 assert(reg.isVecReg());
172 return thread.getWritableVecReg(reg);
173 }
174
175 TheISA::VecElem
176 readVecElemOperand(const StaticInst *si, int idx) const override
177 {
178 const RegId& reg = si->srcRegIdx(idx);
179 assert(reg.isVecElem());
180 return thread.readVecElem(reg);
181 }
182
183 const TheISA::VecPredRegContainer&
184 readVecPredRegOperand(const StaticInst *si, int idx) const override
185 {
186 const RegId& reg = si->srcRegIdx(idx);
187 assert(reg.isVecPredReg());
188 return thread.readVecPredReg(reg);
189 }
190
191 TheISA::VecPredRegContainer&
192 getWritableVecPredRegOperand(const StaticInst *si, int idx) override
193 {
194 const RegId& reg = si->destRegIdx(idx);
195 assert(reg.isVecPredReg());
196 return thread.getWritableVecPredReg(reg);
197 }
198
199 void
200 setIntRegOperand(const StaticInst *si, int idx, RegVal val) override
201 {
202 const RegId& reg = si->destRegIdx(idx);
203 assert(reg.isIntReg());
204 thread.setIntReg(reg.index(), val);
205 }
206
207 void
208 setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override
209 {
210 const RegId& reg = si->destRegIdx(idx);
211 assert(reg.isFloatReg());
212 thread.setFloatReg(reg.index(), val);
213 }
214
215 void
216 setVecRegOperand(const StaticInst *si, int idx,
217 const TheISA::VecRegContainer& val) override
218 {
219 const RegId& reg = si->destRegIdx(idx);
220 assert(reg.isVecReg());
221 thread.setVecReg(reg, val);
222 }
223
224 void
225 setVecPredRegOperand(const StaticInst *si, int idx,
226 const TheISA::VecPredRegContainer& val) override
227 {
228 const RegId& reg = si->destRegIdx(idx);
229 assert(reg.isVecPredReg());
230 thread.setVecPredReg(reg, val);
231 }
232
233 /** Vector Register Lane Interfaces. */
234 /** @{ */
235 /** Reads source vector 8bit operand. */
236 ConstVecLane8
237 readVec8BitLaneOperand(const StaticInst *si, int idx) const
238 override
239 {
240 const RegId& reg = si->srcRegIdx(idx);
241 assert(reg.isVecReg());
242 return thread.readVec8BitLaneReg(reg);
243 }
244
245 /** Reads source vector 16bit operand. */
246 ConstVecLane16
247 readVec16BitLaneOperand(const StaticInst *si, int idx) const
248 override
249 {
250 const RegId& reg = si->srcRegIdx(idx);
251 assert(reg.isVecReg());
252 return thread.readVec16BitLaneReg(reg);
253 }
254
255 /** Reads source vector 32bit operand. */
256 ConstVecLane32
257 readVec32BitLaneOperand(const StaticInst *si, int idx) const
258 override
259 {
260 const RegId& reg = si->srcRegIdx(idx);
261 assert(reg.isVecReg());
262 return thread.readVec32BitLaneReg(reg);
263 }
264
265 /** Reads source vector 64bit operand. */
266 ConstVecLane64
267 readVec64BitLaneOperand(const StaticInst *si, int idx) const
268 override
269 {
270 const RegId& reg = si->srcRegIdx(idx);
271 assert(reg.isVecReg());
272 return thread.readVec64BitLaneReg(reg);
273 }
274
275 /** Write a lane of the destination vector operand. */
276 template <typename LD>
277 void
278 setVecLaneOperandT(const StaticInst *si, int idx, const LD& val)
279 {
280 const RegId& reg = si->destRegIdx(idx);
281 assert(reg.isVecReg());
282 return thread.setVecLane(reg, val);
283 }
284 virtual void
285 setVecLaneOperand(const StaticInst *si, int idx,
286 const LaneData<LaneSize::Byte>& val) override
287 {
288 setVecLaneOperandT(si, idx, val);
289 }
290 virtual void
291 setVecLaneOperand(const StaticInst *si, int idx,
292 const LaneData<LaneSize::TwoByte>& val) override
293 {
294 setVecLaneOperandT(si, idx, val);
295 }
296 virtual void
297 setVecLaneOperand(const StaticInst *si, int idx,
298 const LaneData<LaneSize::FourByte>& val) override
299 {
300 setVecLaneOperandT(si, idx, val);
301 }
302 virtual void
303 setVecLaneOperand(const StaticInst *si, int idx,
304 const LaneData<LaneSize::EightByte>& val) override
305 {
306 setVecLaneOperandT(si, idx, val);
307 }
308 /** @} */
309
310 void
311 setVecElemOperand(const StaticInst *si, int idx,
312 const TheISA::VecElem val) override
313 {
314 const RegId& reg = si->destRegIdx(idx);
315 assert(reg.isVecElem());
316 thread.setVecElem(reg, val);
317 }
318
319 bool
320 readPredicate() const override
321 {
322 return thread.readPredicate();
323 }
324
325 void
326 setPredicate(bool val) override
327 {
328 thread.setPredicate(val);
329 }
330
331 bool
332 readMemAccPredicate() const override
333 {
334 return thread.readMemAccPredicate();
335 }
336
337 void
338 setMemAccPredicate(bool val) override
339 {
340 thread.setMemAccPredicate(val);
341 }
342
343 TheISA::PCState
344 pcState() const override
345 {
346 return thread.pcState();
347 }
348
349 void
350 pcState(const TheISA::PCState &val) override
351 {
352 thread.pcState(val);
353 }
354
355 RegVal
356 readMiscRegNoEffect(int misc_reg) const
357 {
358 return thread.readMiscRegNoEffect(misc_reg);
359 }
360
361 RegVal
362 readMiscReg(int misc_reg) override
363 {
364 return thread.readMiscReg(misc_reg);
365 }
366
367 void
368 setMiscReg(int misc_reg, RegVal val) override
369 {
370 thread.setMiscReg(misc_reg, val);
371 }
372
373 RegVal
374 readMiscRegOperand(const StaticInst *si, int idx) override
375 {
376 const RegId& reg = si->srcRegIdx(idx);
377 assert(reg.isMiscReg());
378 return thread.readMiscReg(reg.index());
379 }
380
381 void
382 setMiscRegOperand(const StaticInst *si, int idx, RegVal val) override
383 {
384 const RegId& reg = si->destRegIdx(idx);
385 assert(reg.isMiscReg());
386 return thread.setMiscReg(reg.index(), val);
387 }
388
389 void
390 syscall(Fault *fault) override
391 {
392 thread.syscall(fault);
393 }
394
395 ThreadContext *tcBase() override { return thread.getTC(); }
396
397 /* @todo, should make stCondFailures persistent somewhere */
398 unsigned int readStCondFailures() const override { return 0; }
399 void setStCondFailures(unsigned int st_cond_failures) override {}
400
401 ContextID contextId() { return thread.contextId(); }
402 /* ISA-specific (or at least currently ISA singleton) functions */
403
404 /* X86: TLB twiddling */
405 void
406 demapPage(Addr vaddr, uint64_t asn) override
407 {
408 thread.getITBPtr()->demapPage(vaddr, asn);
409 thread.getDTBPtr()->demapPage(vaddr, asn);
410 }
411
412 RegVal
413 readCCRegOperand(const StaticInst *si, int idx) override
414 {
415 const RegId& reg = si->srcRegIdx(idx);
416 assert(reg.isCCReg());
417 return thread.readCCReg(reg.index());
418 }
419
420 void
421 setCCRegOperand(const StaticInst *si, int idx, RegVal val) override
422 {
423 const RegId& reg = si->destRegIdx(idx);
424 assert(reg.isCCReg());
425 thread.setCCReg(reg.index(), val);
426 }
427
428 void
429 demapInstPage(Addr vaddr, uint64_t asn)
430 {
431 thread.getITBPtr()->demapPage(vaddr, asn);
432 }
433
434 void
435 demapDataPage(Addr vaddr, uint64_t asn)
436 {
437 thread.getDTBPtr()->demapPage(vaddr, asn);
438 }
439
440 BaseCPU *getCpuPtr() { return &cpu; }
441
442 public:
443 // monitor/mwait funtions
444 void armMonitor(Addr address) override
445 { getCpuPtr()->armMonitor(inst->id.threadId, address); }
446
447 bool mwait(PacketPtr pkt) override
448 { return getCpuPtr()->mwait(inst->id.threadId, pkt); }
449
450 void mwaitAtomic(ThreadContext *tc) override
451 { return getCpuPtr()->mwaitAtomic(inst->id.threadId, tc, thread.dtb); }
452
453 AddressMonitor *getAddrMonitor() override
454 { return getCpuPtr()->getCpuAddrMonitor(inst->id.threadId); }
455 };
456
457 }
458
459 #endif /* __CPU_MINOR_EXEC_CONTEXT_HH__ */