145 |
|
// CPU context to preserve on interrupt |
146 |
|
class interrupt_context { |
147 |
|
uint32 gpr[32]; |
148 |
+ |
double fpr[32]; |
149 |
|
uint32 pc; |
150 |
|
uint32 lr; |
151 |
|
uint32 ctr; |
152 |
|
uint32 cr; |
153 |
|
uint32 xer; |
154 |
+ |
uint32 fpscr; |
155 |
|
sheepshaver_cpu *cpu; |
156 |
|
const char *where; |
157 |
|
public: |
488 |
|
|
489 |
|
// Save interrupt context |
490 |
|
memcpy(&gpr[0], &cpu->gpr(0), sizeof(gpr)); |
491 |
+ |
memcpy(&fpr[0], &cpu->fpr(0), sizeof(fpr)); |
492 |
|
pc = cpu->pc(); |
493 |
|
lr = cpu->lr(); |
494 |
|
ctr = cpu->ctr(); |
495 |
|
cr = cpu->get_cr(); |
496 |
|
xer = cpu->get_xer(); |
497 |
+ |
fpscr = cpu->fpscr(); |
498 |
|
#endif |
499 |
|
} |
500 |
|
|
508 |
|
if (gpr[i] != cpu->gpr(i)) |
509 |
|
printf(" r%d: %08x -> %08x\n", i, gpr[i], cpu->gpr(i)); |
510 |
|
} |
511 |
+ |
if (memcmp(&fpr[0], &cpu->fpr(0), sizeof(fpr)) != 0) { |
512 |
+ |
printf("FATAL: %s: interrupt clobbers registers\n", where); |
513 |
+ |
for (int i = 0; i < 32; i++) |
514 |
+ |
if (fpr[i] != cpu->fpr(i)) |
515 |
+ |
printf(" r%d: %f -> %f\n", i, fpr[i], cpu->fpr(i)); |
516 |
+ |
} |
517 |
|
if (pc != cpu->pc()) |
518 |
|
printf("FATAL: %s: interrupt clobbers PC\n", where); |
519 |
|
if (lr != cpu->lr()) |
524 |
|
printf("FATAL: %s: interrupt clobbers CR\n", where); |
525 |
|
if (xer != cpu->get_xer()) |
526 |
|
printf("FATAL: %s: interrupt clobbers XER\n", where); |
527 |
+ |
if (fpscr != cpu->fpscr()) |
528 |
+ |
printf("FATAL: %s: interrupt clobbers FPSCR\n", where); |
529 |
|
#endif |
530 |
|
} |
531 |
|
|