Line 23... |
Line 23... |
#include <errno.h>
|
#include <errno.h>
|
|
|
#include "arch.h"
|
#include "arch.h"
|
#include "sprs.h"
|
#include "sprs.h"
|
#include "abstract.h"
|
#include "abstract.h"
|
|
#include "sim-config.h"
|
|
|
extern int cont_run; /* defined in toplevel.c */
|
extern int cont_run; /* defined in toplevel.c */
|
extern int tt_stopped; /* defined in tick.c */
|
extern int tt_stopped; /* defined in tick.c */
|
extern int flag;
|
extern int flag;
|
|
|
Line 39... |
Line 40... |
inline void
|
inline void
|
mtspr(const int regno, const sprword value)
|
mtspr(const int regno, const sprword value)
|
{
|
{
|
int ofs = regno % MAX_SPRS_PER_GRP;
|
int ofs = regno % MAX_SPRS_PER_GRP;
|
extern unsigned long pc_phy;
|
extern unsigned long pc_phy;
|
|
extern unsigned long reg[32];
|
|
|
/* MM: Register hooks. */
|
/* MM: Register hooks. */
|
switch (regno) {
|
switch (regno) {
|
case 0xFFFD:
|
case 0xFFFD:
|
fo = fopen ("audiosim.pcm", "wb+");
|
fo = fopen ("audiosim.pcm", "wb+");
|
Line 105... |
Line 107... |
extern unsigned long pc;
|
extern unsigned long pc;
|
extern unsigned long pcnext;
|
extern unsigned long pcnext;
|
extern int delay_insn;
|
extern int delay_insn;
|
extern unsigned long pcdelay;
|
extern unsigned long pcdelay;
|
|
|
|
clear_pending_exception ();
|
|
|
/* The debugger has redirected us to a new address */
|
/* The debugger has redirected us to a new address */
|
/* This is usually done to reissue an instruction
|
/* This is usually done to reissue an instruction
|
which just caused a breakpoint exception. */
|
which just caused a breakpoint exception. */
|
pcnext = value;
|
pc = value;
|
|
|
if(!value)
|
if(!value && config.sim.verbose)
|
printf("WARNING: PC just set to 0!\n");
|
printf("WARNING: PC just set to 0!\n");
|
|
|
/* Clear any pending delay slot jumps also */
|
/* Clear any pending delay slot jumps also */
|
delay_insn = 0;
|
delay_insn = 0;
|
pcdelay = value + 4;
|
pcnext = value + 4;
|
}
|
}
|
break;
|
break;
|
|
default:
|
|
/* Links to GPRS */
|
|
if(regno >= 0x0400 && regno < 0x0420)
|
|
reg[regno - 0x0400] = value;
|
|
break;
|
}
|
}
|
|
|
if (regno < MAX_SPRS)
|
if (regno < MAX_SPRS)
|
sprs[regno] = value;
|
sprs[regno] = value;
|
else {
|
else if (config.sim.verbose)
|
printf("\nABORT: write out of SPR range %08X\n", regno);
|
printf("WARNING: write out of SPR range %08X\n", regno);
|
cont_run = 0;
|
|
}
|
|
}
|
}
|
|
|
/* Get a specific SPR. */
|
/* Get a specific SPR. */
|
inline sprword
|
inline sprword
|
mfspr_(const int regno)
|
mfspr_(const int regno)
|
{
|
{
|
/* CZ 21/06/01 ... the debugger wants to do this! */
|
extern unsigned long reg[32];
|
{
|
|
extern unsigned long pc;
|
extern unsigned long pc;
|
extern unsigned long prevpc;
|
extern unsigned long pcprev;
|
if (regno == SPR_NPC)
|
|
return pc;
|
|
else if (regno == SPR_PPC)
|
|
return prevpc;
|
|
}
|
|
|
|
/* Exceptions are allways enabled */
|
switch (regno) {
|
if (regno == SPR_SR)
|
case SPR_NPC:
|
|
return pc;
|
|
case SPR_PPC:
|
|
return pcprev;
|
|
case SPR_SR:
|
|
/* Exceptions are always enabled */
|
return sprs[regno] | SPR_SR_EXR;
|
return sprs[regno] | SPR_SR_EXR;
|
|
|
|
|
|
default:
|
|
/* Links to GPRS */
|
|
if(regno >= 0x0400 && regno < 0x0420)
|
|
return reg[regno - 0x0400];
|
|
}
|
if (regno < MAX_SPRS)
|
if (regno < MAX_SPRS)
|
return sprs[regno];
|
return sprs[regno];
|
else {
|
|
printf("\nABORT: read out of SPR range %08X\n", regno);
|
if (config.sim.verbose)
|
cont_run = 0;
|
printf ("WARNING: read out of SPR range %08X\n", regno);
|
}
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/* Set a specific bit from SPR. LSB in a word is numbered zero. */
|
/* Set a specific bit from SPR. LSB in a word is numbered zero. */
|
inline void
|
inline void
|