cpu.hh (13500:6e0a2a7c6d8c) cpu.hh (13557:fc33e6048b25)
1/*
2 * Copyright (c) 2011, 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

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

83 * Checker's state through any ThreadContext accesses. This allows the
84 * checker to be able to correctly verify instructions, even with
85 * external accesses to the ThreadContext that change state.
86 */
87class CheckerCPU : public BaseCPU, public ExecContext
88{
89 protected:
90 typedef TheISA::MachInst MachInst;
1/*
2 * Copyright (c) 2011, 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

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

83 * Checker's state through any ThreadContext accesses. This allows the
84 * checker to be able to correctly verify instructions, even with
85 * external accesses to the ThreadContext that change state.
86 */
87class CheckerCPU : public BaseCPU, public ExecContext
88{
89 protected:
90 typedef TheISA::MachInst MachInst;
91 typedef TheISA::FloatReg FloatReg;
92 typedef TheISA::FloatRegBits FloatRegBits;
93 typedef TheISA::MiscReg MiscReg;
94 using VecRegContainer = TheISA::VecRegContainer;
95
96 /** id attached to all issued requests */
97 MasterID masterId;
98 public:
99 void init() override;
100
101 typedef CheckerCPUParams Params;

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

184 // renaming. We find the architectural register index by indexing
185 // into the instruction's own operand index table. Note that a
186 // raw pointer to the StaticInst is provided instead of a
187 // ref-counted StaticInstPtr to redice overhead. This is fine as
188 // long as these methods don't copy the pointer into any long-term
189 // storage (which is pretty hard to imagine they would have reason
190 // to do).
191
91 using VecRegContainer = TheISA::VecRegContainer;
92
93 /** id attached to all issued requests */
94 MasterID masterId;
95 public:
96 void init() override;
97
98 typedef CheckerCPUParams Params;

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

181 // renaming. We find the architectural register index by indexing
182 // into the instruction's own operand index table. Note that a
183 // raw pointer to the StaticInst is provided instead of a
184 // ref-counted StaticInstPtr to redice overhead. This is fine as
185 // long as these methods don't copy the pointer into any long-term
186 // storage (which is pretty hard to imagine they would have reason
187 // to do).
188
192 IntReg readIntRegOperand(const StaticInst *si, int idx) override
189 RegVal
190 readIntRegOperand(const StaticInst *si, int idx) override
193 {
194 const RegId& reg = si->srcRegIdx(idx);
195 assert(reg.isIntReg());
196 return thread->readIntReg(reg.index());
197 }
198
191 {
192 const RegId& reg = si->srcRegIdx(idx);
193 assert(reg.isIntReg());
194 return thread->readIntReg(reg.index());
195 }
196
199 FloatRegBits readFloatRegOperandBits(const StaticInst *si,
200 int idx) override
197 RegVal
198 readFloatRegOperandBits(const StaticInst *si, int idx) override
201 {
202 const RegId& reg = si->srcRegIdx(idx);
203 assert(reg.isFloatReg());
204 return thread->readFloatRegBits(reg.index());
205 }
206
207 /**
208 * Read source vector register operand.
209 */
199 {
200 const RegId& reg = si->srcRegIdx(idx);
201 assert(reg.isFloatReg());
202 return thread->readFloatRegBits(reg.index());
203 }
204
205 /**
206 * Read source vector register operand.
207 */
210 const VecRegContainer& readVecRegOperand(const StaticInst *si,
211 int idx) const override
208 const VecRegContainer &
209 readVecRegOperand(const StaticInst *si, int idx) const override
212 {
213 const RegId& reg = si->srcRegIdx(idx);
214 assert(reg.isVecReg());
215 return thread->readVecReg(reg);
216 }
217
218 /**
219 * Read destination vector register operand for modification.
220 */
210 {
211 const RegId& reg = si->srcRegIdx(idx);
212 assert(reg.isVecReg());
213 return thread->readVecReg(reg);
214 }
215
216 /**
217 * Read destination vector register operand for modification.
218 */
221 VecRegContainer& getWritableVecRegOperand(const StaticInst *si,
222 int idx) override
219 VecRegContainer &
220 getWritableVecRegOperand(const StaticInst *si, int idx) override
223 {
224 const RegId& reg = si->destRegIdx(idx);
225 assert(reg.isVecReg());
226 return thread->getWritableVecReg(reg);
227 }
228
229 /** Vector Register Lane Interfaces. */
230 /** @{ */
231 /** Reads source vector 8bit operand. */
232 virtual ConstVecLane8
221 {
222 const RegId& reg = si->destRegIdx(idx);
223 assert(reg.isVecReg());
224 return thread->getWritableVecReg(reg);
225 }
226
227 /** Vector Register Lane Interfaces. */
228 /** @{ */
229 /** Reads source vector 8bit operand. */
230 virtual ConstVecLane8
233 readVec8BitLaneOperand(const StaticInst *si, int idx) const
234 override
231 readVec8BitLaneOperand(const StaticInst *si, int idx) const override
235 {
236 const RegId& reg = si->destRegIdx(idx);
237 assert(reg.isVecReg());
238 return thread->readVec8BitLaneReg(reg);
239 }
240
241 /** Reads source vector 16bit operand. */
242 virtual ConstVecLane16
232 {
233 const RegId& reg = si->destRegIdx(idx);
234 assert(reg.isVecReg());
235 return thread->readVec8BitLaneReg(reg);
236 }
237
238 /** Reads source vector 16bit operand. */
239 virtual ConstVecLane16
243 readVec16BitLaneOperand(const StaticInst *si, int idx) const
244 override
240 readVec16BitLaneOperand(const StaticInst *si, int idx) const override
245 {
246 const RegId& reg = si->destRegIdx(idx);
247 assert(reg.isVecReg());
248 return thread->readVec16BitLaneReg(reg);
249 }
250
251 /** Reads source vector 32bit operand. */
252 virtual ConstVecLane32
241 {
242 const RegId& reg = si->destRegIdx(idx);
243 assert(reg.isVecReg());
244 return thread->readVec16BitLaneReg(reg);
245 }
246
247 /** Reads source vector 32bit operand. */
248 virtual ConstVecLane32
253 readVec32BitLaneOperand(const StaticInst *si, int idx) const
254 override
249 readVec32BitLaneOperand(const StaticInst *si, int idx) const override
255 {
256 const RegId& reg = si->destRegIdx(idx);
257 assert(reg.isVecReg());
258 return thread->readVec32BitLaneReg(reg);
259 }
260
261 /** Reads source vector 64bit operand. */
262 virtual ConstVecLane64
250 {
251 const RegId& reg = si->destRegIdx(idx);
252 assert(reg.isVecReg());
253 return thread->readVec32BitLaneReg(reg);
254 }
255
256 /** Reads source vector 64bit operand. */
257 virtual ConstVecLane64
263 readVec64BitLaneOperand(const StaticInst *si, int idx) const
264 override
258 readVec64BitLaneOperand(const StaticInst *si, int idx) const override
265 {
266 const RegId& reg = si->destRegIdx(idx);
267 assert(reg.isVecReg());
268 return thread->readVec64BitLaneReg(reg);
269 }
270
271 /** Write a lane of the destination vector operand. */
272 template <typename LD>

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

298 virtual void
299 setVecLaneOperand(const StaticInst *si, int idx,
300 const LaneData<LaneSize::EightByte>& val) override
301 {
302 setVecLaneOperandT(si, idx, val);
303 }
304 /** @} */
305
259 {
260 const RegId& reg = si->destRegIdx(idx);
261 assert(reg.isVecReg());
262 return thread->readVec64BitLaneReg(reg);
263 }
264
265 /** Write a lane of the destination vector operand. */
266 template <typename LD>

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

292 virtual void
293 setVecLaneOperand(const StaticInst *si, int idx,
294 const LaneData<LaneSize::EightByte>& val) override
295 {
296 setVecLaneOperandT(si, idx, val);
297 }
298 /** @} */
299
306 VecElem readVecElemOperand(const StaticInst *si, int idx) const override
300 VecElem
301 readVecElemOperand(const StaticInst *si, int idx) const override
307 {
308 const RegId& reg = si->srcRegIdx(idx);
309 return thread->readVecElem(reg);
310 }
311
302 {
303 const RegId& reg = si->srcRegIdx(idx);
304 return thread->readVecElem(reg);
305 }
306
312 CCReg readCCRegOperand(const StaticInst *si, int idx) override
307 CCReg
308 readCCRegOperand(const StaticInst *si, int idx) override
313 {
314 const RegId& reg = si->srcRegIdx(idx);
315 assert(reg.isCCReg());
316 return thread->readCCReg(reg.index());
317 }
318
319 template<typename T>
309 {
310 const RegId& reg = si->srcRegIdx(idx);
311 assert(reg.isCCReg());
312 return thread->readCCReg(reg.index());
313 }
314
315 template<typename T>
320 void setScalarResult(T&& t)
316 void
317 setScalarResult(T&& t)
321 {
322 result.push(InstResult(std::forward<T>(t),
318 {
319 result.push(InstResult(std::forward<T>(t),
323 InstResult::ResultType::Scalar));
320 InstResult::ResultType::Scalar));
324 }
325
326 template<typename T>
321 }
322
323 template<typename T>
327 void setVecResult(T&& t)
324 void
325 setVecResult(T&& t)
328 {
329 result.push(InstResult(std::forward<T>(t),
326 {
327 result.push(InstResult(std::forward<T>(t),
330 InstResult::ResultType::VecReg));
328 InstResult::ResultType::VecReg));
331 }
332
333 template<typename T>
329 }
330
331 template<typename T>
334 void setVecElemResult(T&& t)
332 void
333 setVecElemResult(T&& t)
335 {
336 result.push(InstResult(std::forward<T>(t),
334 {
335 result.push(InstResult(std::forward<T>(t),
337 InstResult::ResultType::VecElem));
336 InstResult::ResultType::VecElem));
338 }
339
337 }
338
340 void setIntRegOperand(const StaticInst *si, int idx,
341 IntReg val) override
339 void
340 setIntRegOperand(const StaticInst *si, int idx, RegVal val) override
342 {
343 const RegId& reg = si->destRegIdx(idx);
344 assert(reg.isIntReg());
345 thread->setIntReg(reg.index(), val);
346 setScalarResult(val);
347 }
348
341 {
342 const RegId& reg = si->destRegIdx(idx);
343 assert(reg.isIntReg());
344 thread->setIntReg(reg.index(), val);
345 setScalarResult(val);
346 }
347
349 void setFloatRegOperandBits(const StaticInst *si, int idx,
350 FloatRegBits val) override
348 void
349 setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override
351 {
352 const RegId& reg = si->destRegIdx(idx);
353 assert(reg.isFloatReg());
354 thread->setFloatRegBits(reg.index(), val);
355 setScalarResult(val);
356 }
357
350 {
351 const RegId& reg = si->destRegIdx(idx);
352 assert(reg.isFloatReg());
353 thread->setFloatRegBits(reg.index(), val);
354 setScalarResult(val);
355 }
356
358 void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override
357 void
358 setCCRegOperand(const StaticInst *si, int idx, CCReg val) override
359 {
360 const RegId& reg = si->destRegIdx(idx);
361 assert(reg.isCCReg());
362 thread->setCCReg(reg.index(), val);
363 setScalarResult((uint64_t)val);
364 }
365
359 {
360 const RegId& reg = si->destRegIdx(idx);
361 assert(reg.isCCReg());
362 thread->setCCReg(reg.index(), val);
363 setScalarResult((uint64_t)val);
364 }
365
366 void setVecRegOperand(const StaticInst *si, int idx,
367 const VecRegContainer& val) override
366 void
367 setVecRegOperand(const StaticInst *si, int idx,
368 const VecRegContainer& val) override
368 {
369 const RegId& reg = si->destRegIdx(idx);
370 assert(reg.isVecReg());
371 thread->setVecReg(reg, val);
372 setVecResult(val);
373 }
374
369 {
370 const RegId& reg = si->destRegIdx(idx);
371 assert(reg.isVecReg());
372 thread->setVecReg(reg, val);
373 setVecResult(val);
374 }
375
375 void setVecElemOperand(const StaticInst *si, int idx,
376 const VecElem val) override
376 void
377 setVecElemOperand(const StaticInst *si, int idx,
378 const VecElem val) override
377 {
378 const RegId& reg = si->destRegIdx(idx);
379 assert(reg.isVecElem());
380 thread->setVecElem(reg, val);
381 setVecElemResult(val);
382 }
383
384 bool readPredicate() const override { return thread->readPredicate(); }
385
379 {
380 const RegId& reg = si->destRegIdx(idx);
381 assert(reg.isVecElem());
382 thread->setVecElem(reg, val);
383 setVecElemResult(val);
384 }
385
386 bool readPredicate() const override { return thread->readPredicate(); }
387
386 void setPredicate(bool val) override
388 void
389 setPredicate(bool val) override
387 {
388 thread->setPredicate(val);
389 }
390
391 TheISA::PCState pcState() const override { return thread->pcState(); }
390 {
391 thread->setPredicate(val);
392 }
393
394 TheISA::PCState pcState() const override { return thread->pcState(); }
392 void pcState(const TheISA::PCState &val) override
395 void
396 pcState(const TheISA::PCState &val) override
393 {
394 DPRINTF(Checker, "Changing PC to %s, old PC %s.\n",
395 val, thread->pcState());
396 thread->pcState(val);
397 }
398 Addr instAddr() { return thread->instAddr(); }
399 Addr nextInstAddr() { return thread->nextInstAddr(); }
400 MicroPC microPC() { return thread->microPC(); }
401 //////////////////////////////////////////
402
397 {
398 DPRINTF(Checker, "Changing PC to %s, old PC %s.\n",
399 val, thread->pcState());
400 thread->pcState(val);
401 }
402 Addr instAddr() { return thread->instAddr(); }
403 Addr nextInstAddr() { return thread->nextInstAddr(); }
404 MicroPC microPC() { return thread->microPC(); }
405 //////////////////////////////////////////
406
403 MiscReg readMiscRegNoEffect(int misc_reg) const
407 RegVal
408 readMiscRegNoEffect(int misc_reg) const
404 {
405 return thread->readMiscRegNoEffect(misc_reg);
406 }
407
409 {
410 return thread->readMiscRegNoEffect(misc_reg);
411 }
412
408 MiscReg readMiscReg(int misc_reg) override
413 RegVal
414 readMiscReg(int misc_reg) override
409 {
410 return thread->readMiscReg(misc_reg);
411 }
412
415 {
416 return thread->readMiscReg(misc_reg);
417 }
418
413 void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
419 void
420 setMiscRegNoEffect(int misc_reg, const RegVal &val)
414 {
421 {
415 DPRINTF(Checker, "Setting misc reg %d with no effect to check later\n", misc_reg);
422 DPRINTF(Checker, "Setting misc reg %d with no effect to check later\n",
423 misc_reg);
416 miscRegIdxs.push(misc_reg);
417 return thread->setMiscRegNoEffect(misc_reg, val);
418 }
419
424 miscRegIdxs.push(misc_reg);
425 return thread->setMiscRegNoEffect(misc_reg, val);
426 }
427
420 void setMiscReg(int misc_reg, const MiscReg &val) override
428 void
429 setMiscReg(int misc_reg, const RegVal &val) override
421 {
430 {
422 DPRINTF(Checker, "Setting misc reg %d with effect to check later\n", misc_reg);
431 DPRINTF(Checker, "Setting misc reg %d with effect to check later\n",
432 misc_reg);
423 miscRegIdxs.push(misc_reg);
424 return thread->setMiscReg(misc_reg, val);
425 }
426
433 miscRegIdxs.push(misc_reg);
434 return thread->setMiscReg(misc_reg, val);
435 }
436
427 MiscReg readMiscRegOperand(const StaticInst *si, int idx) override
437 RegVal
438 readMiscRegOperand(const StaticInst *si, int idx) override
428 {
429 const RegId& reg = si->srcRegIdx(idx);
430 assert(reg.isMiscReg());
431 return thread->readMiscReg(reg.index());
432 }
433
439 {
440 const RegId& reg = si->srcRegIdx(idx);
441 assert(reg.isMiscReg());
442 return thread->readMiscReg(reg.index());
443 }
444
434 void setMiscRegOperand(const StaticInst *si, int idx,
435 const MiscReg &val) override
445 void
446 setMiscRegOperand(const StaticInst *si, int idx,
447 const RegVal &val) override
436 {
437 const RegId& reg = si->destRegIdx(idx);
438 assert(reg.isMiscReg());
439 return this->setMiscReg(reg.index(), val);
440 }
441
442#if THE_ISA == MIPS_ISA
448 {
449 const RegId& reg = si->destRegIdx(idx);
450 assert(reg.isMiscReg());
451 return this->setMiscReg(reg.index(), val);
452 }
453
454#if THE_ISA == MIPS_ISA
443 MiscReg readRegOtherThread(const RegId& misc_reg, ThreadID tid) override
455 RegVal
456 readRegOtherThread(const RegId &misc_reg, ThreadID tid) override
444 {
445 panic("MIPS MT not defined for CheckerCPU.\n");
446 return 0;
447 }
448
457 {
458 panic("MIPS MT not defined for CheckerCPU.\n");
459 return 0;
460 }
461
449 void setRegOtherThread(const RegId& misc_reg, MiscReg val,
450 ThreadID tid) override
462 void
463 setRegOtherThread(const RegId& misc_reg, RegVal val, ThreadID tid) override
451 {
452 panic("MIPS MT not defined for CheckerCPU.\n");
453 }
454#endif
455
456 /////////////////////////////////////////
457
464 {
465 panic("MIPS MT not defined for CheckerCPU.\n");
466 }
467#endif
468
469 /////////////////////////////////////////
470
458 void recordPCChange(const TheISA::PCState &val)
471 void
472 recordPCChange(const TheISA::PCState &val)
459 {
460 changedPC = true;
461 newPCState = val;
462 }
463
473 {
474 changedPC = true;
475 newPCState = val;
476 }
477
464 void demapPage(Addr vaddr, uint64_t asn) override
478 void
479 demapPage(Addr vaddr, uint64_t asn) override
465 {
466 this->itb->demapPage(vaddr, asn);
467 this->dtb->demapPage(vaddr, asn);
468 }
469
470 // monitor/mwait funtions
480 {
481 this->itb->demapPage(vaddr, asn);
482 this->dtb->demapPage(vaddr, asn);
483 }
484
485 // monitor/mwait funtions
471 void armMonitor(Addr address) override
472 { BaseCPU::armMonitor(0, address); }
486 void armMonitor(Addr address) override { BaseCPU::armMonitor(0, address); }
473 bool mwait(PacketPtr pkt) override { return BaseCPU::mwait(0, pkt); }
474 void mwaitAtomic(ThreadContext *tc) override
475 { return BaseCPU::mwaitAtomic(0, tc, thread->dtb); }
476 AddressMonitor *getAddrMonitor() override
477 { return BaseCPU::getCpuAddrMonitor(0); }
478
487 bool mwait(PacketPtr pkt) override { return BaseCPU::mwait(0, pkt); }
488 void mwaitAtomic(ThreadContext *tc) override
489 { return BaseCPU::mwaitAtomic(0, tc, thread->dtb); }
490 AddressMonitor *getAddrMonitor() override
491 { return BaseCPU::getCpuAddrMonitor(0); }
492
479 void demapInstPage(Addr vaddr, uint64_t asn)
493 void
494 demapInstPage(Addr vaddr, uint64_t asn)
480 {
481 this->itb->demapPage(vaddr, asn);
482 }
483
495 {
496 this->itb->demapPage(vaddr, asn);
497 }
498
484 void demapDataPage(Addr vaddr, uint64_t asn)
499 void
500 demapDataPage(Addr vaddr, uint64_t asn)
485 {
486 this->dtb->demapPage(vaddr, asn);
487 }
488
489 Fault readMem(Addr addr, uint8_t *data, unsigned size,
490 Request::Flags flags) override;
491 Fault writeMem(uint8_t *data, unsigned size, Addr addr,
492 Request::Flags flags, uint64_t *res) override;
493
501 {
502 this->dtb->demapPage(vaddr, asn);
503 }
504
505 Fault readMem(Addr addr, uint8_t *data, unsigned size,
506 Request::Flags flags) override;
507 Fault writeMem(uint8_t *data, unsigned size, Addr addr,
508 Request::Flags flags, uint64_t *res) override;
509
494 unsigned int readStCondFailures() const override {
510 unsigned int
511 readStCondFailures() const override {
495 return thread->readStCondFailures();
496 }
497
512 return thread->readStCondFailures();
513 }
514
498 void setStCondFailures(unsigned int sc_failures) override
499 {}
515 void setStCondFailures(unsigned int sc_failures) override {}
500 /////////////////////////////////////////////////////
501
502 Fault hwrei() override { return thread->hwrei(); }
503 bool simPalCheck(int palFunc) override
504 { return thread->simPalCheck(palFunc); }
505 void wakeup(ThreadID tid) override { }
506 // Assume that the normal CPU's call to syscall was successful.
507 // The checker's state would have already been updated by the syscall.
508 void syscall(int64_t callnum, Fault *fault) override { }
509
516 /////////////////////////////////////////////////////
517
518 Fault hwrei() override { return thread->hwrei(); }
519 bool simPalCheck(int palFunc) override
520 { return thread->simPalCheck(palFunc); }
521 void wakeup(ThreadID tid) override { }
522 // Assume that the normal CPU's call to syscall was successful.
523 // The checker's state would have already been updated by the syscall.
524 void syscall(int64_t callnum, Fault *fault) override { }
525
510 void handleError()
526 void
527 handleError()
511 {
512 if (exitOnError)
513 dumpAndExit();
514 }
515
516 bool checkFlags(const RequestPtr &unverified_req, Addr vAddr,
517 Addr pAddr, int flags);
518

--- 73 unchanged lines hidden ---
528 {
529 if (exitOnError)
530 dumpAndExit();
531 }
532
533 bool checkFlags(const RequestPtr &unverified_req, Addr vAddr,
534 Addr pAddr, int flags);
535

--- 73 unchanged lines hidden ---