base.hh (10935:acd48ddd725f) base.hh (11147:cc8d6e99cf46)
1/*
1/*
2 * Copyright (c) 2011-2012 ARM Limited
2 * Copyright (c) 2011-2012,2015 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

--- 63 unchanged lines hidden (view full) ---

74}
75
76namespace Trace {
77 class InstRecord;
78}
79
80struct BaseSimpleCPUParams;
81class BPredUnit;
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

--- 63 unchanged lines hidden (view full) ---

74}
75
76namespace Trace {
77 class InstRecord;
78}
79
80struct BaseSimpleCPUParams;
81class BPredUnit;
82class SimpleExecContext;
82
83
83class BaseSimpleCPU : public BaseCPU, public ExecContext
84class BaseSimpleCPU : public BaseCPU
84{
85 protected:
85{
86 protected:
86 typedef TheISA::MiscReg MiscReg;
87 typedef TheISA::FloatReg FloatReg;
88 typedef TheISA::FloatRegBits FloatRegBits;
89 typedef TheISA::CCReg CCReg;
90
87 ThreadID curThread;
91 BPredUnit *branchPred;
92
88 BPredUnit *branchPred;
89
93 protected:
94 Trace::InstRecord *traceData;
90 void checkPcEventQueue();
91 void swapActiveThread();
95
92
96 inline void checkPcEventQueue() {
97 Addr oldpc, pc = thread->instAddr();
98 do {
99 oldpc = pc;
100 system->pcEventQueue.service(tc);
101 pc = thread->instAddr();
102 } while (oldpc != pc);
103 }
104
105 public:
93 public:
106 void wakeup();
107
108 void zero_fill_64(Addr addr) {
109 static int warned = 0;
110 if (!warned) {
111 warn ("WH64 is not implemented");
112 warned = 1;
113 }
114 };
115
116 public:
117 BaseSimpleCPU(BaseSimpleCPUParams *params);
118 virtual ~BaseSimpleCPU();
94 BaseSimpleCPU(BaseSimpleCPUParams *params);
95 virtual ~BaseSimpleCPU();
119
96 void wakeup();
97 virtual void init();
120 public:
98 public:
121 /** SimpleThread object, provides all the architectural state. */
122 SimpleThread *thread;
99 Trace::InstRecord *traceData;
100 CheckerCPU *checker;
123
101
124 /** ThreadContext object, provides an interface for external
125 * objects to modify this thread's state.
126 */
127 ThreadContext *tc;
102 std::vector<SimpleExecContext*> threadInfo;
103 std::list<ThreadID> activeThreads;
128
104
129 CheckerCPU *checker;
105 /** Current instruction */
106 TheISA::MachInst inst;
107 StaticInstPtr curStaticInst;
108 StaticInstPtr curMacroStaticInst;
130
131 protected:
109
110 protected:
132
133 enum Status {
134 Idle,
135 Running,
136 Faulting,
137 ITBWaitResponse,
138 IcacheRetry,
139 IcacheWaitResponse,
140 IcacheWaitSwitch,
141 DTBWaitResponse,
142 DcacheRetry,
143 DcacheWaitResponse,
144 DcacheWaitSwitch,
145 };
146
147 Status _status;
148
149 public:
111 enum Status {
112 Idle,
113 Running,
114 Faulting,
115 ITBWaitResponse,
116 IcacheRetry,
117 IcacheWaitResponse,
118 IcacheWaitSwitch,
119 DTBWaitResponse,
120 DcacheRetry,
121 DcacheWaitResponse,
122 DcacheWaitSwitch,
123 };
124
125 Status _status;
126
127 public:
150
151 Addr dbg_vtophys(Addr addr);
152
128 Addr dbg_vtophys(Addr addr);
129
153 bool interval_stats;
154
130
155 // current instruction
156 TheISA::MachInst inst;
157
158 StaticInstPtr curStaticInst;
159 StaticInstPtr curMacroStaticInst;
160
161 //This is the offset from the current pc that fetch should be performed at
162 Addr fetchOffset;
163 //This flag says to stay at the current pc. This is useful for
164 //instructions which go beyond MachInst boundaries.
165 bool stayAtPC;
166
167 void checkForInterrupts();
168 void setupFetchRequest(Request *req);
169 void preExecute();
170 void postExecute();
171 void advancePC(const Fault &fault);
172
173 virtual void haltContext(ThreadID thread_num);
174
175 // statistics
176 virtual void regStats();
177 virtual void resetStats();
178
179 virtual void startup();
180
131 void checkForInterrupts();
132 void setupFetchRequest(Request *req);
133 void preExecute();
134 void postExecute();
135 void advancePC(const Fault &fault);
136
137 virtual void haltContext(ThreadID thread_num);
138
139 // statistics
140 virtual void regStats();
141 virtual void resetStats();
142
143 virtual void startup();
144
181 // number of simulated instructions
182 Counter numInst;
183 Counter startNumInst;
184 Stats::Scalar numInsts;
185 Counter numOp;
186 Counter startNumOp;
187 Stats::Scalar numOps;
145 virtual Fault readMem(Addr addr, uint8_t* data, unsigned size,
146 unsigned flags) = 0;
188
147
189 void countInst()
190 {
191 if (!curStaticInst->isMicroop() || curStaticInst->isLastMicroop()) {
192 numInst++;
193 numInsts++;
194 }
195 numOp++;
196 numOps++;
148 virtual Fault writeMem(uint8_t* data, unsigned size, Addr addr,
149 unsigned flags, uint64_t* res) = 0;
197
150
198 system->totalNumInsts++;
199 thread->funcExeInst++;
200 }
151 void countInst();
152 virtual Counter totalInsts() const;
153 virtual Counter totalOps() const;
201
154
202 virtual Counter totalInsts() const
203 {
204 return numInst - startNumInst;
205 }
206
207 virtual Counter totalOps() const
208 {
209 return numOp - startNumOp;
210 }
211
212 //number of integer alu accesses
213 Stats::Scalar numIntAluAccesses;
214
215 //number of float alu accesses
216 Stats::Scalar numFpAluAccesses;
217
218 //number of function calls/returns
219 Stats::Scalar numCallsReturns;
220
221 //conditional control instructions;
222 Stats::Scalar numCondCtrlInsts;
223
224 //number of int instructions
225 Stats::Scalar numIntInsts;
226
227 //number of float instructions
228 Stats::Scalar numFpInsts;
229
230 //number of integer register file accesses
231 Stats::Scalar numIntRegReads;
232 Stats::Scalar numIntRegWrites;
233
234 //number of float register file accesses
235 Stats::Scalar numFpRegReads;
236 Stats::Scalar numFpRegWrites;
237
238 //number of condition code register file accesses
239 Stats::Scalar numCCRegReads;
240 Stats::Scalar numCCRegWrites;
241
242 // number of simulated memory references
243 Stats::Scalar numMemRefs;
244 Stats::Scalar numLoadInsts;
245 Stats::Scalar numStoreInsts;
246
247 // number of idle cycles
248 Stats::Formula numIdleCycles;
249
250 // number of busy cycles
251 Stats::Formula numBusyCycles;
252
253 // number of simulated loads
254 Counter numLoad;
255 Counter startNumLoad;
256
257 // number of idle cycles
258 Stats::Average notIdleFraction;
259 Stats::Formula idleFraction;
260
261 // number of cycles stalled for I-cache responses
262 Stats::Scalar icacheStallCycles;
263 Counter lastIcacheStall;
264
265 // number of cycles stalled for D-cache responses
266 Stats::Scalar dcacheStallCycles;
267 Counter lastDcacheStall;
268
269 /// @{
270 /// Total number of branches fetched
271 Stats::Scalar numBranches;
272 /// Number of branches predicted as taken
273 Stats::Scalar numPredictedBranches;
274 /// Number of misprediced branches
275 Stats::Scalar numBranchMispred;
276 /// @}
277
278 // instruction mix histogram by OpClass
279 Stats::Vector statExecutedInstType;
280
281 void serializeThread(CheckpointOut &cp,
282 ThreadID tid) const M5_ATTR_OVERRIDE;
283 void unserializeThread(CheckpointIn &cp, ThreadID tid) M5_ATTR_OVERRIDE;
284
155 void serializeThread(CheckpointOut &cp,
156 ThreadID tid) const M5_ATTR_OVERRIDE;
157 void unserializeThread(CheckpointIn &cp, ThreadID tid) M5_ATTR_OVERRIDE;
158
285 // These functions are only used in CPU models that split
286 // effective address computation from the actual memory access.
287 void setEA(Addr EA) { panic("BaseSimpleCPU::setEA() not implemented\n"); }
288 Addr getEA() const { panic("BaseSimpleCPU::getEA() not implemented\n"); }
289
290 // The register accessor methods provide the index of the
291 // instruction's operand (e.g., 0 or 1), not the architectural
292 // register index, to simplify the implementation of register
293 // renaming. We find the architectural register index by indexing
294 // into the instruction's own operand index table. Note that a
295 // raw pointer to the StaticInst is provided instead of a
296 // ref-counted StaticInstPtr to redice overhead. This is fine as
297 // long as these methods don't copy the pointer into any long-term
298 // storage (which is pretty hard to imagine they would have reason
299 // to do).
300
301 IntReg readIntRegOperand(const StaticInst *si, int idx)
302 {
303 numIntRegReads++;
304 return thread->readIntReg(si->srcRegIdx(idx));
305 }
306
307 FloatReg readFloatRegOperand(const StaticInst *si, int idx)
308 {
309 numFpRegReads++;
310 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
311 return thread->readFloatReg(reg_idx);
312 }
313
314 FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
315 {
316 numFpRegReads++;
317 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
318 return thread->readFloatRegBits(reg_idx);
319 }
320
321 CCReg readCCRegOperand(const StaticInst *si, int idx)
322 {
323 numCCRegReads++;
324 int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base;
325 return thread->readCCReg(reg_idx);
326 }
327
328 void setIntRegOperand(const StaticInst *si, int idx, IntReg val)
329 {
330 numIntRegWrites++;
331 thread->setIntReg(si->destRegIdx(idx), val);
332 }
333
334 void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
335 {
336 numFpRegWrites++;
337 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
338 thread->setFloatReg(reg_idx, val);
339 }
340
341 void setFloatRegOperandBits(const StaticInst *si, int idx,
342 FloatRegBits val)
343 {
344 numFpRegWrites++;
345 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
346 thread->setFloatRegBits(reg_idx, val);
347 }
348
349 void setCCRegOperand(const StaticInst *si, int idx, CCReg val)
350 {
351 numCCRegWrites++;
352 int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base;
353 thread->setCCReg(reg_idx, val);
354 }
355
356 bool readPredicate() { return thread->readPredicate(); }
357 void setPredicate(bool val)
358 {
359 thread->setPredicate(val);
360 if (traceData) {
361 traceData->setPredicate(val);
362 }
363 }
364 TheISA::PCState pcState() const { return thread->pcState(); }
365 void pcState(const TheISA::PCState &val) { thread->pcState(val); }
366 Addr instAddr() { return thread->instAddr(); }
367 Addr nextInstAddr() { return thread->nextInstAddr(); }
368 MicroPC microPC() { return thread->microPC(); }
369
370 MiscReg readMiscRegNoEffect(int misc_reg) const
371 {
372 return thread->readMiscRegNoEffect(misc_reg);
373 }
374
375 MiscReg readMiscReg(int misc_reg)
376 {
377 numIntRegReads++;
378 return thread->readMiscReg(misc_reg);
379 }
380
381 void setMiscReg(int misc_reg, const MiscReg &val)
382 {
383 numIntRegWrites++;
384 return thread->setMiscReg(misc_reg, val);
385 }
386
387 MiscReg readMiscRegOperand(const StaticInst *si, int idx)
388 {
389 numIntRegReads++;
390 int reg_idx = si->srcRegIdx(idx) - TheISA::Misc_Reg_Base;
391 return thread->readMiscReg(reg_idx);
392 }
393
394 void setMiscRegOperand(
395 const StaticInst *si, int idx, const MiscReg &val)
396 {
397 numIntRegWrites++;
398 int reg_idx = si->destRegIdx(idx) - TheISA::Misc_Reg_Base;
399 return thread->setMiscReg(reg_idx, val);
400 }
401
402 void demapPage(Addr vaddr, uint64_t asn)
403 {
404 thread->demapPage(vaddr, asn);
405 }
406
407 void demapInstPage(Addr vaddr, uint64_t asn)
408 {
409 thread->demapInstPage(vaddr, asn);
410 }
411
412 void demapDataPage(Addr vaddr, uint64_t asn)
413 {
414 thread->demapDataPage(vaddr, asn);
415 }
416
417 unsigned int readStCondFailures() const {
418 return thread->readStCondFailures();
419 }
420
421 void setStCondFailures(unsigned int sc_failures) {
422 thread->setStCondFailures(sc_failures);
423 }
424
425 MiscReg readRegOtherThread(int regIdx, ThreadID tid = InvalidThreadID)
426 {
427 panic("Simple CPU models do not support multithreaded "
428 "register access.\n");
429 }
430
431 void setRegOtherThread(int regIdx, MiscReg val,
432 ThreadID tid = InvalidThreadID)
433 {
434 panic("Simple CPU models do not support multithreaded "
435 "register access.\n");
436 }
437
438 //Fault CacheOp(uint8_t Op, Addr EA);
439
440 Fault hwrei() { return thread->hwrei(); }
441 bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
442
443 void
444 syscall(int64_t callnum)
445 {
446 if (FullSystem)
447 panic("Syscall emulation isn't available in FS mode.\n");
448
449 thread->syscall(callnum);
450 }
451
452 ThreadContext *tcBase() { return tc; }
453
454 private:
455 TheISA::PCState pred_pc;
456
457 public:
458 // monitor/mwait funtions
459 void armMonitor(Addr address) { BaseCPU::armMonitor(address); }
460 bool mwait(PacketPtr pkt) { return BaseCPU::mwait(pkt); }
461 void mwaitAtomic(ThreadContext *tc)
462 { return BaseCPU::mwaitAtomic(tc, thread->dtb); }
463 AddressMonitor *getAddrMonitor() { return BaseCPU::getCpuAddrMonitor(); }
464};
465
466#endif // __CPU_SIMPLE_BASE_HH__
159};
160
161#endif // __CPU_SIMPLE_BASE_HH__