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 start-sanitize-v850e
Wed Sep 17 14:02:10 1997 Andrew Cagney <cagney@b1.cygnus.com> 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; char **interrupt_name = (char**)data;
enum interrupt_type inttype; enum interrupt_type inttype;
inttype = (interrupt_name - STATE_WATCHPOINTS (sd)->interrupt_names); inttype = (interrupt_name - STATE_WATCHPOINTS (sd)->interrupt_names);
/* Disable further interrupts. */
PSW |= PSW_ID; /* For a hardware reset, drop everything and jump to the start
/* Indicate that we're doing interrupt not exception processing. */ address */
PSW &= ~PSW_EP;
if (inttype == int_reset) if (inttype == int_reset)
{ {
PC = 0; PC = 0;
PSW = 0x20; PSW = 0x20;
ECR = 0; 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) if (PSW & PSW_NP)
{ {
/* We're already working on an NMI, so this one must wait /* We're already working on an NMI, so this one must wait
around until the previous one is done. The processor around until the previous one is done. The processor
ignores subsequent NMIs, so we don't need to count them. */ ignores subsequent NMIs, so we don't need to count them.
State.pending_nmi = 1; 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 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; FEPC = PC;
FEPSW = PSW; FEPSW = PSW;
/* Set the FECC part of the ECR. */ /* Set the FECC part of the ECR. */
ECR &= 0x0000ffff; ECR &= 0x0000ffff;
ECR |= 0x10; ECR |= 0x10;
PSW |= PSW_NP; PSW |= PSW_NP;
PSW &= ~PSW_EP;
PSW |= PSW_ID;
PC = 0x10; 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; if ((PSW & PSW_NP) || (PSW & PSW_ID))
EIPSW = PSW;
/* Clear the EICC part of the ECR, will set below. */
ECR &= 0xffff0000;
switch (inttype)
{ {
case int_intov1: /* Can't deliver this interrupt, reschedule it for later */
PC = 0x80; sim_events_schedule (sd, 1, do_interrupt, data);
ECR |= 0x80; return;
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;
} }
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. */ /* These default values correspond to expected usage for the chip. */
int v850_debug;
uint32 OP[4]; 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_DESC
sim_open (kind, cb, abfd, argv) sim_open (kind, cb, abfd, argv)
@ -329,66 +295,6 @@ sim_stop (sd)
return 0; 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 void
sim_info (sd, verbose) sim_info (sd, verbose)
SIM_DESC sd; SIM_DESC sd;

View file

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

View file

@ -1330,19 +1330,6 @@ OP_160 ()
return 2; 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 */ /* mov sign_extend(imm5), reg */
int int
OP_200 () OP_200 ()
@ -1826,28 +1813,6 @@ OP_12007E0 ()
return 0; 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 */ /* trap */
int int
OP_10007E0 () OP_10007E0 ()

View file

@ -631,9 +631,12 @@ regID,111111,RRRRR + 0000000000100000:IX:::ldsr
rrrrr!0,000000,RRRRR:I:::mov rrrrr!0,000000,RRRRR:I:::mov
"mov r<reg1>, r<reg2>" "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 rrrrr!0,010000,iiiii:II:::mov
"mov <imm5>, r<reg2>" "mov <imm5>, r<reg2>"
{ {
@ -757,7 +760,7 @@ rrrrr,111111,iiiii + wwwww,01001,IIII,10:XII:::mulu
0000000000000000:I:::nop 0000000000000000:I:::nop
"nop" "nop"
{ {
COMPAT_1 (OP_0 ()); /* do nothing, trace nothing */
} }
@ -886,7 +889,22 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI:::ori
0000011111100000 + 0000000101000000:X:::reti 0000011111100000 + 0000000101000000:X:::reti
"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);
} }