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
|
cp0->reg[MIPS_CP0_CAUSE] |= 0x10000000; //CE=1
|
||||||
mips_trigger_exception (cpu, MIPS_CP0_CAUSE_CP_UNUSABLE,
|
mips_trigger_exception (cpu, MIPS_CP0_CAUSE_CP_UNUSABLE,
|
||||||
cpu->is_in_bdslot);
|
cpu->is_in_bdslot);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Execute ERET instruction */
|
/* Execute ERET instruction */
|
||||||
@@ -624,19 +623,14 @@ void fastcall mips_exec_deret (cpu_mips_t *cpu)
|
|||||||
/* Execute BREAK instruction */
|
/* Execute BREAK instruction */
|
||||||
void fastcall mips_exec_break (cpu_mips_t * cpu, u_int code)
|
void fastcall mips_exec_break (cpu_mips_t * cpu, u_int code)
|
||||||
{
|
{
|
||||||
//mips_dump_regs(cpu);
|
mips_trigger_exception (cpu, MIPS_CP0_CAUSE_BP, cpu->is_in_bdslot);
|
||||||
//printf ("exec break cpu->pc %x\n", cpu->pc);
|
|
||||||
|
|
||||||
/* XXX TODO: Branch Delay slot */
|
|
||||||
mips_trigger_exception (cpu, MIPS_CP0_CAUSE_BP, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Trigger a Trap Exception */
|
/* Trigger a Trap Exception */
|
||||||
void fastcall mips_trigger_trap_exception (cpu_mips_t * cpu)
|
void fastcall mips_trigger_trap_exception (cpu_mips_t * cpu)
|
||||||
{
|
{
|
||||||
/* XXX TODO: Branch Delay slot */
|
//printf ("MIPS64: TRAP exception, CPU=%p\n", cpu);
|
||||||
printf ("MIPS64: TRAP exception, CPU=%p\n", cpu);
|
mips_trigger_exception (cpu, MIPS_CP0_CAUSE_TRAP, cpu->is_in_bdslot);
|
||||||
mips_trigger_exception (cpu, MIPS_CP0_CAUSE_TRAP, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Execute SYSCALL instruction */
|
/* 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));
|
cpu->reg_set(cpu, MIPS_GPR_SP, cpu->gpr[MIPS_GPR_SP] + (simm8 << 3));
|
||||||
break;
|
break;
|
||||||
case 4: // SVRS
|
case 4: // SVRS
|
||||||
|
// TBD!!! handle memory errors better
|
||||||
if (instr & 0x80) { // save
|
if (instr & 0x80) { // save
|
||||||
uint32_t temp = cpu->gpr[MIPS_GPR_SP];
|
uint32_t temp = cpu->gpr[MIPS_GPR_SP];
|
||||||
cpu->reg_set(cpu, MIPS_GPR_SP, cpu->gpr[MIPS_GPR_SP] - (imm4 ? imm4 * 8 : 128));
|
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);
|
cpu->reg_set(cpu, MIPS_GPR_SP, cpu->gpr[MIPS_GPR_SP] + simm16);
|
||||||
break;
|
break;
|
||||||
case 4: { // SVRS
|
case 4: { // SVRS
|
||||||
|
// TBD!!! handle memory errors better
|
||||||
uint32_t astatic = 0;
|
uint32_t astatic = 0;
|
||||||
uint32_t i, temp;
|
uint32_t i, temp;
|
||||||
switch (aregs) {
|
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);
|
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 */
|
/* Fetch an instruction */
|
||||||
static int mips_fetch_instruction_word (cpu_mips_t * cpu,
|
static int mips_fetch_instruction_inner (cpu_mips_t * cpu,
|
||||||
m_va_t pc, mips_insn_t * insn)
|
m_va_t pc, mips_insn_t * insn, u_int size)
|
||||||
{
|
{
|
||||||
m_va_t exec_page;
|
m_va_t exec_page;
|
||||||
m_uint32_t offset;
|
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;
|
exec_page = pc & ~(m_va_t) MIPS_MIN_PAGE_IMASK;
|
||||||
if (unlikely (exec_page != cpu->njm_exec_page)) {
|
if (unlikely (exec_page != cpu->njm_exec_page)) {
|
||||||
cpu->njm_exec_ptr = cpu->mem_op_lookup (cpu, exec_page);
|
cpu->njm_exec_ptr = cpu->mem_op_lookup (cpu, exec_page);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cpu->njm_exec_ptr == NULL) {
|
if (cpu->njm_exec_ptr == NULL) {
|
||||||
//exception when fetching instruction
|
//exception when fetching instruction
|
||||||
return (1);
|
return (1);
|
||||||
@@ -96,6 +106,13 @@ static int mips_fetch_instruction_word (cpu_mips_t * cpu,
|
|||||||
cpu->njm_exec_page = exec_page;
|
cpu->njm_exec_page = exec_page;
|
||||||
offset = (pc & MIPS_MIN_PAGE_IMASK) >> 2;
|
offset = (pc & MIPS_MIN_PAGE_IMASK) >> 2;
|
||||||
*insn = vmtoh32 (cpu->njm_exec_ptr[offset]);
|
*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);
|
// printf ("(%08x) %08x\n", pc, *insn);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@@ -103,35 +120,28 @@ static int mips_fetch_instruction_word (cpu_mips_t * cpu,
|
|||||||
int mips_fetch_instruction (cpu_mips_t * cpu,
|
int mips_fetch_instruction (cpu_mips_t * cpu,
|
||||||
m_va_t pc, mips_insn_t * insn)
|
m_va_t pc, mips_insn_t * insn)
|
||||||
{
|
{
|
||||||
int res = mips_fetch_instruction_word(cpu, pc, insn);
|
int res;
|
||||||
cpu->insn_len = 4;
|
|
||||||
if (unlikely(res)) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
if (unlikely(cpu->is_mips16e)) {
|
if (unlikely(cpu->is_mips16e)) {
|
||||||
mips_insn_t i;
|
res = mips_fetch_instruction_inner(cpu, pc, insn, 2);
|
||||||
if (pc & 2) {
|
if (unlikely(res)) {
|
||||||
i = *insn >> 16;
|
return res;
|
||||||
} else {
|
|
||||||
i = *insn & 0xFFFF;
|
|
||||||
}
|
}
|
||||||
if (unlikely((i >> 11) == 0x1E || (i >> 11) == 3)) {
|
if (unlikely((*insn >> 11) == 0x1E || (*insn >> 11) == 3)) {
|
||||||
/* 4-byte extended instruction or jal(x) */
|
/* 4-byte extended instruction or jal(x): 2 more bytes needed */
|
||||||
if (pc & 2) {
|
mips_insn_t i;
|
||||||
/* 2 more bytes needed */
|
res = mips_fetch_instruction_inner(cpu, pc + 2, &i, 2);
|
||||||
res = mips_fetch_instruction_word(cpu, pc + 2, insn);
|
if (unlikely(res)) {
|
||||||
if (unlikely(res)) {
|
return res;
|
||||||
return res;
|
|
||||||
}
|
|
||||||
*insn = (i << 16) | (*insn & 0xFFFF);
|
|
||||||
} else {
|
|
||||||
*insn = (*insn << 16) | (*insn >> 16);
|
|
||||||
}
|
}
|
||||||
|
*insn = (*insn << 16) | i;
|
||||||
|
cpu->insn_len = 4;
|
||||||
} else {
|
} else {
|
||||||
/* 2-byte instruction */
|
/* 2-byte instruction */
|
||||||
*insn = i;
|
|
||||||
cpu->insn_len = 2;
|
cpu->insn_len = 2;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
res = mips_fetch_instruction_inner(cpu, pc, insn, 4);
|
||||||
|
cpu->insn_len = 4;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user