From: Ian Carmichael Date: Tue, 9 Jun 1998 16:54:08 +0000 (+0000) Subject: * Handle 10 and 20-bit versions of Break instruction. Move handling X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=895a7dc2aa8fc1903f0bd3e160ae2eccfbb328f4;p=binutils-gdb.git * Handle 10 and 20-bit versions of Break instruction. Move handling * of special values from signal_exception() in interp.c into mips.igen. * * Modified: gencode.c interp.c mips.igen sim-main.h --- diff --git a/sim/mips/gencode.c b/sim/mips/gencode.c index 928b88e3799..2e5ed289e9d 100644 --- a/sim/mips/gencode.c +++ b/sim/mips/gencode.c @@ -2716,6 +2716,24 @@ build_instruction (doisa, features, mips16, insn) break ; case BREAK: + + printf(" unsigned int break_code = instruction & HALT_INSTRUCTION_MASK;\n"); + printf(" if ( break_code == (HALT_INSTRUCTION & HALT_INSTRUCTION_MASK)\n"); + printf(" || break_code == (HALT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))\n"); + printf(" {\n"); + printf(" sim_engine_halt (SD, CPU, NULL, cia,\n"); + printf(" sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));\n"); + printf(" }\n"); + printf(" else if ( break_code == (BREAKPOINT_INSTRUCTION & HALT_INSTRUCTION_MASK)\n"); + printf(" || break_code == (BREAKPOINT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))\n"); + printf(" {\n"); + printf(" if (STATE & simDELAYSLOT)\n"); + printf(" PC = cia - 4; /* reference the branch instruction */\n"); + printf(" else\n"); + printf(" PC = cia;\n"); + printf(" sim_engine_halt (SD, CPU, NULL, cia, sim_stopped, SIM_SIGTRAP);\n"); + printf(" }\n"); + printf(" SignalException(BreakPoint,instruction);\n"); break ; diff --git a/sim/mips/interp.c b/sim/mips/interp.c index 07b7e6b013c..f35674a2d8b 100644 --- a/sim/mips/interp.c +++ b/sim/mips/interp.c @@ -110,23 +110,11 @@ char* pr_uword64 PARAMS ((uword64 addr)); #define RSVD_INSTRUCTION_ARG_MASK 0xFFFFF -/* The following reserved instruction value is used when a simulator - halt is required. NOTE: Care must be taken, since this value may - be used in later revisions of the MIPS ISA. */ -#define HALT_INSTRUCTION (0x03ff000d) -#define HALT_INSTRUCTION2 (0x0000ffcd) -#define HALT_INSTRUCTION_MASK (0x03FFFFC0) - - /* Bits in the Debug register */ #define Debug_DBD 0x80000000 /* Debug Branch Delay */ #define Debug_DM 0x40000000 /* Debug Mode */ #define Debug_DBp 0x00000002 /* Debug Breakpoint indicator */ - - - - /*---------------------------------------------------------------------------*/ /*-- GDB simulator interface ------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -1839,33 +1827,6 @@ signal_exception (SIM_DESC sd, sim_io_eprintf(sd,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia)); } - case BreakPoint: -#ifdef DEBUG - sim_io_printf(sd,"DBG: SignalException(%d) PC = 0x%s\n",exception,pr_addr(cia)); -#endif /* DEBUG */ - /* Keep a copy of the current A0 in-case this is the program exit - breakpoint: */ - { - va_list ap; - unsigned int instruction; - va_start(ap, exception); - instruction = va_arg(ap,unsigned int); - va_end(ap); - /* Check for our special terminating BREAK: */ - if ((instruction & HALT_INSTRUCTION_MASK) == (HALT_INSTRUCTION & HALT_INSTRUCTION_MASK) || - (instruction & HALT_INSTRUCTION_MASK) == (HALT_INSTRUCTION2 & HALT_INSTRUCTION_MASK)) - { - sim_engine_halt (SD, CPU, NULL, cia, - sim_exited, (unsigned int)(A0 & 0xFFFFFFFF)); - } - } - if (STATE & simDELAYSLOT) - PC = cia - 4; /* reference the branch instruction */ - else - PC = cia; - sim_engine_halt (SD, CPU, NULL, cia, - sim_stopped, SIM_SIGTRAP); - default: /* Store exception code into current exception id variable (used by exit code): */ @@ -1964,6 +1925,7 @@ signal_exception (SIM_DESC sd, sim_engine_halt (SD, CPU, NULL, NULL_CIA, sim_stopped, SIM_SIGFPE); + case BreakPoint: case SystemCall: case Trap: sim_engine_restart (SD, CPU, NULL, PC); @@ -1974,11 +1936,6 @@ signal_exception (SIM_DESC sd, sim_engine_halt (SD, CPU, NULL, NULL_CIA, sim_stopped, SIM_SIGTRAP); - case BreakPoint: - PC = EPC; - sim_engine_abort (SD, CPU, NULL_CIA, - "FATAL: Should not encounter a breakpoint\n"); - default : /* Unknown internal exception */ PC = EPC; sim_engine_halt (SD, CPU, NULL, NULL_CIA, diff --git a/sim/mips/mips.igen b/sim/mips/mips.igen index 10ed6b8c042..d6b247cbc38 100644 --- a/sim/mips/mips.igen +++ b/sim/mips/mips.igen @@ -941,6 +941,36 @@ *tx19: // end-sanitize-tx19 { + /* Check for some break instruction which are reserved for use by the simulator. */ + unsigned int break_code = instruction_0 & HALT_INSTRUCTION_MASK; + if (break_code == (HALT_INSTRUCTION & HALT_INSTRUCTION_MASK) || + break_code == (HALT_INSTRUCTION2 & HALT_INSTRUCTION_MASK)) + { + sim_engine_halt (SD, CPU, NULL, cia, + sim_exited, (unsigned int)(A0 & 0xFFFFFFFF)); + } + else if (break_code == (BREAKPOINT_INSTRUCTION & HALT_INSTRUCTION_MASK) || + break_code == (BREAKPOINT_INSTRUCTION2 & HALT_INSTRUCTION_MASK)) + { + if (STATE & simDELAYSLOT) + PC = cia - 4; /* reference the branch instruction */ + else + PC = cia; + sim_engine_halt (SD, CPU, NULL, cia, sim_stopped, SIM_SIGTRAP); + } +// start-sanitize-sky + else if (break_code == (HALT_INSTRUCTION_PASS & HALT_INSTRUCTION_MASK)) + { + sim_engine_halt (SD, CPU, NULL, cia, sim_exited, 0); + } + else if (break_code == (HALT_INSTRUCTION_FAIL & HALT_INSTRUCTION_MASK)) + { + sim_engine_halt (SD, CPU, NULL, cia, sim_exited, 15); + } +// end-sanitize-sky + + /* If we get this far, we're not an instruction reserved by the sim. Raise + the exception. */ SignalException(BreakPoint, instruction_0); } diff --git a/sim/mips/sim-main.h b/sim/mips/sim-main.h index 295b127f947..4a632ab5f3c 100644 --- a/sim/mips/sim-main.h +++ b/sim/mips/sim-main.h @@ -212,7 +212,7 @@ typedef struct _hilo_history { #define ALU32_END(ANS) \ if (ALU32_HAD_OVERFLOW) \ SignalExceptionIntegerOverflow (); \ - (ANS) = ALU32_OVERFLOW_RESULT + (ANS) = (signed32) ALU32_OVERFLOW_RESULT #define ALU64_END(ANS) \ @@ -838,6 +838,24 @@ struct sim_state { run-time errors in the simulator. */ #define SimulatorFault (0xFFFFFFFF) +/* The following break instructions are reserved for use by the + simulator. The first is used to halt the simulation. The second + is used by gdb for break-points. NOTE: Care must be taken, since + this value may be used in later revisions of the MIPS ISA. */ +#define HALT_INSTRUCTION_MASK (0x03FFFFC0) + +#define HALT_INSTRUCTION (0x03ff000d) +#define HALT_INSTRUCTION2 (0x0000ffcd) + +/* start-sanitize-sky */ +#define HALT_INSTRUCTION_PASS (0x03fffc0d) +#define HALT_INSTRUCTION_FAIL (0x03ffffcd) +/* end-sanitize-sky */ + +#define BREAKPOINT_INSTRUCTION (0x0005000d) +#define BREAKPOINT_INSTRUCTION2 (0x0000014d) + + void signal_exception (SIM_DESC sd, sim_cpu *cpu, address_word cia, int exception, ...); #define SignalException(exc,instruction) signal_exception (SD, CPU, cia, (exc), (instruction)) #define SignalExceptionInterrupt() signal_exception (SD, CPU, cia, Interrupt)