exec_context.hh (13953:43ae8a30ec1f) exec_context.hh (13954:2f400a5f2627)
1/*
2 * Copyright (c) 2014-2018 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2002-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Kevin Lim
41 * Andreas Sandberg
42 * Mitch Hayenga
43 */
44
45#ifndef __CPU_SIMPLE_EXEC_CONTEXT_HH__
46#define __CPU_SIMPLE_EXEC_CONTEXT_HH__
47
48#include "arch/registers.hh"
49#include "base/types.hh"
50#include "config/the_isa.hh"
51#include "cpu/base.hh"
52#include "cpu/exec_context.hh"
53#include "cpu/reg_class.hh"
54#include "cpu/simple/base.hh"
55#include "cpu/static_inst_fwd.hh"
56#include "cpu/translation.hh"
57#include "mem/request.hh"
58
59class BaseSimpleCPU;
60
61class SimpleExecContext : public ExecContext {
62 protected:
63 using VecRegContainer = TheISA::VecRegContainer;
64 using VecElem = TheISA::VecElem;
65
66 public:
67 BaseSimpleCPU *cpu;
68 SimpleThread* thread;
69
70 // This is the offset from the current pc that fetch should be performed
71 Addr fetchOffset;
72 // This flag says to stay at the current pc. This is useful for
73 // instructions which go beyond MachInst boundaries.
74 bool stayAtPC;
75
76 // Branch prediction
77 TheISA::PCState predPC;
78
79 /** PER-THREAD STATS */
80
81 // Number of simulated instructions
82 Counter numInst;
83 Stats::Scalar numInsts;
84 Counter numOp;
85 Stats::Scalar numOps;
86
87 // Number of integer alu accesses
88 Stats::Scalar numIntAluAccesses;
89
90 // Number of float alu accesses
91 Stats::Scalar numFpAluAccesses;
92
93 // Number of vector alu accesses
94 Stats::Scalar numVecAluAccesses;
95
96 // Number of function calls/returns
97 Stats::Scalar numCallsReturns;
98
99 // Conditional control instructions;
100 Stats::Scalar numCondCtrlInsts;
101
102 // Number of int instructions
103 Stats::Scalar numIntInsts;
104
105 // Number of float instructions
106 Stats::Scalar numFpInsts;
107
108 // Number of vector instructions
109 Stats::Scalar numVecInsts;
110
111 // Number of integer register file accesses
112 Stats::Scalar numIntRegReads;
113 Stats::Scalar numIntRegWrites;
114
115 // Number of float register file accesses
116 Stats::Scalar numFpRegReads;
117 Stats::Scalar numFpRegWrites;
118
119 // Number of vector register file accesses
120 mutable Stats::Scalar numVecRegReads;
121 Stats::Scalar numVecRegWrites;
122
123 // Number of predicate register file accesses
124 mutable Stats::Scalar numVecPredRegReads;
125 Stats::Scalar numVecPredRegWrites;
126
127 // Number of condition code register file accesses
128 Stats::Scalar numCCRegReads;
129 Stats::Scalar numCCRegWrites;
130
131 // Number of simulated memory references
132 Stats::Scalar numMemRefs;
133 Stats::Scalar numLoadInsts;
134 Stats::Scalar numStoreInsts;
135
136 // Number of idle cycles
137 Stats::Formula numIdleCycles;
138
139 // Number of busy cycles
140 Stats::Formula numBusyCycles;
141
142 // Number of simulated loads
143 Counter numLoad;
144
145 // Number of idle cycles
146 Stats::Average notIdleFraction;
147 Stats::Formula idleFraction;
148
149 // Number of cycles stalled for I-cache responses
150 Stats::Scalar icacheStallCycles;
151 Counter lastIcacheStall;
152
153 // Number of cycles stalled for D-cache responses
154 Stats::Scalar dcacheStallCycles;
155 Counter lastDcacheStall;
156
157 /// @{
158 /// Total number of branches fetched
159 Stats::Scalar numBranches;
160 /// Number of branches predicted as taken
161 Stats::Scalar numPredictedBranches;
162 /// Number of misprediced branches
163 Stats::Scalar numBranchMispred;
164 /// @}
165
166 // Instruction mix histogram by OpClass
167 Stats::Vector statExecutedInstType;
168
169 public:
170 /** Constructor */
171 SimpleExecContext(BaseSimpleCPU* _cpu, SimpleThread* _thread)
172 : cpu(_cpu), thread(_thread), fetchOffset(0), stayAtPC(false),
173 numInst(0), numOp(0), numLoad(0), lastIcacheStall(0), lastDcacheStall(0)
174 { }
175
176 /** Reads an integer register. */
177 RegVal
178 readIntRegOperand(const StaticInst *si, int idx) override
179 {
180 numIntRegReads++;
181 const RegId& reg = si->srcRegIdx(idx);
182 assert(reg.isIntReg());
183 return thread->readIntReg(reg.index());
184 }
185
186 /** Sets an integer register to a value. */
187 void
188 setIntRegOperand(const StaticInst *si, int idx, RegVal val) override
189 {
190 numIntRegWrites++;
191 const RegId& reg = si->destRegIdx(idx);
192 assert(reg.isIntReg());
193 thread->setIntReg(reg.index(), val);
194 }
195
196 /** Reads a floating point register in its binary format, instead
197 * of by value. */
198 RegVal
199 readFloatRegOperandBits(const StaticInst *si, int idx) override
200 {
201 numFpRegReads++;
202 const RegId& reg = si->srcRegIdx(idx);
203 assert(reg.isFloatReg());
204 return thread->readFloatReg(reg.index());
205 }
206
207 /** Sets the bits of a floating point register of single width
208 * to a binary value. */
209 void
210 setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override
211 {
212 numFpRegWrites++;
213 const RegId& reg = si->destRegIdx(idx);
214 assert(reg.isFloatReg());
215 thread->setFloatReg(reg.index(), val);
216 }
217
218 /** Reads a vector register. */
219 const VecRegContainer &
220 readVecRegOperand(const StaticInst *si, int idx) const override
221 {
222 numVecRegReads++;
223 const RegId& reg = si->srcRegIdx(idx);
224 assert(reg.isVecReg());
225 return thread->readVecReg(reg);
226 }
227
228 /** Reads a vector register for modification. */
229 VecRegContainer &
230 getWritableVecRegOperand(const StaticInst *si, int idx) override
231 {
232 numVecRegWrites++;
233 const RegId& reg = si->destRegIdx(idx);
234 assert(reg.isVecReg());
235 return thread->getWritableVecReg(reg);
236 }
237
238 /** Sets a vector register to a value. */
239 void
240 setVecRegOperand(const StaticInst *si, int idx,
241 const VecRegContainer& val) override
242 {
243 numVecRegWrites++;
244 const RegId& reg = si->destRegIdx(idx);
245 assert(reg.isVecReg());
246 thread->setVecReg(reg, val);
247 }
248
249 /** Vector Register Lane Interfaces. */
250 /** @{ */
251 /** Reads source vector lane. */
252 template <typename VecElem>
253 VecLaneT<VecElem, true>
254 readVecLaneOperand(const StaticInst *si, int idx) const
255 {
256 numVecRegReads++;
257 const RegId& reg = si->srcRegIdx(idx);
258 assert(reg.isVecReg());
259 return thread->readVecLane<VecElem>(reg);
260 }
261 /** Reads source vector 8bit operand. */
262 virtual ConstVecLane8
263 readVec8BitLaneOperand(const StaticInst *si, int idx) const
264 override
265 { return readVecLaneOperand<uint8_t>(si, idx); }
266
267 /** Reads source vector 16bit operand. */
268 virtual ConstVecLane16
269 readVec16BitLaneOperand(const StaticInst *si, int idx) const
270 override
271 { return readVecLaneOperand<uint16_t>(si, idx); }
272
273 /** Reads source vector 32bit operand. */
274 virtual ConstVecLane32
275 readVec32BitLaneOperand(const StaticInst *si, int idx) const
276 override
277 { return readVecLaneOperand<uint32_t>(si, idx); }
278
279 /** Reads source vector 64bit operand. */
280 virtual ConstVecLane64
281 readVec64BitLaneOperand(const StaticInst *si, int idx) const
282 override
283 { return readVecLaneOperand<uint64_t>(si, idx); }
284
285 /** Write a lane of the destination vector operand. */
286 template <typename LD>
287 void
288 setVecLaneOperandT(const StaticInst *si, int idx,
289 const LD& val)
290 {
291 numVecRegWrites++;
292 const RegId& reg = si->destRegIdx(idx);
293 assert(reg.isVecReg());
294 return thread->setVecLane(reg, val);
295 }
296 /** Write a lane of the destination vector operand. */
297 virtual void
298 setVecLaneOperand(const StaticInst *si, int idx,
299 const LaneData<LaneSize::Byte>& val) override
300 { return setVecLaneOperandT(si, idx, val); }
301 /** Write a lane of the destination vector operand. */
302 virtual void
303 setVecLaneOperand(const StaticInst *si, int idx,
304 const LaneData<LaneSize::TwoByte>& val) override
305 { return setVecLaneOperandT(si, idx, val); }
306 /** Write a lane of the destination vector operand. */
307 virtual void
308 setVecLaneOperand(const StaticInst *si, int idx,
309 const LaneData<LaneSize::FourByte>& val) override
310 { return setVecLaneOperandT(si, idx, val); }
311 /** Write a lane of the destination vector operand. */
312 virtual void
313 setVecLaneOperand(const StaticInst *si, int idx,
314 const LaneData<LaneSize::EightByte>& val) override
315 { return setVecLaneOperandT(si, idx, val); }
316 /** @} */
317
318 /** Reads an element of a vector register. */
319 VecElem
320 readVecElemOperand(const StaticInst *si, int idx) const override
321 {
322 numVecRegReads++;
323 const RegId& reg = si->srcRegIdx(idx);
324 assert(reg.isVecElem());
325 return thread->readVecElem(reg);
326 }
327
328 /** Sets an element of a vector register to a value. */
329 void
330 setVecElemOperand(const StaticInst *si, int idx,
331 const VecElem val) override
332 {
333 numVecRegWrites++;
334 const RegId& reg = si->destRegIdx(idx);
335 assert(reg.isVecElem());
336 thread->setVecElem(reg, val);
337 }
338
339 const VecPredRegContainer&
340 readVecPredRegOperand(const StaticInst *si, int idx) const override
341 {
342 numVecPredRegReads++;
343 const RegId& reg = si->srcRegIdx(idx);
344 assert(reg.isVecPredReg());
345 return thread->readVecPredReg(reg);
346 }
347
348 VecPredRegContainer&
349 getWritableVecPredRegOperand(const StaticInst *si, int idx) override
350 {
351 numVecPredRegWrites++;
352 const RegId& reg = si->destRegIdx(idx);
353 assert(reg.isVecPredReg());
354 return thread->getWritableVecPredReg(reg);
355 }
356
357 void
358 setVecPredRegOperand(const StaticInst *si, int idx,
359 const VecPredRegContainer& val) override
360 {
361 numVecPredRegWrites++;
362 const RegId& reg = si->destRegIdx(idx);
363 assert(reg.isVecPredReg());
364 thread->setVecPredReg(reg, val);
365 }
366
367 RegVal
368 readCCRegOperand(const StaticInst *si, int idx) override
369 {
370 numCCRegReads++;
371 const RegId& reg = si->srcRegIdx(idx);
372 assert(reg.isCCReg());
373 return thread->readCCReg(reg.index());
374 }
375
376 void
377 setCCRegOperand(const StaticInst *si, int idx, RegVal val) override
378 {
379 numCCRegWrites++;
380 const RegId& reg = si->destRegIdx(idx);
381 assert(reg.isCCReg());
382 thread->setCCReg(reg.index(), val);
383 }
384
385 RegVal
386 readMiscRegOperand(const StaticInst *si, int idx) override
387 {
388 numIntRegReads++;
389 const RegId& reg = si->srcRegIdx(idx);
390 assert(reg.isMiscReg());
391 return thread->readMiscReg(reg.index());
392 }
393
394 void
395 setMiscRegOperand(const StaticInst *si, int idx, RegVal val) override
396 {
397 numIntRegWrites++;
398 const RegId& reg = si->destRegIdx(idx);
399 assert(reg.isMiscReg());
400 thread->setMiscReg(reg.index(), val);
401 }
402
403 /**
404 * Reads a miscellaneous register, handling any architectural
405 * side effects due to reading that register.
406 */
407 RegVal
408 readMiscReg(int misc_reg) override
409 {
410 numIntRegReads++;
411 return thread->readMiscReg(misc_reg);
412 }
413
414 /**
415 * Sets a miscellaneous register, handling any architectural
416 * side effects due to writing that register.
417 */
418 void
419 setMiscReg(int misc_reg, RegVal val) override
420 {
421 numIntRegWrites++;
422 thread->setMiscReg(misc_reg, val);
423 }
424
425 PCState
426 pcState() const override
427 {
428 return thread->pcState();
429 }
430
431 void
432 pcState(const PCState &val) override
433 {
434 thread->pcState(val);
435 }
436
1/*
2 * Copyright (c) 2014-2018 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2002-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Kevin Lim
41 * Andreas Sandberg
42 * Mitch Hayenga
43 */
44
45#ifndef __CPU_SIMPLE_EXEC_CONTEXT_HH__
46#define __CPU_SIMPLE_EXEC_CONTEXT_HH__
47
48#include "arch/registers.hh"
49#include "base/types.hh"
50#include "config/the_isa.hh"
51#include "cpu/base.hh"
52#include "cpu/exec_context.hh"
53#include "cpu/reg_class.hh"
54#include "cpu/simple/base.hh"
55#include "cpu/static_inst_fwd.hh"
56#include "cpu/translation.hh"
57#include "mem/request.hh"
58
59class BaseSimpleCPU;
60
61class SimpleExecContext : public ExecContext {
62 protected:
63 using VecRegContainer = TheISA::VecRegContainer;
64 using VecElem = TheISA::VecElem;
65
66 public:
67 BaseSimpleCPU *cpu;
68 SimpleThread* thread;
69
70 // This is the offset from the current pc that fetch should be performed
71 Addr fetchOffset;
72 // This flag says to stay at the current pc. This is useful for
73 // instructions which go beyond MachInst boundaries.
74 bool stayAtPC;
75
76 // Branch prediction
77 TheISA::PCState predPC;
78
79 /** PER-THREAD STATS */
80
81 // Number of simulated instructions
82 Counter numInst;
83 Stats::Scalar numInsts;
84 Counter numOp;
85 Stats::Scalar numOps;
86
87 // Number of integer alu accesses
88 Stats::Scalar numIntAluAccesses;
89
90 // Number of float alu accesses
91 Stats::Scalar numFpAluAccesses;
92
93 // Number of vector alu accesses
94 Stats::Scalar numVecAluAccesses;
95
96 // Number of function calls/returns
97 Stats::Scalar numCallsReturns;
98
99 // Conditional control instructions;
100 Stats::Scalar numCondCtrlInsts;
101
102 // Number of int instructions
103 Stats::Scalar numIntInsts;
104
105 // Number of float instructions
106 Stats::Scalar numFpInsts;
107
108 // Number of vector instructions
109 Stats::Scalar numVecInsts;
110
111 // Number of integer register file accesses
112 Stats::Scalar numIntRegReads;
113 Stats::Scalar numIntRegWrites;
114
115 // Number of float register file accesses
116 Stats::Scalar numFpRegReads;
117 Stats::Scalar numFpRegWrites;
118
119 // Number of vector register file accesses
120 mutable Stats::Scalar numVecRegReads;
121 Stats::Scalar numVecRegWrites;
122
123 // Number of predicate register file accesses
124 mutable Stats::Scalar numVecPredRegReads;
125 Stats::Scalar numVecPredRegWrites;
126
127 // Number of condition code register file accesses
128 Stats::Scalar numCCRegReads;
129 Stats::Scalar numCCRegWrites;
130
131 // Number of simulated memory references
132 Stats::Scalar numMemRefs;
133 Stats::Scalar numLoadInsts;
134 Stats::Scalar numStoreInsts;
135
136 // Number of idle cycles
137 Stats::Formula numIdleCycles;
138
139 // Number of busy cycles
140 Stats::Formula numBusyCycles;
141
142 // Number of simulated loads
143 Counter numLoad;
144
145 // Number of idle cycles
146 Stats::Average notIdleFraction;
147 Stats::Formula idleFraction;
148
149 // Number of cycles stalled for I-cache responses
150 Stats::Scalar icacheStallCycles;
151 Counter lastIcacheStall;
152
153 // Number of cycles stalled for D-cache responses
154 Stats::Scalar dcacheStallCycles;
155 Counter lastDcacheStall;
156
157 /// @{
158 /// Total number of branches fetched
159 Stats::Scalar numBranches;
160 /// Number of branches predicted as taken
161 Stats::Scalar numPredictedBranches;
162 /// Number of misprediced branches
163 Stats::Scalar numBranchMispred;
164 /// @}
165
166 // Instruction mix histogram by OpClass
167 Stats::Vector statExecutedInstType;
168
169 public:
170 /** Constructor */
171 SimpleExecContext(BaseSimpleCPU* _cpu, SimpleThread* _thread)
172 : cpu(_cpu), thread(_thread), fetchOffset(0), stayAtPC(false),
173 numInst(0), numOp(0), numLoad(0), lastIcacheStall(0), lastDcacheStall(0)
174 { }
175
176 /** Reads an integer register. */
177 RegVal
178 readIntRegOperand(const StaticInst *si, int idx) override
179 {
180 numIntRegReads++;
181 const RegId& reg = si->srcRegIdx(idx);
182 assert(reg.isIntReg());
183 return thread->readIntReg(reg.index());
184 }
185
186 /** Sets an integer register to a value. */
187 void
188 setIntRegOperand(const StaticInst *si, int idx, RegVal val) override
189 {
190 numIntRegWrites++;
191 const RegId& reg = si->destRegIdx(idx);
192 assert(reg.isIntReg());
193 thread->setIntReg(reg.index(), val);
194 }
195
196 /** Reads a floating point register in its binary format, instead
197 * of by value. */
198 RegVal
199 readFloatRegOperandBits(const StaticInst *si, int idx) override
200 {
201 numFpRegReads++;
202 const RegId& reg = si->srcRegIdx(idx);
203 assert(reg.isFloatReg());
204 return thread->readFloatReg(reg.index());
205 }
206
207 /** Sets the bits of a floating point register of single width
208 * to a binary value. */
209 void
210 setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override
211 {
212 numFpRegWrites++;
213 const RegId& reg = si->destRegIdx(idx);
214 assert(reg.isFloatReg());
215 thread->setFloatReg(reg.index(), val);
216 }
217
218 /** Reads a vector register. */
219 const VecRegContainer &
220 readVecRegOperand(const StaticInst *si, int idx) const override
221 {
222 numVecRegReads++;
223 const RegId& reg = si->srcRegIdx(idx);
224 assert(reg.isVecReg());
225 return thread->readVecReg(reg);
226 }
227
228 /** Reads a vector register for modification. */
229 VecRegContainer &
230 getWritableVecRegOperand(const StaticInst *si, int idx) override
231 {
232 numVecRegWrites++;
233 const RegId& reg = si->destRegIdx(idx);
234 assert(reg.isVecReg());
235 return thread->getWritableVecReg(reg);
236 }
237
238 /** Sets a vector register to a value. */
239 void
240 setVecRegOperand(const StaticInst *si, int idx,
241 const VecRegContainer& val) override
242 {
243 numVecRegWrites++;
244 const RegId& reg = si->destRegIdx(idx);
245 assert(reg.isVecReg());
246 thread->setVecReg(reg, val);
247 }
248
249 /** Vector Register Lane Interfaces. */
250 /** @{ */
251 /** Reads source vector lane. */
252 template <typename VecElem>
253 VecLaneT<VecElem, true>
254 readVecLaneOperand(const StaticInst *si, int idx) const
255 {
256 numVecRegReads++;
257 const RegId& reg = si->srcRegIdx(idx);
258 assert(reg.isVecReg());
259 return thread->readVecLane<VecElem>(reg);
260 }
261 /** Reads source vector 8bit operand. */
262 virtual ConstVecLane8
263 readVec8BitLaneOperand(const StaticInst *si, int idx) const
264 override
265 { return readVecLaneOperand<uint8_t>(si, idx); }
266
267 /** Reads source vector 16bit operand. */
268 virtual ConstVecLane16
269 readVec16BitLaneOperand(const StaticInst *si, int idx) const
270 override
271 { return readVecLaneOperand<uint16_t>(si, idx); }
272
273 /** Reads source vector 32bit operand. */
274 virtual ConstVecLane32
275 readVec32BitLaneOperand(const StaticInst *si, int idx) const
276 override
277 { return readVecLaneOperand<uint32_t>(si, idx); }
278
279 /** Reads source vector 64bit operand. */
280 virtual ConstVecLane64
281 readVec64BitLaneOperand(const StaticInst *si, int idx) const
282 override
283 { return readVecLaneOperand<uint64_t>(si, idx); }
284
285 /** Write a lane of the destination vector operand. */
286 template <typename LD>
287 void
288 setVecLaneOperandT(const StaticInst *si, int idx,
289 const LD& val)
290 {
291 numVecRegWrites++;
292 const RegId& reg = si->destRegIdx(idx);
293 assert(reg.isVecReg());
294 return thread->setVecLane(reg, val);
295 }
296 /** Write a lane of the destination vector operand. */
297 virtual void
298 setVecLaneOperand(const StaticInst *si, int idx,
299 const LaneData<LaneSize::Byte>& val) override
300 { return setVecLaneOperandT(si, idx, val); }
301 /** Write a lane of the destination vector operand. */
302 virtual void
303 setVecLaneOperand(const StaticInst *si, int idx,
304 const LaneData<LaneSize::TwoByte>& val) override
305 { return setVecLaneOperandT(si, idx, val); }
306 /** Write a lane of the destination vector operand. */
307 virtual void
308 setVecLaneOperand(const StaticInst *si, int idx,
309 const LaneData<LaneSize::FourByte>& val) override
310 { return setVecLaneOperandT(si, idx, val); }
311 /** Write a lane of the destination vector operand. */
312 virtual void
313 setVecLaneOperand(const StaticInst *si, int idx,
314 const LaneData<LaneSize::EightByte>& val) override
315 { return setVecLaneOperandT(si, idx, val); }
316 /** @} */
317
318 /** Reads an element of a vector register. */
319 VecElem
320 readVecElemOperand(const StaticInst *si, int idx) const override
321 {
322 numVecRegReads++;
323 const RegId& reg = si->srcRegIdx(idx);
324 assert(reg.isVecElem());
325 return thread->readVecElem(reg);
326 }
327
328 /** Sets an element of a vector register to a value. */
329 void
330 setVecElemOperand(const StaticInst *si, int idx,
331 const VecElem val) override
332 {
333 numVecRegWrites++;
334 const RegId& reg = si->destRegIdx(idx);
335 assert(reg.isVecElem());
336 thread->setVecElem(reg, val);
337 }
338
339 const VecPredRegContainer&
340 readVecPredRegOperand(const StaticInst *si, int idx) const override
341 {
342 numVecPredRegReads++;
343 const RegId& reg = si->srcRegIdx(idx);
344 assert(reg.isVecPredReg());
345 return thread->readVecPredReg(reg);
346 }
347
348 VecPredRegContainer&
349 getWritableVecPredRegOperand(const StaticInst *si, int idx) override
350 {
351 numVecPredRegWrites++;
352 const RegId& reg = si->destRegIdx(idx);
353 assert(reg.isVecPredReg());
354 return thread->getWritableVecPredReg(reg);
355 }
356
357 void
358 setVecPredRegOperand(const StaticInst *si, int idx,
359 const VecPredRegContainer& val) override
360 {
361 numVecPredRegWrites++;
362 const RegId& reg = si->destRegIdx(idx);
363 assert(reg.isVecPredReg());
364 thread->setVecPredReg(reg, val);
365 }
366
367 RegVal
368 readCCRegOperand(const StaticInst *si, int idx) override
369 {
370 numCCRegReads++;
371 const RegId& reg = si->srcRegIdx(idx);
372 assert(reg.isCCReg());
373 return thread->readCCReg(reg.index());
374 }
375
376 void
377 setCCRegOperand(const StaticInst *si, int idx, RegVal val) override
378 {
379 numCCRegWrites++;
380 const RegId& reg = si->destRegIdx(idx);
381 assert(reg.isCCReg());
382 thread->setCCReg(reg.index(), val);
383 }
384
385 RegVal
386 readMiscRegOperand(const StaticInst *si, int idx) override
387 {
388 numIntRegReads++;
389 const RegId& reg = si->srcRegIdx(idx);
390 assert(reg.isMiscReg());
391 return thread->readMiscReg(reg.index());
392 }
393
394 void
395 setMiscRegOperand(const StaticInst *si, int idx, RegVal val) override
396 {
397 numIntRegWrites++;
398 const RegId& reg = si->destRegIdx(idx);
399 assert(reg.isMiscReg());
400 thread->setMiscReg(reg.index(), val);
401 }
402
403 /**
404 * Reads a miscellaneous register, handling any architectural
405 * side effects due to reading that register.
406 */
407 RegVal
408 readMiscReg(int misc_reg) override
409 {
410 numIntRegReads++;
411 return thread->readMiscReg(misc_reg);
412 }
413
414 /**
415 * Sets a miscellaneous register, handling any architectural
416 * side effects due to writing that register.
417 */
418 void
419 setMiscReg(int misc_reg, RegVal val) override
420 {
421 numIntRegWrites++;
422 thread->setMiscReg(misc_reg, val);
423 }
424
425 PCState
426 pcState() const override
427 {
428 return thread->pcState();
429 }
430
431 void
432 pcState(const PCState &val) override
433 {
434 thread->pcState(val);
435 }
436
437
438 Fault
439 readMem(Addr addr, uint8_t *data, unsigned int size,
437 Fault
438 readMem(Addr addr, uint8_t *data, unsigned int size,
440 Request::Flags flags) override
439 Request::Flags flags,
440 const std::vector<bool>& byteEnable = std::vector<bool>())
441 override
441 {
442 {
442 return cpu->readMem(addr, data, size, flags);
443 return cpu->readMem(addr, data, size, flags, byteEnable);
443 }
444
445 Fault
446 initiateMemRead(Addr addr, unsigned int size,
444 }
445
446 Fault
447 initiateMemRead(Addr addr, unsigned int size,
447 Request::Flags flags) override
448 Request::Flags flags,
449 const std::vector<bool>& byteEnable = std::vector<bool>())
450 override
448 {
451 {
449 return cpu->initiateMemRead(addr, size, flags);
452 return cpu->initiateMemRead(addr, size, flags, byteEnable);
450 }
451
452 Fault
453 writeMem(uint8_t *data, unsigned int size, Addr addr,
453 }
454
455 Fault
456 writeMem(uint8_t *data, unsigned int size, Addr addr,
454 Request::Flags flags, uint64_t *res) override
457 Request::Flags flags, uint64_t *res,
458 const std::vector<bool>& byteEnable = std::vector<bool>())
459 override
455 {
460 {
456 return cpu->writeMem(data, size, addr, flags, res);
461 assert(byteEnable.empty() || byteEnable.size() == size);
462 return cpu->writeMem(data, size, addr, flags, res, byteEnable);
457 }
458
459 Fault amoMem(Addr addr, uint8_t *data, unsigned int size,
460 Request::Flags flags, AtomicOpFunctor *amo_op) override
461 {
462 return cpu->amoMem(addr, data, size, flags, amo_op);
463 }
464
465 Fault initiateMemAMO(Addr addr, unsigned int size,
466 Request::Flags flags,
467 AtomicOpFunctor *amo_op) override
468 {
469 return cpu->initiateMemAMO(addr, size, flags, amo_op);
470 }
471
472 /**
473 * Sets the number of consecutive store conditional failures.
474 */
475 void
476 setStCondFailures(unsigned int sc_failures) override
477 {
478 thread->setStCondFailures(sc_failures);
479 }
480
481 /**
482 * Returns the number of consecutive store conditional failures.
483 */
484 unsigned int
485 readStCondFailures() const override
486 {
487 return thread->readStCondFailures();
488 }
489
490 /**
491 * Executes a syscall specified by the callnum.
492 */
493 void
494 syscall(int64_t callnum, Fault *fault) override
495 {
496 if (FullSystem)
497 panic("Syscall emulation isn't available in FS mode.");
498
499 thread->syscall(callnum, fault);
500 }
501
502 /** Returns a pointer to the ThreadContext. */
503 ThreadContext *tcBase() override { return thread->getTC(); }
504
505 bool
506 readPredicate() const override
507 {
508 return thread->readPredicate();
509 }
510
511 void
512 setPredicate(bool val) override
513 {
514 thread->setPredicate(val);
515
516 if (cpu->traceData) {
517 cpu->traceData->setPredicate(val);
518 }
519 }
520
521 bool
522 readMemAccPredicate() const override
523 {
524 return thread->readMemAccPredicate();
525 }
526
527 void
528 setMemAccPredicate(bool val) override
529 {
530 thread->setMemAccPredicate(val);
531 }
532
533 /**
534 * Invalidate a page in the DTLB <i>and</i> ITLB.
535 */
536 void
537 demapPage(Addr vaddr, uint64_t asn) override
538 {
539 thread->demapPage(vaddr, asn);
540 }
541
542 void
543 armMonitor(Addr address) override
544 {
545 cpu->armMonitor(thread->threadId(), address);
546 }
547
548 bool
549 mwait(PacketPtr pkt) override
550 {
551 return cpu->mwait(thread->threadId(), pkt);
552 }
553
554 void
555 mwaitAtomic(ThreadContext *tc) override
556 {
557 cpu->mwaitAtomic(thread->threadId(), tc, thread->dtb);
558 }
559
560 AddressMonitor *
561 getAddrMonitor() override
562 {
563 return cpu->getCpuAddrMonitor(thread->threadId());
564 }
565};
566
567#endif // __CPU_EXEC_CONTEXT_HH__
463 }
464
465 Fault amoMem(Addr addr, uint8_t *data, unsigned int size,
466 Request::Flags flags, AtomicOpFunctor *amo_op) override
467 {
468 return cpu->amoMem(addr, data, size, flags, amo_op);
469 }
470
471 Fault initiateMemAMO(Addr addr, unsigned int size,
472 Request::Flags flags,
473 AtomicOpFunctor *amo_op) override
474 {
475 return cpu->initiateMemAMO(addr, size, flags, amo_op);
476 }
477
478 /**
479 * Sets the number of consecutive store conditional failures.
480 */
481 void
482 setStCondFailures(unsigned int sc_failures) override
483 {
484 thread->setStCondFailures(sc_failures);
485 }
486
487 /**
488 * Returns the number of consecutive store conditional failures.
489 */
490 unsigned int
491 readStCondFailures() const override
492 {
493 return thread->readStCondFailures();
494 }
495
496 /**
497 * Executes a syscall specified by the callnum.
498 */
499 void
500 syscall(int64_t callnum, Fault *fault) override
501 {
502 if (FullSystem)
503 panic("Syscall emulation isn't available in FS mode.");
504
505 thread->syscall(callnum, fault);
506 }
507
508 /** Returns a pointer to the ThreadContext. */
509 ThreadContext *tcBase() override { return thread->getTC(); }
510
511 bool
512 readPredicate() const override
513 {
514 return thread->readPredicate();
515 }
516
517 void
518 setPredicate(bool val) override
519 {
520 thread->setPredicate(val);
521
522 if (cpu->traceData) {
523 cpu->traceData->setPredicate(val);
524 }
525 }
526
527 bool
528 readMemAccPredicate() const override
529 {
530 return thread->readMemAccPredicate();
531 }
532
533 void
534 setMemAccPredicate(bool val) override
535 {
536 thread->setMemAccPredicate(val);
537 }
538
539 /**
540 * Invalidate a page in the DTLB <i>and</i> ITLB.
541 */
542 void
543 demapPage(Addr vaddr, uint64_t asn) override
544 {
545 thread->demapPage(vaddr, asn);
546 }
547
548 void
549 armMonitor(Addr address) override
550 {
551 cpu->armMonitor(thread->threadId(), address);
552 }
553
554 bool
555 mwait(PacketPtr pkt) override
556 {
557 return cpu->mwait(thread->threadId(), pkt);
558 }
559
560 void
561 mwaitAtomic(ThreadContext *tc) override
562 {
563 cpu->mwaitAtomic(thread->threadId(), tc, thread->dtb);
564 }
565
566 AddressMonitor *
567 getAddrMonitor() override
568 {
569 return cpu->getCpuAddrMonitor(thread->threadId());
570 }
571};
572
573#endif // __CPU_EXEC_CONTEXT_HH__