Virtualmips: merge changes from alexfru.
This commit is contained in:
@@ -575,7 +575,6 @@ void fastcall mips_exec_soft_fpu (cpu_mips_t * cpu)
|
||||
cp0->reg[MIPS_CP0_CAUSE] |= 0x10000000; //CE=1
|
||||
mips_trigger_exception (cpu, MIPS_CP0_CAUSE_CP_UNUSABLE,
|
||||
cpu->is_in_bdslot);
|
||||
|
||||
}
|
||||
|
||||
/* Execute ERET instruction */
|
||||
@@ -624,19 +623,14 @@ void fastcall mips_exec_deret (cpu_mips_t *cpu)
|
||||
/* Execute BREAK instruction */
|
||||
void fastcall mips_exec_break (cpu_mips_t * cpu, u_int code)
|
||||
{
|
||||
//mips_dump_regs(cpu);
|
||||
//printf ("exec break cpu->pc %x\n", cpu->pc);
|
||||
|
||||
/* XXX TODO: Branch Delay slot */
|
||||
mips_trigger_exception (cpu, MIPS_CP0_CAUSE_BP, 0);
|
||||
mips_trigger_exception (cpu, MIPS_CP0_CAUSE_BP, cpu->is_in_bdslot);
|
||||
}
|
||||
|
||||
/* Trigger a Trap Exception */
|
||||
void fastcall mips_trigger_trap_exception (cpu_mips_t * cpu)
|
||||
{
|
||||
/* XXX TODO: Branch Delay slot */
|
||||
printf ("MIPS64: TRAP exception, CPU=%p\n", cpu);
|
||||
mips_trigger_exception (cpu, MIPS_CP0_CAUSE_TRAP, 0);
|
||||
//printf ("MIPS64: TRAP exception, CPU=%p\n", cpu);
|
||||
mips_trigger_exception (cpu, MIPS_CP0_CAUSE_TRAP, cpu->is_in_bdslot);
|
||||
}
|
||||
|
||||
/* Execute SYSCALL instruction */
|
||||
|
||||
@@ -2418,6 +2418,7 @@ static int mips_exec_mips16e(cpu_mips_t* cpu, mips_insn_t instr)
|
||||
cpu->reg_set(cpu, MIPS_GPR_SP, cpu->gpr[MIPS_GPR_SP] + (simm8 << 3));
|
||||
break;
|
||||
case 4: // SVRS
|
||||
// TBD!!! handle memory errors better
|
||||
if (instr & 0x80) { // save
|
||||
uint32_t temp = cpu->gpr[MIPS_GPR_SP];
|
||||
cpu->reg_set(cpu, MIPS_GPR_SP, cpu->gpr[MIPS_GPR_SP] - (imm4 ? imm4 * 8 : 128));
|
||||
@@ -2722,6 +2723,7 @@ static int mips_exec_mips16e(cpu_mips_t* cpu, mips_insn_t instr)
|
||||
cpu->reg_set(cpu, MIPS_GPR_SP, cpu->gpr[MIPS_GPR_SP] + simm16);
|
||||
break;
|
||||
case 4: { // SVRS
|
||||
// TBD!!! handle memory errors better
|
||||
uint32_t astatic = 0;
|
||||
uint32_t i, temp;
|
||||
switch (aregs) {
|
||||
|
||||
@@ -78,17 +78,27 @@ static int forced_inline mips_exec_memop2 (cpu_mips_t * cpu, int memop,
|
||||
return mips_exec_memop (cpu, memop, vaddr, dst_reg, keep_ll_bit);
|
||||
}
|
||||
|
||||
extern void mips_access_special (cpu_mips_t * cpu, m_va_t vaddr, m_uint32_t mask,
|
||||
u_int op_code, u_int op_type, u_int op_size, m_reg_t * data, u_int * exc);
|
||||
|
||||
/* Fetch an instruction */
|
||||
static int mips_fetch_instruction_word (cpu_mips_t * cpu,
|
||||
m_va_t pc, mips_insn_t * insn)
|
||||
static int mips_fetch_instruction_inner (cpu_mips_t * cpu,
|
||||
m_va_t pc, mips_insn_t * insn, u_int size)
|
||||
{
|
||||
m_va_t exec_page;
|
||||
m_uint32_t offset;
|
||||
|
||||
if (unlikely (pc & (size - 1))) {
|
||||
u_int exc = 0;
|
||||
mips_access_special(cpu, pc, MTS_ACC_AE, MIPS_MEMOP_LOOKUP, MTS_READ, size, NULL, &exc);
|
||||
return (1);
|
||||
}
|
||||
|
||||
exec_page = pc & ~(m_va_t) MIPS_MIN_PAGE_IMASK;
|
||||
if (unlikely (exec_page != cpu->njm_exec_page)) {
|
||||
cpu->njm_exec_ptr = cpu->mem_op_lookup (cpu, exec_page);
|
||||
}
|
||||
|
||||
if (cpu->njm_exec_ptr == NULL) {
|
||||
//exception when fetching instruction
|
||||
return (1);
|
||||
@@ -96,6 +106,13 @@ static int mips_fetch_instruction_word (cpu_mips_t * cpu,
|
||||
cpu->njm_exec_page = exec_page;
|
||||
offset = (pc & MIPS_MIN_PAGE_IMASK) >> 2;
|
||||
*insn = vmtoh32 (cpu->njm_exec_ptr[offset]);
|
||||
if (unlikely (size == 2)) {
|
||||
if (pc & 2) {
|
||||
*insn >>= 16;
|
||||
} else {
|
||||
*insn &= 0xFFFF;
|
||||
}
|
||||
}
|
||||
// printf ("(%08x) %08x\n", pc, *insn);
|
||||
return (0);
|
||||
}
|
||||
@@ -103,35 +120,28 @@ static int mips_fetch_instruction_word (cpu_mips_t * cpu,
|
||||
int mips_fetch_instruction (cpu_mips_t * cpu,
|
||||
m_va_t pc, mips_insn_t * insn)
|
||||
{
|
||||
int res = mips_fetch_instruction_word(cpu, pc, insn);
|
||||
cpu->insn_len = 4;
|
||||
if (unlikely(res)) {
|
||||
return res;
|
||||
}
|
||||
int res;
|
||||
if (unlikely(cpu->is_mips16e)) {
|
||||
mips_insn_t i;
|
||||
if (pc & 2) {
|
||||
i = *insn >> 16;
|
||||
} else {
|
||||
i = *insn & 0xFFFF;
|
||||
res = mips_fetch_instruction_inner(cpu, pc, insn, 2);
|
||||
if (unlikely(res)) {
|
||||
return res;
|
||||
}
|
||||
if (unlikely((i >> 11) == 0x1E || (i >> 11) == 3)) {
|
||||
/* 4-byte extended instruction or jal(x) */
|
||||
if (pc & 2) {
|
||||
/* 2 more bytes needed */
|
||||
res = mips_fetch_instruction_word(cpu, pc + 2, insn);
|
||||
if (unlikely(res)) {
|
||||
return res;
|
||||
}
|
||||
*insn = (i << 16) | (*insn & 0xFFFF);
|
||||
} else {
|
||||
*insn = (*insn << 16) | (*insn >> 16);
|
||||
if (unlikely((*insn >> 11) == 0x1E || (*insn >> 11) == 3)) {
|
||||
/* 4-byte extended instruction or jal(x): 2 more bytes needed */
|
||||
mips_insn_t i;
|
||||
res = mips_fetch_instruction_inner(cpu, pc + 2, &i, 2);
|
||||
if (unlikely(res)) {
|
||||
return res;
|
||||
}
|
||||
*insn = (*insn << 16) | i;
|
||||
cpu->insn_len = 4;
|
||||
} else {
|
||||
/* 2-byte instruction */
|
||||
*insn = i;
|
||||
cpu->insn_len = 2;
|
||||
}
|
||||
} else {
|
||||
res = mips_fetch_instruction_inner(cpu, pc, insn, 4);
|
||||
cpu->insn_len = 4;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user