Virtualmips: add DERET instruction.

This commit is contained in:
Serge Vakulenko
2015-10-29 18:04:42 -07:00
parent 8d15906495
commit 666f22786f
3 changed files with 42 additions and 13 deletions

View File

@@ -513,17 +513,13 @@ void mips_trigger_debug_exception (cpu_mips_t *cpu, u_int dexc_type)
mips_cp0_t *cp0 = &cpu->cp0;
int old_dm = cpu->cp0.reg[MIPS_CP0_DEBUG] & MIPS_CP0_DEBUG_DM;
/* Set DEPC. */
cp0->reg[MIPS_CP0_DEPC] = cpu->pc;
/* Update exception type bits. */
cpu->cp0.reg[MIPS_CP0_DEBUG] &= ~(MIPS_CP0_DEBUG_DSS |
MIPS_CP0_DEBUG_DBP | MIPS_CP0_DEBUG_DDBL | MIPS_CP0_DEBUG_DDBS |
MIPS_CP0_DEBUG_DIB | MIPS_CP0_DEBUG_DINT |
MIPS_CP0_DEBUG_DDBLIMPR | MIPS_CP0_DEBUG_DDBSIMPR);
if (! old_dm) {
cpu->cp0.reg[MIPS_CP0_DEBUG] |= dexc_type;
}
MIPS_CP0_DEBUG_DBP | MIPS_CP0_DEBUG_DDBL |
MIPS_CP0_DEBUG_DDBS | MIPS_CP0_DEBUG_DIB |
MIPS_CP0_DEBUG_DINT | MIPS_CP0_DEBUG_DDBLIMPR |
MIPS_CP0_DEBUG_DDBSIMPR | MIPS_CP0_DEBUG_DEXCCODE);
cpu->cp0.reg[MIPS_CP0_DEBUG] |= dexc_type;
/* Update delay slot flag. */
if (cpu->is_in_bdslot)
@@ -535,6 +531,9 @@ void mips_trigger_debug_exception (cpu_mips_t *cpu, u_int dexc_type)
cpu->cp0.reg[MIPS_CP0_DEBUG] |= MIPS_CP0_DEBUG_DM;
cpu->cp0.reg[MIPS_CP0_DEBUG] |= MIPS_CP0_DEBUG_IEXI;
/* Set DEPC. */
cp0->reg[MIPS_CP0_DEPC] = cpu->pc | cpu->is_mips16e;
if (cpu->vm->debug_level > 2) {
char *type = 0;
printf ("--- 0x%08x: ", cpu->pc);
@@ -561,7 +560,7 @@ void mips_trigger_debug_exception (cpu_mips_t *cpu, u_int dexc_type)
printf (" c0_depc := %08x\n", cpu->cp0.reg[MIPS_CP0_DEPC]);
}
/* Debug exception vector. */
/* Jump to Debug exception vector. */
cpu->pc = (m_va_t) 0xffffffffbfc00480ULL;
cpu->is_mips16e = 0;
@@ -587,16 +586,39 @@ void fastcall mips_exec_eret (cpu_mips_t * cpu)
if (cp0->reg[MIPS_CP0_STATUS] & MIPS_CP0_STATUS_ERL) {
cp0->reg[MIPS_CP0_STATUS] &= ~MIPS_CP0_STATUS_ERL;
cpu->pc = cp0->reg[MIPS_CP0_ERR_EPC];
} else {
cp0->reg[MIPS_CP0_STATUS] &= ~MIPS_CP0_STATUS_EXL;
cpu->pc = cp0->reg[MIPS_CP0_EPC];
}
if (cpu->vm->debug_level > 2) {
printf (" c0_status := %08x\n", cpu->cp0.reg[MIPS_CP0_STATUS]);
}
/* We have to clear the LLbit */
cpu->ll_bit = 0;
cpu->is_mips16e = cpu->pc & 1;
cpu->pc &= 0xFFFFFFFE;
cpu->pc &= ~1;
}
/* Execute DERET instruction */
void fastcall mips_exec_deret (cpu_mips_t *cpu)
{
mips_cp0_t *cp0 = &cpu->cp0;
/* Clear Debug mode. */
cpu->cp0.reg[MIPS_CP0_DEBUG] &= ~MIPS_CP0_DEBUG_DM;
cpu->cp0.reg[MIPS_CP0_DEBUG] &= ~MIPS_CP0_DEBUG_IEXI;
/* Restore PC. */
cpu->pc = cp0->reg[MIPS_CP0_DEPC];
cpu->is_mips16e = cpu->pc & 1;
cpu->pc &= ~1;
if (cpu->vm->debug_level > 2) {
printf (" c0_debug := %08x\n", cpu->cp0.reg[MIPS_CP0_DEBUG]);
}
}
/* Execute BREAK instruction */

View File

@@ -502,6 +502,7 @@ void mips_trigger_exception (cpu_mips_t * cpu, u_int exc_code, int bd_slot);
void mips_trigger_debug_exception (cpu_mips_t * cpu, u_int dexc_type);
void fastcall mips_exec_soft_fpu (cpu_mips_t * cpu);
void fastcall mips_exec_eret (cpu_mips_t * cpu);
void fastcall mips_exec_deret (cpu_mips_t * cpu);
void fastcall mips_exec_break (cpu_mips_t * cpu, u_int code);
void fastcall mips_trigger_trap_exception (cpu_mips_t * cpu);
void fastcall mips_exec_syscall (cpu_mips_t * cpu);

View File

@@ -735,6 +735,12 @@ static int eret_op (cpu_mips_t * cpu, mips_insn_t insn)
return (1);
}
static int deret_op (cpu_mips_t * cpu, mips_insn_t insn)
{
mips_exec_deret (cpu);
return (1);
}
static int j_op (cpu_mips_t * cpu, mips_insn_t insn)
{
u_int instr_index = bits (insn, 0, 25);
@@ -2259,7 +2265,7 @@ static const struct mips_op_desc mips_tlb_opcodes[] = {
{"?tlb", undef_tlb, 0x1c},
{"?tlb", undef_tlb, 0x1d},
{"?tlb", undef_tlb, 0x1e},
{"?tlb", undef_tlb, 0x1f},
{"deret", deret_op, 0x1f},
{"wait", wait_op, 0x20},
{"?tlb", undef_tlb, 0x21},
{"?tlb", undef_tlb, 0x22},