Browse Source

o Fixes to repeated watchpoints

o	Add mips ISA instructions needed to handle interrupts
gdb-4_18-branch
Andrew Cagney 30 years ago
parent
commit
56e7c84918
  1. 25
      sim/common/ChangeLog
  2. 34
      sim/mips/ChangeLog
  3. 279
      sim/mips/interp.c

25
sim/common/ChangeLog

@ -1,3 +1,28 @@
Tue Jun 3 04:52:04 1997 Andrew Cagney <cagney@b1.cygnus.com>
* sim-watch.c (schedule_watchpoint): Use sim_unschedule_watchpoint
to remove the old watchpoint, not delete_watchpoint.
(watch_option_handler): Action the correct watchpoint, not just
cycles.
Wed May 28 14:47:41 1997 Andrew Cagney <cagney@b1.cygnus.com>
* sim-n-core.h (sim_core_write_aligned_N): For 8byte reads, output
both low and high word.
(sim_core_write_aligned_N): Ditto.
* sim-trace.c (set_trace_options): Delete code explicitly setting
core->trace.
* sim-options.c (sim_print_help): Call the list commands if not a
standalone simulator.
(sim_print_help): Advise that some options may not be applicable.
* sim-trace.c (set_trace_options): Assume core present.
* sim-events.c (sim_events_schedule_after_signal): Overflow signal
buffer when full not almost full.
Tue May 27 14:32:00 1997 Andrew Cagney <cagney@b1.cygnus.com> Tue May 27 14:32:00 1997 Andrew Cagney <cagney@b1.cygnus.com>
* sim-events.c (sim_events_process): Don't blat the event queue * sim-events.c (sim_events_process): Don't blat the event queue

34
sim/mips/ChangeLog

@ -1,3 +1,35 @@
start-sanitize-r5900
Tue Jun 3 05:00:33 1997 Andrew Cagney <cagney@b1.cygnus.com>
* interp.c (SignalException): Clear the simDELAYSLOT flag when an
exception has been taken.
* interp.c: Implement the ERET and mt/f sr instructions.
Mon Jun 2 23:28:19 1997 Andrew Cagney <cagney@b1.cygnus.com>
* gencode.c (build_instruction): For paddu, extract unsigned
sub-fields.
* gencode.c (build_instruction): Saturate padds instead of padd
instructions.
end-sanitize-r5900
Sat May 31 00:44:16 1997 Andrew Cagney <cagney@b1.cygnus.com>
* interp.c (SignalException): Don't bother restarting an
interrupt.
Fri May 30 23:41:48 1997 Andrew Cagney <cagney@b1.cygnus.com>
* interp.c (SignalException): Really take an interrupt.
(interrupt_event): Only deliver interrupts when enabled.
Tue May 27 20:08:06 1997 Andrew Cagney <cagney@b1.cygnus.com>
* interp.c (sim_info): Only print info when verbose.
(sim_info) Use sim_io_printf for output.
Tue May 27 14:22:23 1997 Andrew Cagney <cagney@b1.cygnus.com> Tue May 27 14:22:23 1997 Andrew Cagney <cagney@b1.cygnus.com>
* interp.c (CoProcPresent): Add UNUSED attribute - not used by all * interp.c (CoProcPresent): Add UNUSED attribute - not used by all
@ -192,8 +224,8 @@ Wed Feb 26 18:32:21 1997 Gavin Koch <gavin@cygnus.com>
Change values to avoid overloading DOUBLEWORD which is tested Change values to avoid overloading DOUBLEWORD which is tested
for all insns. for all insns.
* gencode.c: reinstate "offending code". * gencode.c: reinstate "offending code".
end-sanitize-r5900
end-sanitize-r5900
Mon Feb 24 22:47:14 1997 Dawn Perchik <dawn@cygnus.com> Mon Feb 24 22:47:14 1997 Dawn Perchik <dawn@cygnus.com>
* interp.c: Fix printing of addresses for non-64-bit targets. * interp.c: Fix printing of addresses for non-64-bit targets.

279
sim/mips/interp.c

@ -385,6 +385,8 @@ static ut_reg DSPC = 0; /* delay-slot PC */
#define ksu_user (0x2) #define ksu_user (0x2)
#define ksu_unknown (0x3) #define ksu_unknown (0x3)
#define status_IE (1 << 0) /* Interrupt enable */
#define status_EXL (1 << 1) /* Exception level */
#define status_RE (1 << 25) /* Reverse Endian in user mode */ #define status_RE (1 << 25) /* Reverse Endian in user mode */
#define status_FR (1 << 26) /* enables MIPS III additional FP registers */ #define status_FR (1 << 26) /* enables MIPS III additional FP registers */
#define status_SR (1 << 20) /* soft reset or NMI */ #define status_SR (1 << 20) /* soft reset or NMI */
@ -746,10 +748,18 @@ static const OPTION mips_options[] =
}; };
int interrupt_pending;
static void static void
interrupt_event (SIM_DESC sd, void *data) interrupt_event (SIM_DESC sd, void *data)
{ {
SignalException (Interrupt); if (SR & status_IE)
{
interrupt_pending = 0;
SignalException (Interrupt);
}
else if (!interrupt_pending)
sim_events_schedule (sd, 1, interrupt_event, data);
} }
@ -1240,43 +1250,49 @@ sim_info (sd,verbose)
SIM_DESC sd; SIM_DESC sd;
int verbose; int verbose;
{ {
return;
/* Accessed from the GDB "info files" command: */ /* Accessed from the GDB "info files" command: */
if (STATE_VERBOSE_P (sd) || verbose)
callback->printf_filtered(callback,"MIPS %d-bit simulator\n",(PROCESSOR_64BIT ? 64 : 32)); {
callback->printf_filtered(callback,"%s endian memory model\n", sim_io_printf (sd, "MIPS %d-bit %s endian simulator\n",
(CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN (PROCESSOR_64BIT ? 64 : 32),
? "Big" : "Little")); (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN ? "Big" : "Little"));
callback->printf_filtered(callback,"0x%08X bytes of memory at 0x%s\n", sim_io_printf (sd, "0x%08X bytes of memory at 0x%s\n",
STATE_MEM_SIZE (sd), STATE_MEM_SIZE (sd),
pr_addr (STATE_MEM_BASE (sd))); pr_addr (STATE_MEM_BASE (sd)));
#if !defined(FASTSIM) #if !defined(FASTSIM)
if (instruction_fetch_overflow != 0) #if 0
callback->printf_filtered(callback,"Instruction fetches = 0x%08X%08X\n",instruction_fetch_overflow,instruction_fetches); /* at present this simulator executes one instruction per
else simulator cycle. Consequently this data never changes */
callback->printf_filtered(callback,"Instruction fetches = %d\n",instruction_fetches); if (instruction_fetch_overflow != 0)
callback->printf_filtered(callback,"Pipeline ticks = %ld\n", sim_io_printf (sd, "Instruction fetches = 0x%08X%08X\n",
(long) sim_events_time (sd)); instruction_fetch_overflow, instruction_fetches);
/* It would be a useful feature, if when performing multi-cycle else
simulations (rather than single-stepping) we keep the start and sim_io_printf (sd, "Instruction fetches = %d\n", instruction_fetches);
end times of the execution, so that we can give a performance #endif
figure for the simulator. */ /* It would be a useful feature, if when performing multi-cycle
simulations (rather than single-stepping) we keep the start and
end times of the execution, so that we can give a performance
figure for the simulator. */
#endif /* !FASTSIM */ #endif /* !FASTSIM */
sim_io_printf (sd, "Number of execution cycles = %ld\n",
/* print information pertaining to MIPS ISA and architecture being simulated */ (long) sim_events_time (sd));
/* things that may be interesting */
/* instructions executed - if available */ /* print information pertaining to MIPS ISA and architecture being simulated */
/* cycles executed - if available */ /* things that may be interesting */
/* pipeline stalls - if available */ /* instructions executed - if available */
/* virtual time taken */ /* cycles executed - if available */
/* profiling size */ /* pipeline stalls - if available */
/* profiling frequency */ /* virtual time taken */
/* profile minpc */ /* profiling size */
/* profile maxpc */ /* profiling frequency */
/* profile minpc */
return; /* profile maxpc */
}
} }
SIM_RC SIM_RC
@ -2731,6 +2747,7 @@ SyncOperation(stype)
static void static void
SignalException (int exception,...) SignalException (int exception,...)
{ {
int vector;
SIM_DESC sd = &simulator; SIM_DESC sd = &simulator;
/* Ensure that any active atomic read/modify/write operation will fail: */ /* Ensure that any active atomic read/modify/write operation will fail: */
LLBIT = 0; LLBIT = 0;
@ -2805,22 +2822,40 @@ SignalException (int exception,...)
} }
} }
/* See figure 5-17 for an outline of the code below */
if (! (SR & status_EXL))
{
CAUSE = (exception << 2);
if (state & simDELAYSLOT)
{
state &= ~simDELAYSLOT;
CAUSE |= cause_BD;
EPC = (IPC - 4); /* reference the branch instruction */
}
else
EPC = IPC;
/* FIXME: TLB et.al. */
vector = 0x180;
}
else
{
CAUSE = 0;
vector = 0x180;
}
SR |= status_EXL;
/* Store exception code into current exception id variable (used /* Store exception code into current exception id variable (used
by exit code): */ by exit code): */
CAUSE = (exception << 2); if (SR & status_BEV)
if (state & simDELAYSLOT) { PC = (signed)0xBFC00200 + 0x180;
CAUSE |= cause_BD; else
EPC = (IPC - 4); /* reference the branch instruction */ PC = (signed)0x80000000 + 0x180;
} else
EPC = IPC;
/* The following is so that the simulator will continue from the
exception address on breakpoint operations. */
PC = EPC;
switch ((CAUSE >> 2) & 0x1F) switch ((CAUSE >> 2) & 0x1F)
{ {
case Interrupt: case Interrupt:
sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA, /* Interrupts arrive during event processing, no need to
sim_stopped, SIGINT); restart */
return;
case TLBModification: case TLBModification:
case TLBLoad: case TLBLoad:
@ -2829,11 +2864,15 @@ SignalException (int exception,...)
case AddressStore: case AddressStore:
case InstructionFetch: case InstructionFetch:
case DataReference: case DataReference:
/* The following is so that the simulator will continue from the
exception address on breakpoint operations. */
PC = EPC;
sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA, sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
sim_stopped, SIGBUS); sim_stopped, SIGBUS);
case ReservedInstruction: case ReservedInstruction:
case CoProcessorUnusable: case CoProcessorUnusable:
PC = EPC;
sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA, sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
sim_stopped, SIGILL); sim_stopped, SIGILL);
@ -2846,10 +2885,12 @@ SignalException (int exception,...)
case Watch: case Watch:
case SystemCall: case SystemCall:
case BreakPoint: case BreakPoint:
PC = EPC;
sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA, sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
sim_stopped, SIGTRAP); sim_stopped, SIGTRAP);
default : /* Unknown internal exception */ default : /* Unknown internal exception */
PC = EPC;
sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA, sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
sim_stopped, SIGQUIT); sim_stopped, SIGQUIT);
@ -4026,85 +4067,105 @@ decode_coproc(instruction)
{ {
int coprocnum = ((instruction >> 26) & 3); int coprocnum = ((instruction >> 26) & 3);
switch (coprocnum) { switch (coprocnum)
{
case 0: /* standard CPU control and cache registers */ case 0: /* standard CPU control and cache registers */
{ {
/* NOTEs:
Standard CP0 registers
0 = Index R4000 VR4100 VR4300
1 = Random R4000 VR4100 VR4300
2 = EntryLo0 R4000 VR4100 VR4300
3 = EntryLo1 R4000 VR4100 VR4300
4 = Context R4000 VR4100 VR4300
5 = PageMask R4000 VR4100 VR4300
6 = Wired R4000 VR4100 VR4300
8 = BadVAddr R4000 VR4100 VR4300
9 = Count R4000 VR4100 VR4300
10 = EntryHi R4000 VR4100 VR4300
11 = Compare R4000 VR4100 VR4300
12 = SR R4000 VR4100 VR4300
13 = Cause R4000 VR4100 VR4300
14 = EPC R4000 VR4100 VR4300
15 = PRId R4000 VR4100 VR4300
16 = Config R4000 VR4100 VR4300
17 = LLAddr R4000 VR4100 VR4300
18 = WatchLo R4000 VR4100 VR4300
19 = WatchHi R4000 VR4100 VR4300
20 = XContext R4000 VR4100 VR4300
26 = PErr or ECC R4000 VR4100 VR4300
27 = CacheErr R4000 VR4100
28 = TagLo R4000 VR4100 VR4300
29 = TagHi R4000 VR4100 VR4300
30 = ErrorEPC R4000 VR4100 VR4300
*/
int code = ((instruction >> 21) & 0x1F); int code = ((instruction >> 21) & 0x1F);
/* R4000 Users Manual (second edition) lists the following CP0 /* R4000 Users Manual (second edition) lists the following CP0
instructions: instructions:
DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000) DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000) DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000) MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000) MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001) TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010) TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110) TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000) TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii) CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
ERET Exception return (VR4100 = 01000010000000000000000000011000) ERET Exception return (VR4100 = 01000010000000000000000000011000)
*/ */
if (((code == 0x00) || (code == 0x04)) && ((instruction & 0x7FF) == 0)) { if (((code == 0x00) || (code == 0x04)) && ((instruction & 0x7FF) == 0))
int rt = ((instruction >> 16) & 0x1F); {
#if 0 int rt = ((instruction >> 16) & 0x1F);
int rd = ((instruction >> 11) & 0x1F); int rd = ((instruction >> 11) & 0x1F);
#endif
if (code == 0x00) { /* MF : move from */ switch (rd) /* NOTEs: Standard CP0 registers */
#if 0 /* message should be controlled by configuration option */ {
callback->printf_filtered(callback,"Warning: MFC0 %d,%d not handled yet (architecture specific)\n",rt,rd); /* 0 = Index R4000 VR4100 VR4300 */
#endif /* 1 = Random R4000 VR4100 VR4300 */
GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */ /* 2 = EntryLo0 R4000 VR4100 VR4300 */
} else { /* MT : move to */ /* 3 = EntryLo1 R4000 VR4100 VR4300 */
/* CPR[0,rd] = GPR[rt]; */ /* 4 = Context R4000 VR4100 VR4300 */
#if 0 /* should be controlled by configuration option */ /* 5 = PageMask R4000 VR4100 VR4300 */
callback->printf_filtered(callback,"Warning: MTC0 %d,%d not handled yet (architecture specific)\n",rt,rd); /* 6 = Wired R4000 VR4100 VR4300 */
#endif /* 8 = BadVAddr R4000 VR4100 VR4300 */
} /* 9 = Count R4000 VR4100 VR4300 */
} else /* 10 = EntryHi R4000 VR4100 VR4300 */
sim_warning("Unrecognised COP0 instruction 0x%08X at IPC = 0x%s : No handler present",instruction,pr_addr(IPC)); /* 11 = Compare R4000 VR4100 VR4300 */
/* 12 = SR R4000 VR4100 VR4300 */
case 12:
if (code == 0x00)
GPR[rt] = SR;
else
SR = GPR[rt];
break;
/* 13 = Cause R4000 VR4100 VR4300 */
/* 14 = EPC R4000 VR4100 VR4300 */
/* 15 = PRId R4000 VR4100 VR4300 */
/* 16 = Config R4000 VR4100 VR4300 */
/* 17 = LLAddr R4000 VR4100 VR4300 */
/* 18 = WatchLo R4000 VR4100 VR4300 */
/* 19 = WatchHi R4000 VR4100 VR4300 */
/* 20 = XContext R4000 VR4100 VR4300 */
/* 26 = PErr or ECC R4000 VR4100 VR4300 */
/* 27 = CacheErr R4000 VR4100 */
/* 28 = TagLo R4000 VR4100 VR4300 */
/* 29 = TagHi R4000 VR4100 VR4300 */
/* 30 = ErrorEPC R4000 VR4100 VR4300 */
GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */
/* CPR[0,rd] = GPR[rt]; */
default:
if (code == 0x00)
callback->printf_filtered(callback,"Warning: MFC0 %d,%d not handled yet (architecture specific)\n",rt,rd);
else
callback->printf_filtered(callback,"Warning: MTC0 %d,%d not handled yet (architecture specific)\n",rt,rd);
}
}
else if (code == 0x10 && (instruction & 0x3f) == 0x18)
{
/* ERET */
if (SR & status_ERL)
{
/* Oops, not yet available */
callback->printf_filtered(callback,"Warning: ERET when SR[ERL] set not handled yet");
PC = EPC;
SR &= ~status_ERL;
}
else
{
PC = EPC;
SR &= ~status_EXL;
}
}
else
sim_warning("Unrecognised COP0 instruction 0x%08X at IPC = 0x%s : No handler present",instruction,pr_addr(IPC));
/* TODO: When executing an ERET or RFE instruction we should /* TODO: When executing an ERET or RFE instruction we should
clear LLBIT, to ensure that any out-standing atomic clear LLBIT, to ensure that any out-standing atomic
read/modify/write sequence fails. */ read/modify/write sequence fails. */
} }
break; break;
case 2: /* undefined co-processor */ case 2: /* undefined co-processor */
sim_warning("COP2 instruction 0x%08X at IPC = 0x%s : No handler present",instruction,pr_addr(IPC)); sim_warning("COP2 instruction 0x%08X at IPC = 0x%s : No handler present",instruction,pr_addr(IPC));
break; break;
case 1: /* should not occur (FPU co-processor) */ case 1: /* should not occur (FPU co-processor) */
case 3: /* should not occur (FPU co-processor) */ case 3: /* should not occur (FPU co-processor) */
SignalException(ReservedInstruction,instruction); SignalException(ReservedInstruction,instruction);
break; break;
} }
return; return;
} }

Loading…
Cancel
Save