diff options
-rw-r--r-- | sim/v850/ChangeLog | 12 | ||||
-rw-r--r-- | sim/v850/interp.c | 250 | ||||
-rw-r--r-- | sim/v850/sim-main.h | 2 | ||||
-rw-r--r-- | sim/v850/simops.c | 35 | ||||
-rw-r--r-- | sim/v850/v850.igen | 24 |
5 files changed, 112 insertions, 211 deletions
diff --git a/sim/v850/ChangeLog b/sim/v850/ChangeLog index 0ff17a9..47ae556 100644 --- a/sim/v850/ChangeLog +++ b/sim/v850/ChangeLog @@ -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> diff --git a/sim/v850/interp.c b/sim/v850/interp.c index 3d7d866..3532011 100644 --- a/sim/v850/interp.c +++ b/sim/v850/interp.c @@ -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; diff --git a/sim/v850/sim-main.h b/sim/v850/sim-main.h index 44a5669..a4c57af 100644 --- a/sim/v850/sim-main.h +++ b/sim/v850/sim-main.h @@ -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; }; diff --git a/sim/v850/simops.c b/sim/v850/simops.c index 60dc170..8a360a3 100644 --- a/sim/v850/simops.c +++ b/sim/v850/simops.c @@ -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 () diff --git a/sim/v850/v850.igen b/sim/v850/v850.igen index eb7451a..fd45a30 100644 --- a/sim/v850/v850.igen +++ b/sim/v850/v850.igen @@ -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); } |