Clean up more tracing.

FIX interrupt delivery - was zapping PSW before it had been saved.
FIX interrupt return, was one instruction out.
This commit is contained in:
Andrew Cagney 1997-09-17 08:14:23 +00:00
parent 175c6fd375
commit a72f8fb439
5 changed files with 112 additions and 211 deletions

View File

@ -1,3 +1,15 @@
Wed Sep 17 16:21:08 1997 Andrew Cagney <cagney@b1.cygnus.com>
* simops.c: Move "mov", "reti", to v850.igen, fix tracing.
* interp.c (hash): Delete.
* v850.igen (nop): Really do nothing.
* interp.c (do_interrupt): Mask interrupts after PSW is saved, not
before.
* v850.igen (reti): Return to current PC not previous.
start-sanitize-v850e
Wed Sep 17 14:02:10 1997 Andrew Cagney <cagney@b1.cygnus.com>

View File

@ -66,151 +66,117 @@ do_interrupt (sd, data)
char **interrupt_name = (char**)data;
enum interrupt_type inttype;
inttype = (interrupt_name - STATE_WATCHPOINTS (sd)->interrupt_names);
/* Disable further interrupts. */
PSW |= PSW_ID;
/* Indicate that we're doing interrupt not exception processing. */
PSW &= ~PSW_EP;
/* For a hardware reset, drop everything and jump to the start
address */
if (inttype == int_reset)
{
PC = 0;
PSW = 0x20;
ECR = 0;
/* (Might be useful to init other regs with random values.) */
sim_engine_restart (sd, NULL, NULL, NULL_CIA);
}
else if (inttype == int_nmi)
/* Deliver an NMI when allowed */
if (inttype == int_nmi)
{
if (PSW & PSW_NP)
{
/* We're already working on an NMI, so this one must wait
around until the previous one is done. The processor
ignores subsequent NMIs, so we don't need to count them. */
State.pending_nmi = 1;
ignores subsequent NMIs, so we don't need to count them.
Just keep re-scheduling a single NMI until it manages to
be delivered */
if (STATE_CPU (sd, 0)->pending_nmi != NULL)
sim_events_deschedule (sd, STATE_CPU (sd, 0)->pending_nmi);
STATE_CPU (sd, 0)->pending_nmi =
sim_events_schedule (sd, 1, do_interrupt, data);
return;
}
else
{
/* NMI can be delivered. Do not deschedule pending_nmi as
that, if still in the event queue, is a second NMI that
needs to be delivered later. */
FEPC = PC;
FEPSW = PSW;
/* Set the FECC part of the ECR. */
ECR &= 0x0000ffff;
ECR |= 0x10;
PSW |= PSW_NP;
PSW &= ~PSW_EP;
PSW |= PSW_ID;
PC = 0x10;
sim_engine_restart (sd, NULL, NULL, NULL_CIA);
}
}
else
/* deliver maskable interrupt when allowed */
if (inttype > int_nmi && inttype < num_int_types)
{
EIPC = PC;
EIPSW = PSW;
/* Clear the EICC part of the ECR, will set below. */
ECR &= 0xffff0000;
switch (inttype)
if ((PSW & PSW_NP) || (PSW & PSW_ID))
{
case int_intov1:
PC = 0x80;
ECR |= 0x80;
break;
case int_intp10:
PC = 0x90;
ECR |= 0x90;
break;
case int_intp11:
PC = 0xa0;
ECR |= 0xa0;
break;
case int_intp12:
PC = 0xb0;
ECR |= 0xb0;
break;
case int_intp13:
PC = 0xc0;
ECR |= 0xc0;
break;
case int_intcm4:
PC = 0xd0;
ECR |= 0xd0;
break;
default:
/* Should never be possible. */
abort ();
break;
/* Can't deliver this interrupt, reschedule it for later */
sim_events_schedule (sd, 1, do_interrupt, data);
return;
}
else
{
/* save context */
EIPC = PC;
EIPSW = PSW;
/* Disable further interrupts. */
PSW |= PSW_ID;
/* Indicate that we're doing interrupt not exception processing. */
PSW &= ~PSW_EP;
/* Clear the EICC part of the ECR, will set below. */
ECR &= 0xffff0000;
switch (inttype)
{
case int_intov1:
PC = 0x80;
ECR |= 0x80;
break;
case int_intp10:
PC = 0x90;
ECR |= 0x90;
break;
case int_intp11:
PC = 0xa0;
ECR |= 0xa0;
break;
case int_intp12:
PC = 0xb0;
ECR |= 0xb0;
break;
case int_intp13:
PC = 0xc0;
ECR |= 0xc0;
break;
case int_intcm4:
PC = 0xd0;
ECR |= 0xd0;
break;
default:
/* Should never be possible. */
sim_engine_abort (sd, NULL, NULL_CIA,
"do_interrupt - internal error - bad switch");
break;
}
}
sim_engine_restart (sd, NULL, NULL, NULL_CIA);
}
/* some other interrupt? */
sim_engine_abort (sd, NULL, NULL_CIA,
"do_interrupt - internal error - interrupt %d unknown",
inttype);
}
/* These default values correspond to expected usage for the chip. */
int v850_debug;
uint32 OP[4];
static long hash PARAMS ((long));
#if 0
static void do_format_1_2 PARAMS ((uint32));
static void do_format_3 PARAMS ((uint32));
static void do_format_4 PARAMS ((uint32));
static void do_format_5 PARAMS ((uint32));
static void do_format_6 PARAMS ((uint32));
static void do_format_7 PARAMS ((uint32));
static void do_format_8 PARAMS ((uint32));
static void do_format_9_10 PARAMS ((uint32));
#endif
#define MAX_HASH 63
struct hash_entry
{
struct hash_entry *next;
unsigned long opcode;
unsigned long mask;
struct simops *ops;
};
struct hash_entry hash_table[MAX_HASH+1];
static INLINE long
hash(insn)
long insn;
{
if ( (insn & 0x0600) == 0
|| (insn & 0x0700) == 0x0200
|| (insn & 0x0700) == 0x0600
|| (insn & 0x0780) == 0x0700)
return (insn & 0x07e0) >> 5;
if ((insn & 0x0700) == 0x0300
|| (insn & 0x0700) == 0x0400
|| (insn & 0x0700) == 0x0500)
return (insn & 0x0780) >> 7;
if ((insn & 0x07c0) == 0x0780)
return (insn & 0x07c0) >> 6;
return (insn & 0x07e0) >> 5;
}
#if 0
static struct hash_entry *
lookup_hash (sd, ins)
SIM_DESC sd;
uint32 ins;
{
struct hash_entry *h;
h = &hash_table[hash(ins)];
while ((ins & h->mask) != h->opcode)
{
if (h->next == NULL)
{
sim_io_error (sd, "ERROR looking up hash for 0x%lx, PC=0x%lx",
(long) ins, (long) PC);
}
h = h->next;
}
return (h);
}
#endif
SIM_DESC
sim_open (kind, cb, abfd, argv)
@ -329,66 +295,6 @@ sim_stop (sd)
return 0;
}
#if 0
void
sim_engine_run (sd, next_cpu_nr, siggnal)
SIM_DESC sd;
int next_cpu_nr;
int siggnal;
{
uint32 inst;
SIM_ADDR oldpc;
while (1)
{
struct hash_entry * h;
/* Fetch the current instruction. */
inst = RLW (PC);
oldpc = PC;
h = lookup_hash (sd, inst);
OP[0] = inst & 0x1f;
OP[1] = (inst >> 11) & 0x1f;
OP[2] = (inst >> 16) & 0xffff;
OP[3] = inst;
/* fprintf (stderr, "PC = %x, SP = %x\n", PC, SP ); */
if (inst == 0)
{
fprintf (stderr, "NOP encountered!\n");
break;
}
PC += h->ops->func ();
if (oldpc == PC)
{
sim_io_eprintf (sd, "simulator loop at %lx\n", (long) PC );
break;
}
if (sim_events_tick (sd))
{
sim_events_process (sd);
}
}
}
#endif
#if 0
int
sim_trace (sd)
SIM_DESC sd;
{
#ifdef DEBUG
v850_debug = DEBUG;
#endif
sim_resume (sd, 0, 0);
return 1;
}
#endif
void
sim_info (sd, verbose)
SIM_DESC sd;

View File

@ -41,7 +41,6 @@ typedef struct _v850_regs {
reg_t sregs[32]; /* system registers, including psw */
reg_t pc;
int dummy_mem; /* where invalid accesses go */
int pending_nmi;
} v850_regs;
struct _sim_cpu
@ -49,6 +48,7 @@ struct _sim_cpu
/* ... simulator specific members ... */
v850_regs reg;
reg_t psw_mask; /* only allow non-reserved bits to be set */
sim_event *pending_nmi;
/* ... base type ... */
sim_cpu_base base;
};

View File

@ -1330,19 +1330,6 @@ OP_160 ()
return 2;
}
/* mov reg, reg */
int
OP_0 ()
{
trace_input ("mov", OP_REG_REG_MOVE, 0);
State.regs[ OP[1] ] = State.regs[ OP[0] ];
trace_output (OP_REG_REG_MOVE);
return 2;
}
/* mov sign_extend(imm5), reg */
int
OP_200 ()
@ -1826,28 +1813,6 @@ OP_12007E0 ()
return 0;
}
/* reti */
int
OP_14007E0 ()
{
trace_input ("reti", OP_NONE, 0);
trace_output (OP_NONE);
/* Restore for NMI if only NP on, otherwise is interrupt or exception. */
if ((PSW & (PSW_NP | PSW_EP)) == PSW_NP)
{
PC = FEPC - 4;
PSW = FEPSW;
}
else
{
PC = EIPC - 4;
PSW = EIPSW;
}
return 0;
}
/* trap */
int
OP_10007E0 ()

View File

@ -631,9 +631,12 @@ regID,111111,RRRRR + 0000000000100000:IX:::ldsr
rrrrr!0,000000,RRRRR:I:::mov
"mov r<reg1>, r<reg2>"
{
COMPAT_1 (OP_0 ());
TRACE_ALU_INPUT0 ();
GR[reg2] = GR[reg1];
TRACE_ALU_RESULT (GR[reg2]);
}
rrrrr!0,010000,iiiii:II:::mov
"mov <imm5>, r<reg2>"
{
@ -757,7 +760,7 @@ rrrrr,111111,iiiii + wwwww,01001,IIII,10:XII:::mulu
0000000000000000:I:::nop
"nop"
{
COMPAT_1 (OP_0 ());
/* do nothing, trace nothing */
}
@ -886,7 +889,22 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI:::ori
0000011111100000 + 0000000101000000:X:::reti
"reti"
{
COMPAT_2 (OP_14007E0 ());
if ((PSW & PSW_EP))
{
nia = (EIPC & ~1);
PSW = EIPSW;
}
else if ((PSW & PSW_NP))
{
nia = (FEPC & ~1);
PSW = FEPSW;
}
else
{
nia = (EIPC & ~1);
PSW = EIPSW;
}
TRACE_BRANCH1 (PSW);
}