cpu_impl.hh (7679:f26cc2c68b48) cpu_impl.hh (7823:dac01f14f20f)
1/*
2 * Copyright (c) 2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

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

121 DPRINTF(Checker, "Changed PC recently to %#x\n",
122 thread->readPC());
123 if (willChangePC) {
124 if (newPC == thread->readPC()) {
125 DPRINTF(Checker, "Changed PC matches expected PC\n");
126 } else {
127 warn("%lli: Changed PC does not match expected PC, "
128 "changed: %#x, expected: %#x",
1/*
2 * Copyright (c) 2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

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

121 DPRINTF(Checker, "Changed PC recently to %#x\n",
122 thread->readPC());
123 if (willChangePC) {
124 if (newPC == thread->readPC()) {
125 DPRINTF(Checker, "Changed PC matches expected PC\n");
126 } else {
127 warn("%lli: Changed PC does not match expected PC, "
128 "changed: %#x, expected: %#x",
129 curTick, thread->readPC(), newPC);
129 curTick(), thread->readPC(), newPC);
130 CheckerCPU::handleError();
131 }
132 willChangePC = false;
133 }
134 changedPC = false;
135 }
136 if (changedNextPC) {
137 DPRINTF(Checker, "Changed NextPC recently to %#x\n",

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

161 if (!succeeded) {
162 if (inst->getFault() == NoFault) {
163 // In this case the instruction was not a dummy
164 // instruction carrying an ITB fault. In the single
165 // threaded case the ITB should still be able to
166 // translate this instruction; in the SMT case it's
167 // possible that its ITB entry was kicked out.
168 warn("%lli: Instruction PC %#x was not found in the ITB!",
130 CheckerCPU::handleError();
131 }
132 willChangePC = false;
133 }
134 changedPC = false;
135 }
136 if (changedNextPC) {
137 DPRINTF(Checker, "Changed NextPC recently to %#x\n",

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

161 if (!succeeded) {
162 if (inst->getFault() == NoFault) {
163 // In this case the instruction was not a dummy
164 // instruction carrying an ITB fault. In the single
165 // threaded case the ITB should still be able to
166 // translate this instruction; in the SMT case it's
167 // possible that its ITB entry was kicked out.
168 warn("%lli: Instruction PC %#x was not found in the ITB!",
169 curTick, thread->readPC());
169 curTick(), thread->readPC());
170 handleError(inst);
171
172 // go to the next instruction
173 thread->setPC(thread->readNextPC());
174 thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
175
176 break;
177 } else {

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

310}
311
312template <class DynInstPtr>
313void
314Checker<DynInstPtr>::validateInst(DynInstPtr &inst)
315{
316 if (inst->readPC() != thread->readPC()) {
317 warn("%lli: PCs do not match! Inst: %#x, checker: %#x",
170 handleError(inst);
171
172 // go to the next instruction
173 thread->setPC(thread->readNextPC());
174 thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
175
176 break;
177 } else {

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

310}
311
312template <class DynInstPtr>
313void
314Checker<DynInstPtr>::validateInst(DynInstPtr &inst)
315{
316 if (inst->readPC() != thread->readPC()) {
317 warn("%lli: PCs do not match! Inst: %#x, checker: %#x",
318 curTick, inst->readPC(), thread->readPC());
318 curTick(), inst->readPC(), thread->readPC());
319 if (changedPC) {
320 warn("%lli: Changed PCs recently, may not be an error",
319 if (changedPC) {
320 warn("%lli: Changed PCs recently, may not be an error",
321 curTick);
321 curTick());
322 } else {
323 handleError(inst);
324 }
325 }
326
327 MachInst mi = static_cast<MachInst>(inst->staticInst->machInst);
328
329 if (mi != machInst) {
330 warn("%lli: Binary instructions do not match! Inst: %#x, "
331 "checker: %#x",
322 } else {
323 handleError(inst);
324 }
325 }
326
327 MachInst mi = static_cast<MachInst>(inst->staticInst->machInst);
328
329 if (mi != machInst) {
330 warn("%lli: Binary instructions do not match! Inst: %#x, "
331 "checker: %#x",
332 curTick, mi, machInst);
332 curTick(), mi, machInst);
333 handleError(inst);
334 }
335}
336
337template <class DynInstPtr>
338void
339Checker<DynInstPtr>::validateExecution(DynInstPtr &inst)
340{

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

349 } else if (result.integer != inst->readIntResult()) {
350 result_mismatch = true;
351 }
352 }
353
354 if (result_mismatch) {
355 warn("%lli: Instruction results do not match! (Values may not "
356 "actually be integers) Inst: %#x, checker: %#x",
333 handleError(inst);
334 }
335}
336
337template <class DynInstPtr>
338void
339Checker<DynInstPtr>::validateExecution(DynInstPtr &inst)
340{

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

349 } else if (result.integer != inst->readIntResult()) {
350 result_mismatch = true;
351 }
352 }
353
354 if (result_mismatch) {
355 warn("%lli: Instruction results do not match! (Values may not "
356 "actually be integers) Inst: %#x, checker: %#x",
357 curTick, inst->readIntResult(), result.integer);
357 curTick(), inst->readIntResult(), result.integer);
358
359 // It's useful to verify load values from memory, but in MP
360 // systems the value obtained at execute may be different than
361 // the value obtained at completion. Similarly DMA can
362 // present the same problem on even UP systems. Thus there is
363 // the option to only warn on loads having a result error.
364 if (inst->isLoad() && warnOnlyOnLoadError) {
365 copyResult(inst);
366 } else {
367 handleError(inst);
368 }
369 }
370
371 if (inst->readNextPC() != thread->readNextPC()) {
372 warn("%lli: Instruction next PCs do not match! Inst: %#x, "
373 "checker: %#x",
358
359 // It's useful to verify load values from memory, but in MP
360 // systems the value obtained at execute may be different than
361 // the value obtained at completion. Similarly DMA can
362 // present the same problem on even UP systems. Thus there is
363 // the option to only warn on loads having a result error.
364 if (inst->isLoad() && warnOnlyOnLoadError) {
365 copyResult(inst);
366 } else {
367 handleError(inst);
368 }
369 }
370
371 if (inst->readNextPC() != thread->readNextPC()) {
372 warn("%lli: Instruction next PCs do not match! Inst: %#x, "
373 "checker: %#x",
374 curTick, inst->readNextPC(), thread->readNextPC());
374 curTick(), inst->readNextPC(), thread->readNextPC());
375 handleError(inst);
376 }
377
378 // Checking side effect registers can be difficult if they are not
379 // checked simultaneously with the execution of the instruction.
380 // This is because other valid instructions may have modified
381 // these registers in the meantime, and their values are not
382 // stored within the DynInst.
383 while (!miscRegIdxs.empty()) {
384 int misc_reg_idx = miscRegIdxs.front();
385 miscRegIdxs.pop();
386
387 if (inst->tcBase()->readMiscRegNoEffect(misc_reg_idx) !=
388 thread->readMiscRegNoEffect(misc_reg_idx)) {
389 warn("%lli: Misc reg idx %i (side effect) does not match! "
390 "Inst: %#x, checker: %#x",
375 handleError(inst);
376 }
377
378 // Checking side effect registers can be difficult if they are not
379 // checked simultaneously with the execution of the instruction.
380 // This is because other valid instructions may have modified
381 // these registers in the meantime, and their values are not
382 // stored within the DynInst.
383 while (!miscRegIdxs.empty()) {
384 int misc_reg_idx = miscRegIdxs.front();
385 miscRegIdxs.pop();
386
387 if (inst->tcBase()->readMiscRegNoEffect(misc_reg_idx) !=
388 thread->readMiscRegNoEffect(misc_reg_idx)) {
389 warn("%lli: Misc reg idx %i (side effect) does not match! "
390 "Inst: %#x, checker: %#x",
391 curTick, misc_reg_idx,
391 curTick(), misc_reg_idx,
392 inst->tcBase()->readMiscRegNoEffect(misc_reg_idx),
393 thread->readMiscRegNoEffect(misc_reg_idx));
394 handleError(inst);
395 }
396 }
397}
398
399template <class DynInstPtr>
400void
401Checker<DynInstPtr>::validateState()
402{
403 if (updateThisCycle) {
404 warn("%lli: Instruction PC %#x results didn't match up, copying all "
392 inst->tcBase()->readMiscRegNoEffect(misc_reg_idx),
393 thread->readMiscRegNoEffect(misc_reg_idx));
394 handleError(inst);
395 }
396 }
397}
398
399template <class DynInstPtr>
400void
401Checker<DynInstPtr>::validateState()
402{
403 if (updateThisCycle) {
404 warn("%lli: Instruction PC %#x results didn't match up, copying all "
405 "registers from main CPU", curTick, unverifiedInst->readPC());
405 "registers from main CPU", curTick(), unverifiedInst->readPC());
406 // Heavy-weight copying of all registers
407 thread->copyArchRegs(unverifiedInst->tcBase());
408 // Also advance the PC. Hopefully no PC-based events happened.
409#if THE_ISA != MIPS_ISA
410 // go to the next instruction
411 thread->setPC(thread->readNextPC());
412 thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
413#else

--- 68 unchanged lines hidden ---
406 // Heavy-weight copying of all registers
407 thread->copyArchRegs(unverifiedInst->tcBase());
408 // Also advance the PC. Hopefully no PC-based events happened.
409#if THE_ISA != MIPS_ISA
410 // go to the next instruction
411 thread->setPC(thread->readNextPC());
412 thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
413#else

--- 68 unchanged lines hidden ---