--- trunk/src/cpus/cpu_mips_coproc.c 2007/10/08 16:20:32 29 +++ trunk/src/cpus/cpu_mips_coproc.c 2007/10/08 16:20:40 30 @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: cpu_mips_coproc.c,v 1.49 2006/07/21 20:39:40 debug Exp $ + * $Id: cpu_mips_coproc.c,v 1.53 2006/08/11 17:43:30 debug Exp $ * * Emulation of MIPS coprocessors. */ @@ -536,7 +536,10 @@ int non4kpages = 0; uint64_t topbit = 1, fillmask = 0xffffff0000000000ULL; - if (cpu->cd.mips.cpu_type.mmu_model == MMU10K) { + if (cpu->is_32bit) { + topbit = 0x80000000; + fillmask = 0xffffffff00000000ULL; + } else if (cpu->cd.mips.cpu_type.mmu_model == MMU10K) { topbit <<= 43; fillmask <<= 4; } else { @@ -1201,7 +1204,7 @@ /* bc1f, bc1t, bc1fl, bc1tl: */ if ((function & 0x03e00000) == 0x01000000) { - int nd, tf, imm, cond_true; + int nd, tf, imm; char *instr_mnem; /* cc are bits 20..18: */ @@ -1224,36 +1227,10 @@ if (unassemble_only) return 1; - if (cpu->delay_slot) { - fatal("%s: jump inside a jump's delay slot, " - "or similar. TODO\n", instr_mnem); - cpu->running = 0; - return 1; - } - - /* Both the FCCR and FCSR contain condition code bits... */ - if (cc == 0) - cond_true = (cp->fcr[MIPS_FPU_FCSR] >> - MIPS_FCSR_FCC0_SHIFT) & 1; - else - cond_true = (cp->fcr[MIPS_FPU_FCSR] >> - (MIPS_FCSR_FCC1_SHIFT + cc-1)) & 1; - - if (!tf) - cond_true = !cond_true; - - if (cond_true) { - cpu->delay_slot = TO_BE_DELAYED; - cpu->delay_jmpaddr = cpu->pc + (imm << 2); - } else { - /* "likely": */ - if (nd) { - /* nullify the delay slot */ - cpu->cd.mips.nullify_next = 1; - } - } - - return 1; + fatal("INTERNAL ERROR: MIPS coprocessor branches should not" + " be implemented in cpu_mips_coproc.c, but in" + " cpu_mips_instr.c!\n"); + exit(1); } /* add.fmt: Floating-point add */ @@ -1467,19 +1444,13 @@ R2K3K_INDEX_SHIFT; if (i >= cp->nr_of_tlbs) { /* TODO: exception? */ - fatal("warning: tlbr from index %i (too " - "high)\n", i); + fatal("[ warning: tlbr from index %i (too " + "high) ]\n", i); return; } - /* - * TODO: Hm. Earlier I had an & ~0x3f on the high - * assignment and an & ~0xff on the lo0 assignment. - * I wonder why. - */ - - cp->reg[COP0_ENTRYHI] = cp->tlbs[i].hi; /* & ~0x3f; */ - cp->reg[COP0_ENTRYLO0] = cp->tlbs[i].lo0;/* & ~0xff; */ + cp->reg[COP0_ENTRYHI] = cp->tlbs[i].hi; + cp->reg[COP0_ENTRYLO0] = cp->tlbs[i].lo0; } else { /* R4000: */ i = cp->reg[COP0_INDEX] & INDEX_MASK; @@ -2098,108 +2069,73 @@ /* TLB operations and other things: */ if (cp->coproc_nr == 0) { + if (!unassemble_only) { + fatal("FATAL INTERNAL ERROR: Should be implemented" + " with dyntrans instead.\n"); + exit(1); + } + op = (function) & 0xff; switch (co_bit) { case 1: switch (op) { case COP0_TLBR: /* Read indexed TLB entry */ - if (unassemble_only) { - debug("tlbr\n"); - return; - } - coproc_tlbpr(cpu, 1); + debug("tlbr\n"); return; case COP0_TLBWI: /* Write indexed */ case COP0_TLBWR: /* Write random */ - if (unassemble_only) { - if (op == COP0_TLBWI) - debug("tlbwi"); - else - debug("tlbwr"); - if (!running) { - debug("\n"); - return; - } - debug("\tindex=%08llx", - (long long)cp->reg[COP0_INDEX]); - debug(", random=%08llx", - (long long)cp->reg[COP0_RANDOM]); - debug(", mask=%016llx", - (long long)cp->reg[COP0_PAGEMASK]); - debug(", hi=%016llx", - (long long)cp->reg[COP0_ENTRYHI]); - debug(", lo0=%016llx", - (long long)cp->reg[COP0_ENTRYLO0]); - debug(", lo1=%016llx\n", - (long long)cp->reg[COP0_ENTRYLO1]); + if (op == COP0_TLBWI) + debug("tlbwi"); + else + debug("tlbwr"); + if (!running) { + debug("\n"); return; } - coproc_tlbwri(cpu, op == COP0_TLBWR); + debug("\tindex=%08llx", + (long long)cp->reg[COP0_INDEX]); + debug(", random=%08llx", + (long long)cp->reg[COP0_RANDOM]); + debug(", mask=%016llx", + (long long)cp->reg[COP0_PAGEMASK]); + debug(", hi=%016llx", + (long long)cp->reg[COP0_ENTRYHI]); + debug(", lo0=%016llx", + (long long)cp->reg[COP0_ENTRYLO0]); + debug(", lo1=%016llx\n", + (long long)cp->reg[COP0_ENTRYLO1]); return; case COP0_TLBP: /* Probe TLB for matching entry */ - if (unassemble_only) { - debug("tlbp\n"); - return; - } - coproc_tlbpr(cpu, 0); + debug("tlbp\n"); return; case COP0_RFE: /* R2000/R3000 only: Return from Exception */ - if (unassemble_only) { - debug("rfe\n"); - return; - } - fatal("Internal error (rfe): Should be " - "implemented in dyntrans instead.\n"); - exit(1); + debug("rfe\n"); + return; case COP0_ERET: /* R4000: Return from exception */ - if (unassemble_only) { - debug("eret\n"); - return; - } - fatal("Internal error (eret): Should be " - "implemented in dyntrans instead.\n"); - exit(1); + debug("eret\n"); + return; case COP0_DERET: - if (unassemble_only) { - debug("deret\n"); - return; + debug("deret\n"); + return; + case COP0_WAIT: + { + int code = (function >> 6) & 0x7ffff; + debug("wait"); + if (code > 0) + debug("\t0x%x", code); + debug("\n"); } - /* - * According to the MIPS64 manual, deret - * loads PC from the DEPC cop0 register, and - * jumps there immediately. No delay slot. - * - * TODO: This instruction is only available - * if the processor is in debug mode. (What - * does that mean?) TODO: This instruction - * is undefined in a delay slot. - */ - cpu->pc = cp->reg[COP0_DEPC]; - cpu->delay_slot = 0; - cp->reg[COP0_STATUS] &= ~STATUS_EXL; return; case COP0_STANDBY: - if (unassemble_only) { - debug("standby\n"); - return; - } - /* TODO: Hm. Do something here? */ + debug("standby\n"); return; case COP0_SUSPEND: - if (unassemble_only) { - debug("suspend\n"); - return; - } - /* TODO: Hm. Do something here? */ + debug("suspend\n"); return; case COP0_HIBERNATE: - if (unassemble_only) { - debug("hibernate\n"); - return; - } - /* TODO: Hm. Do something here? */ + debug("hibernate\n"); return; default: ; @@ -2219,17 +2155,6 @@ return; } - /* TODO: RM5200 idle (?) */ - if ((cp->coproc_nr==0 || cp->coproc_nr==3) && function == 0x02000020) { - if (unassemble_only) { - debug("idle(?)\n"); /* TODO */ - return; - } - - /* Idle? TODO */ - return; - } - if (unassemble_only) { debug("cop%i\t0x%08x (unimplemented)\n", cpnr, (int)function); return;