mirror of
https://github.com/holub/mame
synced 2025-07-05 09:57:47 +03:00
MIPS3 recompiler:
* added UML comments for common state variables * removed some unused fields * implemented LL/LLD/SC/SCD (only works single-processor for now)
This commit is contained in:
parent
4bc9630265
commit
2e8eddb648
@ -46,7 +46,7 @@ size_t mips3com_init(mips3_state *mips, mips3_flavor flavor, int bigendian, int
|
||||
|
||||
/* if no memory, return the amount needed */
|
||||
if (memory == NULL)
|
||||
return config->icache + config->dcache + (sizeof(mips->tlb_table[0]) * (1 << (MIPS3_MAX_PADDR_SHIFT - MIPS3_MIN_PAGE_SHIFT)));
|
||||
return sizeof(mips->tlb_table[0]) * (1 << (MIPS3_MAX_PADDR_SHIFT - MIPS3_MIN_PAGE_SHIFT));
|
||||
|
||||
/* initialize based on the config */
|
||||
memset(mips, 0, sizeof(*mips));
|
||||
@ -62,9 +62,7 @@ size_t mips3com_init(mips3_state *mips, mips3_flavor flavor, int bigendian, int
|
||||
mips->memory = *memory_get_accessors(ADDRESS_SPACE_PROGRAM, 32, mips->bigendian ? CPU_IS_BE : CPU_IS_LE);
|
||||
|
||||
/* allocate memory */
|
||||
mips->icache = memory;
|
||||
mips->dcache = (void *)((UINT8 *)memory + config->icache);
|
||||
mips->tlb_table = (void *)((UINT8 *)memory + config->dcache);
|
||||
mips->tlb_table = memory;
|
||||
|
||||
/* initialize the TLB state */
|
||||
for (tlbindex = 0; tlbindex < ARRAY_LENGTH(mips->tlb); tlbindex++)
|
||||
|
@ -186,7 +186,7 @@ struct _mips3_state
|
||||
/* COP registers */
|
||||
UINT64 cpr[3][32];
|
||||
UINT64 ccr[3][32];
|
||||
UINT8 cf[3][8];
|
||||
UINT32 llbit;
|
||||
|
||||
/* internal stuff */
|
||||
mips3_flavor flavor;
|
||||
@ -201,8 +201,6 @@ struct _mips3_state
|
||||
data_accessors memory;
|
||||
|
||||
/* cache memory */
|
||||
UINT32 * icache;
|
||||
UINT32 * dcache;
|
||||
size_t icache_size;
|
||||
size_t dcache_size;
|
||||
|
||||
|
@ -390,6 +390,49 @@ static void mips3_init(mips3_flavor flavor, int bigendian, int index, int clock,
|
||||
if (mips3->impstate->drcuml == NULL)
|
||||
fatalerror("Error initializing the UML");
|
||||
|
||||
/* add symbols for our stuff */
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->pc, sizeof(mips3->pc), "pc");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->icount, sizeof(mips3->icount), "icount");
|
||||
for (regnum = 0; regnum < 32; regnum++)
|
||||
{
|
||||
char buf[10];
|
||||
sprintf(buf, "r%d", regnum);
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->r[regnum], sizeof(mips3->r[regnum]), buf);
|
||||
sprintf(buf, "f%d", regnum);
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[1][regnum], sizeof(mips3->cpr[1][regnum]), buf);
|
||||
}
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->r[REG_LO], sizeof(mips3->r[REG_LO]), "lo");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->r[REG_HI], sizeof(mips3->r[REG_LO]), "hi");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_Index], sizeof(mips3->cpr[0][COP0_Index]), "Index");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_Random], sizeof(mips3->cpr[0][COP0_Random]), "Random");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_EntryLo0], sizeof(mips3->cpr[0][COP0_EntryLo0]), "EntryLo0");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_EntryLo1], sizeof(mips3->cpr[0][COP0_EntryLo1]), "EntryLo1");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_Context], sizeof(mips3->cpr[0][COP0_Context]), "Context");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_PageMask], sizeof(mips3->cpr[0][COP0_PageMask]), "PageMask");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_Wired], sizeof(mips3->cpr[0][COP0_Wired]), "Wired");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_BadVAddr], sizeof(mips3->cpr[0][COP0_BadVAddr]), "BadVAddr");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_Count], sizeof(mips3->cpr[0][COP0_Count]), "Count");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_EntryHi], sizeof(mips3->cpr[0][COP0_EntryHi]), "EntryHi");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_Compare], sizeof(mips3->cpr[0][COP0_Compare]), "Compare");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_Status], sizeof(mips3->cpr[0][COP0_Status]), "Status");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_Cause], sizeof(mips3->cpr[0][COP0_Cause]), "Cause");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_EPC], sizeof(mips3->cpr[0][COP0_EPC]), "EPC");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_PRId], sizeof(mips3->cpr[0][COP0_PRId]), "PRId");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_Config], sizeof(mips3->cpr[0][COP0_Config]), "Config");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_LLAddr], sizeof(mips3->cpr[0][COP0_LLAddr]), "LLAddr");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_XContext], sizeof(mips3->cpr[0][COP0_XContext]), "XContext");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_ECC], sizeof(mips3->cpr[0][COP0_ECC]), "ECC");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_CacheErr], sizeof(mips3->cpr[0][COP0_CacheErr]), "CacheErr");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_TagLo], sizeof(mips3->cpr[0][COP0_TagLo]), "TagLo");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_TagHi], sizeof(mips3->cpr[0][COP0_TagHi]), "TagHi");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_ErrorPC], sizeof(mips3->cpr[0][COP0_ErrorPC]), "ErrorPC");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->ccr[1][31], sizeof(mips3->cpr[1][31]), "fcr31");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->impstate->mode, sizeof(mips3->impstate->mode), "mode");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->impstate->arg0, sizeof(mips3->impstate->arg0), "arg0");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->impstate->arg1, sizeof(mips3->impstate->arg1), "arg1");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->impstate->numcycles, sizeof(mips3->impstate->numcycles), "numcycles");
|
||||
drcuml_symbol_add(mips3->impstate->drcuml, &mips3->impstate->fpmode, sizeof(mips3->impstate->fpmode), "fpmode");
|
||||
|
||||
/* initialize the front-end helper */
|
||||
if (SINGLE_INSTRUCTION_MODE)
|
||||
feconfig.max_sequence = 1;
|
||||
@ -1805,6 +1848,16 @@ static int generate_opcode(drcuml_block *block, compiler_state *compiler, const
|
||||
generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);
|
||||
return TRUE;
|
||||
|
||||
case 0x30: /* LL - MIPS II */
|
||||
UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL
|
||||
UML_CALLH(block, mips3->impstate->read32[mips3->impstate->mode >> 1]); // callh read32
|
||||
if (RTREG != 0)
|
||||
UML_DSEXT(block, R64(RTREG), IREG(0), DWORD); // dsext <rtreg>,i0
|
||||
UML_MOV(block, MEM(&mips3->llbit), IMM(1)); // mov [llbit],1
|
||||
if (!in_delay_slot)
|
||||
generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);
|
||||
return TRUE;
|
||||
|
||||
case 0x24: /* LBU - MIPS I */
|
||||
UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL
|
||||
UML_CALLH(block, mips3->impstate->read8[mips3->impstate->mode >> 1]); // callh read8
|
||||
@ -1841,6 +1894,16 @@ static int generate_opcode(drcuml_block *block, compiler_state *compiler, const
|
||||
generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);
|
||||
return TRUE;
|
||||
|
||||
case 0x34: /* LLD - MIPS III */
|
||||
UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL
|
||||
UML_CALLH(block, mips3->impstate->read64[mips3->impstate->mode >> 1]); // callh read64
|
||||
if (RTREG != 0)
|
||||
UML_DMOV(block, R64(RTREG), IREG(0)); // dmov <rtreg>,i0
|
||||
UML_MOV(block, MEM(&mips3->llbit), IMM(1)); // mov [llbit],1
|
||||
if (!in_delay_slot)
|
||||
generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);
|
||||
return TRUE;
|
||||
|
||||
case 0x22: /* LWL - MIPS I */
|
||||
UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL
|
||||
UML_SHL(block, IREG(1), IREG(0), IMM(3)); // shl i1,i0,3
|
||||
@ -1978,6 +2041,18 @@ static int generate_opcode(drcuml_block *block, compiler_state *compiler, const
|
||||
generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);
|
||||
return TRUE;
|
||||
|
||||
case 0x38: /* SC - MIPS II */
|
||||
UML_CMP(block, MEM(&mips3->llbit), IMM(0)); // cmp [llbit],0
|
||||
UML_JMPc(block, IF_E, skip = compiler->labelnum++); // je skip
|
||||
UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL
|
||||
UML_MOV(block, IREG(1), R32(RTREG)); // mov i1,<rtreg>
|
||||
UML_CALLH(block, mips3->impstate->write32[mips3->impstate->mode >> 1]); // callh write32
|
||||
UML_LABEL(block, skip); // skip:
|
||||
UML_DSEXT(block, R64(RTREG), MEM(&mips3->llbit), DWORD); // dsext <rtreg>,[llbit],dword
|
||||
if (!in_delay_slot)
|
||||
generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);
|
||||
return TRUE;
|
||||
|
||||
case 0x3f: /* SD - MIPS III */
|
||||
UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL
|
||||
UML_DMOV(block, IREG(1), R64(RTREG)); // dmov i1,<rtreg>
|
||||
@ -1986,6 +2061,18 @@ static int generate_opcode(drcuml_block *block, compiler_state *compiler, const
|
||||
generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);
|
||||
return TRUE;
|
||||
|
||||
case 0x3c: /* SCD - MIPS III */
|
||||
UML_CMP(block, MEM(&mips3->llbit), IMM(0)); // cmp [llbit],0
|
||||
UML_JMPc(block, IF_E, skip = compiler->labelnum++); // je skip
|
||||
UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL
|
||||
UML_DMOV(block, IREG(1), R64(RTREG)); // dmov i1,<rtreg>
|
||||
UML_CALLH(block, mips3->impstate->write64[mips3->impstate->mode >> 1]); // callh write64
|
||||
UML_LABEL(block, skip); // skip:
|
||||
UML_DSEXT(block, R64(RTREG), MEM(&mips3->llbit), DWORD); // dsext <rtreg>,[llbit],dword
|
||||
if (!in_delay_slot)
|
||||
generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);
|
||||
return TRUE;
|
||||
|
||||
case 0x2a: /* SWL - MIPS I */
|
||||
UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL
|
||||
UML_SHL(block, IREG(3), IREG(0), IMM(3)); // shl i3,i0,3
|
||||
@ -2104,10 +2191,6 @@ static int generate_opcode(drcuml_block *block, compiler_state *compiler, const
|
||||
|
||||
/* ----- unimplemented/illegal instructions ----- */
|
||||
|
||||
// case 0x30: /* LL - MIPS II */ logerror("mips3 Unhandled op: LL\n"); break;
|
||||
// case 0x34: /* LLD - MIPS III */ logerror("mips3 Unhandled op: LLD\n"); break;
|
||||
// case 0x38: /* SC - MIPS II */ logerror("mips3 Unhandled op: SC\n"); break;
|
||||
// case 0x3c: /* SCD - MIPS III */ logerror("mips3 Unhandled op: SCD\n"); break;
|
||||
// default: /* ??? */ invalid_instruction(op); break;
|
||||
}
|
||||
|
||||
@ -2844,6 +2927,7 @@ static int generate_cop0(drcuml_block *block, compiler_state *compiler, const op
|
||||
return TRUE;
|
||||
|
||||
case 0x18: /* ERET */
|
||||
UML_MOV(block, MEM(&mips3->llbit), IMM(0)); // mov [llbit],0
|
||||
UML_MOV(block, IREG(0), CPR032(COP0_Status)); // mov i0,[Status]
|
||||
UML_TEST(block, IREG(0), IMM(SR_ERL)); // test i0,SR_ERL
|
||||
UML_JMPc(block, IF_NZ, skip = compiler->labelnum++); // jmp skip,nz
|
||||
|
@ -168,13 +168,18 @@ int mips3fe_describe(void *param, opcode_desc *desc)
|
||||
case 0x2c: /* SDL */
|
||||
case 0x2d: /* SDR */
|
||||
case 0x2e: /* SWR */
|
||||
case 0x38: /* SC */
|
||||
case 0x3c: /* SCD */
|
||||
case 0x3f: /* SD */
|
||||
desc->regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
|
||||
desc->flags |= OPFLAG_WRITES_MEMORY | OPFLAG_CAN_CAUSE_EXCEPTION;
|
||||
return TRUE;
|
||||
|
||||
case 0x38: /* SC */
|
||||
case 0x3c: /* SCD */
|
||||
desc->regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
|
||||
desc->regout[0] |= REGFLAG_R(RTREG);
|
||||
desc->flags |= OPFLAG_WRITES_MEMORY | OPFLAG_CAN_CAUSE_EXCEPTION;
|
||||
return TRUE;
|
||||
|
||||
case 0x31: /* LWC1 */
|
||||
case 0x35: /* LDC1 */
|
||||
desc->regin[0] |= REGFLAG_R(RSREG);
|
||||
|
Loading…
Reference in New Issue
Block a user