mirror of
https://github.com/holub/mame
synced 2025-05-21 13:18:56 +03:00
DRC frontends must do their own opcode fetching unfortunately. Updated all
DRC cores to do this. Also tweaked a few oddities in the SH2 DRC.
This commit is contained in:
parent
eff9223966
commit
aad099ad00
@ -287,25 +287,6 @@ static opcode_desc *describe_one(drcfe_state *drcfe, offs_t curpc, const opcode_
|
||||
desc->physpc = curpc;
|
||||
desc->targetpc = BRANCH_TARGET_DYNAMIC;
|
||||
|
||||
/* compute the physical PC */
|
||||
if (drcfe->translate != NULL && !(*drcfe->translate)(drcfe->device, ADDRESS_SPACE_PROGRAM, TRANSLATE_FETCH, &desc->physpc))
|
||||
{
|
||||
/* uh-oh: a page fault; leave the description empty and just if this is the first instruction, leave it empty and */
|
||||
/* mark as needing to validate; otherwise, just end the sequence here */
|
||||
desc->flags |= OPFLAG_VALIDATE_TLB | OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_COMPILER_PAGE_FAULT | OPFLAG_VIRTUAL_NOOP | OPFLAG_END_SEQUENCE;
|
||||
return desc;
|
||||
}
|
||||
|
||||
/* get a pointer to the physical address */
|
||||
desc->opptr.v = memory_decrypted_read_ptr(drcfe->program, desc->physpc ^ drcfe->codexor);
|
||||
assert(desc->opptr.v != NULL);
|
||||
if (desc->opptr.v == NULL)
|
||||
{
|
||||
/* address is unmapped; report it as such */
|
||||
desc->flags |= OPFLAG_VALIDATE_TLB | OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_COMPILER_UNMAPPED | OPFLAG_VIRTUAL_NOOP | OPFLAG_END_SEQUENCE;
|
||||
return desc;
|
||||
}
|
||||
|
||||
/* call the callback to describe an instruction */
|
||||
if (!(*drcfe->describe)(drcfe->param, desc, prevdesc))
|
||||
{
|
||||
|
@ -105,14 +105,13 @@ struct _opcode_desc
|
||||
offs_t physpc; /* physical PC of this opcode */
|
||||
offs_t targetpc; /* target PC if we are a branch, or BRANCH_TARGET_DYNAMIC */
|
||||
|
||||
/* pointer to the current opcode */
|
||||
/* copy of up to 16 bytes of opcode */
|
||||
union
|
||||
{
|
||||
void * v;
|
||||
UINT8 * b;
|
||||
UINT16 * w;
|
||||
UINT32 * l;
|
||||
UINT64 * q;
|
||||
UINT8 b[16];
|
||||
UINT16 w[8];
|
||||
UINT32 l[4];
|
||||
UINT64 q[2];
|
||||
} opptr; /* pointer to opcode memory */
|
||||
|
||||
/* information about this instruction's execution */
|
||||
|
@ -1471,8 +1471,9 @@ static void generate_checksum_block(mips3_state *mips3, drcuml_block *block, com
|
||||
{
|
||||
if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP))
|
||||
{
|
||||
UML_LOAD(block, IREG(0), seqhead->opptr.l, IMM(0), DWORD); // load i0,*opptr,0,dword
|
||||
UML_CMP(block, IREG(0), IMM(*seqhead->opptr.l)); // cmp i0,*opptr
|
||||
void *base = memory_decrypted_read_ptr(mips3->program, seqhead->physpc);
|
||||
UML_LOAD(block, IREG(0), base, IMM(0), DWORD); // load i0,base,0,dword
|
||||
UML_CMP(block, IREG(0), IMM(seqhead->opptr.l[0])); // cmp i0,opptr[0]
|
||||
UML_EXHc(block, IF_NE, mips3->impstate->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc
|
||||
}
|
||||
}
|
||||
@ -1484,20 +1485,23 @@ static void generate_checksum_block(mips3_state *mips3, drcuml_block *block, com
|
||||
for (curdesc = seqhead->next; curdesc != seqlast->next; curdesc = curdesc->next)
|
||||
if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
|
||||
{
|
||||
UML_LOAD(block, IREG(0), curdesc->opptr.l, IMM(0), DWORD); // load i0,*opptr,0,dword
|
||||
UML_CMP(block, IREG(0), IMM(*curdesc->opptr.l)); // cmp i0,*opptr
|
||||
void *base = memory_decrypted_read_ptr(mips3->program, seqhead->physpc);
|
||||
UML_LOAD(block, IREG(0), base, IMM(0), DWORD); // load i0,base,0,dword
|
||||
UML_CMP(block, IREG(0), IMM(curdesc->opptr.l[0])); // cmp i0,opptr[0]
|
||||
UML_EXHc(block, IF_NE, mips3->impstate->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc
|
||||
}
|
||||
#else
|
||||
UINT32 sum = 0;
|
||||
UML_LOAD(block, IREG(0), seqhead->opptr.l, IMM(0), DWORD); // load i0,*opptr,0,dword
|
||||
sum += *seqhead->opptr.l;
|
||||
void *base = memory_decrypted_read_ptr(mips3->program, seqhead->physpc);
|
||||
UML_LOAD(block, IREG(0), base, IMM(0), DWORD); // load i0,base,0,dword
|
||||
sum += seqhead->opptr.l[0];
|
||||
for (curdesc = seqhead->next; curdesc != seqlast->next; curdesc = curdesc->next)
|
||||
if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
|
||||
{
|
||||
UML_LOAD(block, IREG(1), curdesc->opptr.l, IMM(0), DWORD); // load i1,*opptr,dword
|
||||
base = memory_decrypted_read_ptr(mips3->program, curdesc->physpc);
|
||||
UML_LOAD(block, IREG(1), base, IMM(0), DWORD); // load i1,base,dword
|
||||
UML_ADD(block, IREG(0), IREG(0), IREG(1)); // add i0,i0,i1
|
||||
sum += *curdesc->opptr.l;
|
||||
sum += curdesc->opptr.l[0];
|
||||
}
|
||||
UML_CMP(block, IREG(0), IMM(sum)); // cmp i0,sum
|
||||
UML_EXHc(block, IF_NE, mips3->impstate->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc
|
||||
@ -1518,7 +1522,7 @@ static void generate_sequence_instruction(mips3_state *mips3, drcuml_block *bloc
|
||||
|
||||
/* add an entry for the log */
|
||||
if (LOG_UML && !(desc->flags & OPFLAG_VIRTUAL_NOOP))
|
||||
log_add_disasm_comment(mips3, block, desc->pc, *desc->opptr.l);
|
||||
log_add_disasm_comment(mips3, block, desc->pc, desc->opptr.l[0]);
|
||||
|
||||
/* set the PC map variable */
|
||||
expc = (desc->flags & OPFLAG_IN_DELAY_SLOT) ? desc->pc - 3 : desc->pc;
|
||||
@ -1529,7 +1533,7 @@ static void generate_sequence_instruction(mips3_state *mips3, drcuml_block *bloc
|
||||
|
||||
/* is this a hotspot? */
|
||||
for (hotnum = 0; hotnum < MIPS3_MAX_HOTSPOTS; hotnum++)
|
||||
if (mips3->impstate->hotspot[hotnum].pc != 0 && desc->pc == mips3->impstate->hotspot[hotnum].pc && *desc->opptr.l == mips3->impstate->hotspot[hotnum].opcode)
|
||||
if (mips3->impstate->hotspot[hotnum].pc != 0 && desc->pc == mips3->impstate->hotspot[hotnum].pc && desc->opptr.l[0] == mips3->impstate->hotspot[hotnum].opcode)
|
||||
{
|
||||
compiler->cycles += mips3->impstate->hotspot[hotnum].cycles;
|
||||
break;
|
||||
@ -1619,7 +1623,7 @@ static void generate_sequence_instruction(mips3_state *mips3, drcuml_block *bloc
|
||||
if (!generate_opcode(mips3, block, compiler, desc))
|
||||
{
|
||||
UML_MOV(block, MEM(&mips3->pc), IMM(desc->pc)); // mov [pc],desc->pc
|
||||
UML_MOV(block, MEM(&mips3->impstate->arg0), IMM(*desc->opptr.l)); // mov [arg0],desc->opptr.l
|
||||
UML_MOV(block, MEM(&mips3->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
|
||||
UML_CALLC(block, cfunc_unimplemented, mips3); // callc cfunc_unimplemented
|
||||
}
|
||||
}
|
||||
@ -1633,7 +1637,7 @@ static void generate_sequence_instruction(mips3_state *mips3, drcuml_block *bloc
|
||||
static void generate_delay_slot_and_branch(mips3_state *mips3, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT8 linkreg)
|
||||
{
|
||||
compiler_state compiler_temp = *compiler;
|
||||
UINT32 op = *desc->opptr.l;
|
||||
UINT32 op = desc->opptr.l[0];
|
||||
|
||||
/* fetch the target register if dynamic, in case it is modified by the delay slot */
|
||||
if (desc->targetpc == BRANCH_TARGET_DYNAMIC)
|
||||
@ -1682,7 +1686,7 @@ static void generate_delay_slot_and_branch(mips3_state *mips3, drcuml_block *blo
|
||||
static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
|
||||
{
|
||||
int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0);
|
||||
UINT32 op = *desc->opptr.l;
|
||||
UINT32 op = desc->opptr.l[0];
|
||||
UINT8 opswitch = op >> 26;
|
||||
drcuml_codelabel skip;
|
||||
|
||||
@ -2204,7 +2208,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta
|
||||
|
||||
static int generate_special(mips3_state *mips3, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
|
||||
{
|
||||
UINT32 op = *desc->opptr.l;
|
||||
UINT32 op = desc->opptr.l[0];
|
||||
UINT8 opswitch = op & 63;
|
||||
|
||||
switch (opswitch)
|
||||
@ -2597,7 +2601,7 @@ static int generate_special(mips3_state *mips3, drcuml_block *block, compiler_st
|
||||
|
||||
static int generate_regimm(mips3_state *mips3, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
|
||||
{
|
||||
UINT32 op = *desc->opptr.l;
|
||||
UINT32 op = desc->opptr.l[0];
|
||||
UINT8 opswitch = RTREG;
|
||||
drcuml_codelabel skip;
|
||||
|
||||
@ -2675,7 +2679,7 @@ static int generate_regimm(mips3_state *mips3, drcuml_block *block, compiler_sta
|
||||
|
||||
static int generate_idt(mips3_state *mips3, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
|
||||
{
|
||||
UINT32 op = *desc->opptr.l;
|
||||
UINT32 op = desc->opptr.l[0];
|
||||
UINT8 opswitch = op & 0x1f;
|
||||
|
||||
/* only enabled on IDT processors */
|
||||
@ -2843,7 +2847,7 @@ static int generate_get_cop0_reg(mips3_state *mips3, drcuml_block *block, compil
|
||||
|
||||
static int generate_cop0(mips3_state *mips3, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
|
||||
{
|
||||
UINT32 op = *desc->opptr.l;
|
||||
UINT32 op = desc->opptr.l[0];
|
||||
UINT8 opswitch = RSREG;
|
||||
int skip;
|
||||
|
||||
@ -2969,7 +2973,7 @@ static int generate_cop0(mips3_state *mips3, drcuml_block *block, compiler_state
|
||||
|
||||
static int generate_cop1(mips3_state *mips3, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
|
||||
{
|
||||
UINT32 op = *desc->opptr.l;
|
||||
UINT32 op = desc->opptr.l[0];
|
||||
drcuml_codelabel skip;
|
||||
int condition;
|
||||
|
||||
@ -3346,7 +3350,7 @@ static int generate_cop1(mips3_state *mips3, drcuml_block *block, compiler_state
|
||||
static int generate_cop1x(mips3_state *mips3, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
|
||||
{
|
||||
int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0);
|
||||
UINT32 op = *desc->opptr.l;
|
||||
UINT32 op = desc->opptr.l[0];
|
||||
|
||||
if (mips3->impstate->drcoptions & MIPS3DRC_STRICT_COP1)
|
||||
{
|
||||
@ -3591,7 +3595,7 @@ static void log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, i
|
||||
if (desclist->flags & OPFLAG_VIRTUAL_NOOP)
|
||||
strcpy(buffer, "<virtual nop>");
|
||||
else
|
||||
dasmmips3(buffer, desclist->pc, *desclist->opptr.l);
|
||||
dasmmips3(buffer, desclist->pc, desclist->opptr.l[0]);
|
||||
#else
|
||||
strcpy(buffer, "???");
|
||||
#endif
|
||||
|
@ -42,14 +42,26 @@ static int describe_instruction_cop2(mips3_state *mips, UINT32 op, opcode_desc *
|
||||
int mips3fe_describe(void *param, opcode_desc *desc, const opcode_desc *prev)
|
||||
{
|
||||
mips3_state *mips = param;
|
||||
UINT32 op = *desc->opptr.l;
|
||||
UINT8 opswitch = op >> 26;
|
||||
UINT32 op, opswitch;
|
||||
|
||||
/* compute the physical PC */
|
||||
if (!mips3com_translate_address(mips, ADDRESS_SPACE_PROGRAM, TRANSLATE_FETCH, &desc->physpc))
|
||||
{
|
||||
/* uh-oh: a page fault; leave the description empty and just if this is the first instruction, leave it empty and */
|
||||
/* mark as needing to validate; otherwise, just end the sequence here */
|
||||
desc->flags |= OPFLAG_VALIDATE_TLB | OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_COMPILER_PAGE_FAULT | OPFLAG_VIRTUAL_NOOP | OPFLAG_END_SEQUENCE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* fetch the opcode */
|
||||
op = desc->opptr.l[0] = memory_decrypted_read_dword(mips->program, desc->physpc);
|
||||
|
||||
/* all instructions are 4 bytes and default to a single cycle each */
|
||||
desc->length = 4;
|
||||
desc->cycles = 1;
|
||||
|
||||
/* parse the instruction */
|
||||
opswitch = op >> 26;
|
||||
switch (opswitch)
|
||||
{
|
||||
case 0x00: /* SPECIAL */
|
||||
|
@ -2060,8 +2060,9 @@ static void generate_checksum_block(powerpc_state *ppc, drcuml_block *block, com
|
||||
{
|
||||
if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP))
|
||||
{
|
||||
UML_LOAD(block, IREG(0), seqhead->opptr.l, IMM(0), DWORD); // load i0,*opptr,dword
|
||||
UML_CMP(block, IREG(0), IMM(*seqhead->opptr.l)); // cmp i0,*opptr
|
||||
void *base = memory_decrypted_read_ptr(ppc->program, seqhead->physpc);
|
||||
UML_LOAD(block, IREG(0), base, IMM(0), DWORD); // load i0,base,dword
|
||||
UML_CMP(block, IREG(0), IMM(seqhead->opptr.l[0])); // cmp i0,*opptr
|
||||
UML_EXHc(block, IF_NE, ppc->impstate->nocode, IMM(seqhead->pc)); // exne nocode,seqhead->pc
|
||||
}
|
||||
}
|
||||
@ -2073,20 +2074,23 @@ static void generate_checksum_block(powerpc_state *ppc, drcuml_block *block, com
|
||||
for (curdesc = seqhead->next; curdesc != seqlast->next; curdesc = curdesc->next)
|
||||
if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
|
||||
{
|
||||
UML_LOAD(block, IREG(0), curdesc->opptr.l, IMM(0), DWORD); // load i0,*opptr,dword
|
||||
UML_CMP(block, IREG(0), IMM(*curdesc->opptr.l)); // cmp i0,*opptr
|
||||
void *base = memory_decrypted_read_ptr(ppc->program, seqhead->physpc);
|
||||
UML_LOAD(block, IREG(0), base, IMM(0), DWORD); // load i0,base,dword
|
||||
UML_CMP(block, IREG(0), IMM(curdesc->opptr.l[0])); // cmp i0,*opptr
|
||||
UML_EXHc(block, IF_NE, ppc->impstate->nocode, IMM(seqhead->pc)); // exne nocode,seqhead->pc
|
||||
}
|
||||
#else
|
||||
UINT32 sum = 0;
|
||||
UML_LOAD(block, IREG(0), seqhead->opptr.l, IMM(0), DWORD); // load i0,*opptr,dword
|
||||
sum += *seqhead->opptr.l;
|
||||
void *base = memory_decrypted_read_ptr(ppc->program, seqhead->physpc);
|
||||
UML_LOAD(block, IREG(0), base, IMM(0), DWORD); // load i0,base,dword
|
||||
sum += seqhead->opptr.l[0];
|
||||
for (curdesc = seqhead->next; curdesc != seqlast->next; curdesc = curdesc->next)
|
||||
if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
|
||||
{
|
||||
UML_LOAD(block, IREG(1), curdesc->opptr.l, IMM(0), DWORD); // load i1,*opptr,dword
|
||||
base = memory_decrypted_read_ptr(ppc->program, curdesc->physpc);
|
||||
UML_LOAD(block, IREG(1), base, IMM(0), DWORD); // load i1,base,dword
|
||||
UML_ADD(block, IREG(0), IREG(0), IREG(1)); // add i0,i0,i1
|
||||
sum += *curdesc->opptr.l;
|
||||
sum += curdesc->opptr.l[0];
|
||||
}
|
||||
UML_CMP(block, IREG(0), IMM(sum)); // cmp i0,sum
|
||||
UML_EXHc(block, IF_NE, ppc->impstate->nocode, IMM(seqhead->pc)); // exne nocode,seqhead->pc
|
||||
@ -2106,7 +2110,7 @@ static void generate_sequence_instruction(powerpc_state *ppc, drcuml_block *bloc
|
||||
|
||||
/* add an entry for the log */
|
||||
if (LOG_UML && !(desc->flags & OPFLAG_VIRTUAL_NOOP))
|
||||
log_add_disasm_comment(block, desc->pc, *desc->opptr.l);
|
||||
log_add_disasm_comment(block, desc->pc, desc->opptr.l[0]);
|
||||
|
||||
/* set the PC map variable */
|
||||
UML_MAPVAR(block, MAPVAR_PC, desc->pc); // mapvar PC,desc->pc
|
||||
@ -2116,7 +2120,7 @@ static void generate_sequence_instruction(powerpc_state *ppc, drcuml_block *bloc
|
||||
|
||||
/* is this a hotspot? */
|
||||
for (hotnum = 0; hotnum < PPC_MAX_HOTSPOTS; hotnum++)
|
||||
if (ppc->impstate->hotspot[hotnum].pc != 0 && desc->pc == ppc->impstate->hotspot[hotnum].pc && *desc->opptr.l == ppc->impstate->hotspot[hotnum].opcode)
|
||||
if (ppc->impstate->hotspot[hotnum].pc != 0 && desc->pc == ppc->impstate->hotspot[hotnum].pc && desc->opptr.l[0] == ppc->impstate->hotspot[hotnum].opcode)
|
||||
{
|
||||
compiler->cycles += ppc->impstate->hotspot[hotnum].cycles;
|
||||
break;
|
||||
@ -2210,7 +2214,7 @@ static void generate_sequence_instruction(powerpc_state *ppc, drcuml_block *bloc
|
||||
if (!generate_opcode(ppc, block, compiler, desc))
|
||||
{
|
||||
UML_MOV(block, MEM(&ppc->pc), IMM(desc->pc)); // mov [pc],desc->pc
|
||||
UML_MOV(block, MEM(&ppc->impstate->arg0), IMM(*desc->opptr.l)); // mov [arg0],*desc->opptr.l
|
||||
UML_MOV(block, MEM(&ppc->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],*desc->opptr.l
|
||||
UML_CALLC(block, cfunc_unimplemented, ppc); // callc cfunc_unimplemented,ppc
|
||||
}
|
||||
}
|
||||
@ -2361,7 +2365,7 @@ static void generate_branch_bo(powerpc_state *ppc, drcuml_block *block, compiler
|
||||
|
||||
static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
|
||||
{
|
||||
UINT32 op = *desc->opptr.l;
|
||||
UINT32 op = desc->opptr.l[0];
|
||||
UINT32 opswitch = op >> 26;
|
||||
int regnum;
|
||||
|
||||
@ -2745,7 +2749,7 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta
|
||||
|
||||
static int generate_instruction_13(powerpc_state *ppc, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
|
||||
{
|
||||
UINT32 op = *desc->opptr.l;
|
||||
UINT32 op = desc->opptr.l[0];
|
||||
UINT32 opswitch = (op >> 1) & 0x3ff;
|
||||
|
||||
switch (opswitch)
|
||||
@ -2882,7 +2886,7 @@ static int generate_instruction_13(powerpc_state *ppc, drcuml_block *block, comp
|
||||
|
||||
static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
|
||||
{
|
||||
UINT32 op = *desc->opptr.l;
|
||||
UINT32 op = desc->opptr.l[0];
|
||||
UINT32 opswitch = (op >> 1) & 0x3ff;
|
||||
int item;
|
||||
|
||||
@ -3730,7 +3734,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp
|
||||
|
||||
static int generate_instruction_3b(powerpc_state *ppc, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
|
||||
{
|
||||
UINT32 op = *desc->opptr.l;
|
||||
UINT32 op = desc->opptr.l[0];
|
||||
UINT32 opswitch = (op >> 1) & 0x1f;
|
||||
|
||||
switch (opswitch)
|
||||
@ -3822,7 +3826,7 @@ static int generate_instruction_3b(powerpc_state *ppc, drcuml_block *block, comp
|
||||
|
||||
static int generate_instruction_3f(powerpc_state *ppc, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
|
||||
{
|
||||
UINT32 op = *desc->opptr.l;
|
||||
UINT32 op = desc->opptr.l[0];
|
||||
UINT32 opswitch = (op >> 1) & 0x3ff;
|
||||
|
||||
if (opswitch & 0x10)
|
||||
@ -4169,7 +4173,7 @@ static void log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, i
|
||||
if (desclist->flags & OPFLAG_VIRTUAL_NOOP)
|
||||
strcpy(buffer, "<virtual nop>");
|
||||
else
|
||||
ppc_dasm_one(buffer, desclist->pc, *desclist->opptr.l);
|
||||
ppc_dasm_one(buffer, desclist->pc, desclist->opptr.l[0]);
|
||||
}
|
||||
else
|
||||
strcpy(buffer, "???");
|
||||
|
@ -130,15 +130,27 @@ INLINE int is_603_class(const powerpc_state *ppc)
|
||||
int ppcfe_describe(void *param, opcode_desc *desc, const opcode_desc *prev)
|
||||
{
|
||||
powerpc_state *ppc = param;
|
||||
UINT32 op = *desc->opptr.l;
|
||||
UINT32 opswitch = op >> 26;
|
||||
UINT32 op, opswitch;
|
||||
int regnum;
|
||||
|
||||
/* compute the physical PC */
|
||||
if (!ppccom_translate_address(ppc, ADDRESS_SPACE_PROGRAM, TRANSLATE_FETCH, &desc->physpc))
|
||||
{
|
||||
/* uh-oh: a page fault; leave the description empty and just if this is the first instruction, leave it empty and */
|
||||
/* mark as needing to validate; otherwise, just end the sequence here */
|
||||
desc->flags |= OPFLAG_VALIDATE_TLB | OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_COMPILER_PAGE_FAULT | OPFLAG_VIRTUAL_NOOP | OPFLAG_END_SEQUENCE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* fetch the opcode */
|
||||
op = desc->opptr.l[0] = memory_decrypted_read_dword(ppc->program, desc->physpc);
|
||||
|
||||
/* all instructions are 4 bytes and default to a single cycle each */
|
||||
desc->length = 4;
|
||||
desc->cycles = 1;
|
||||
|
||||
/* parse the instruction */
|
||||
opswitch = op >> 26;
|
||||
switch (opswitch)
|
||||
{
|
||||
case 0x02: /* TDI - 64-bit only */
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "cpu/drcumlsh.h"
|
||||
#endif
|
||||
|
||||
#define SH2_CODE_XOR(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(2,0))
|
||||
|
||||
typedef struct _irq_entry irq_entry;
|
||||
struct _irq_entry
|
||||
{
|
||||
|
@ -1376,7 +1376,7 @@ static void log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, i
|
||||
if (desclist->flags & OPFLAG_VIRTUAL_NOOP)
|
||||
strcpy(buffer, "<virtual nop>");
|
||||
else
|
||||
DasmSH2(buffer, desclist->pc, *desclist->opptr.w);
|
||||
DasmSH2(buffer, desclist->pc, desclist->opptr.w[0]);
|
||||
#else
|
||||
strcpy(buffer, "???");
|
||||
#endif
|
||||
@ -1505,8 +1505,9 @@ static void generate_checksum_block(SH2 *sh2, drcuml_block *block, compiler_stat
|
||||
{
|
||||
if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP))
|
||||
{
|
||||
UML_LOAD(block, IREG(0), seqhead->opptr.l, IMM(0), DWORD); // load i0,*opptr,0,dword
|
||||
UML_CMP(block, IREG(0), IMM(*seqhead->opptr.l)); // cmp i0,*opptr
|
||||
void *base = memory_decrypted_read_ptr(sh2->program, SH2_CODE_XOR(seqhead->physpc));
|
||||
UML_LOAD(block, IREG(0), base, IMM(0), WORD); // load i0,base,word
|
||||
UML_CMP(block, IREG(0), IMM(seqhead->opptr.w[0])); // cmp i0,*opptr
|
||||
UML_EXHc(block, IF_NE, sh2->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc
|
||||
}
|
||||
}
|
||||
@ -1518,20 +1519,23 @@ static void generate_checksum_block(SH2 *sh2, drcuml_block *block, compiler_stat
|
||||
for (curdesc = seqhead->next; curdesc != seqlast->next; curdesc = curdesc->next)
|
||||
if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
|
||||
{
|
||||
base = memory_decrypted_read_ptr(sh2->program, SH2_CODE_XOR(curdesc->physpc));
|
||||
UML_LOAD(block, IREG(0), curdesc->opptr.w, IMM(0), WORD); // load i0,*opptr,0,word
|
||||
UML_CMP(block, IREG(0), IMM(*curdesc->opptr.w)); // cmp i0,*opptr
|
||||
UML_CMP(block, IREG(0), IMM(curdesc->opptr.w[0])); // cmp i0,*opptr
|
||||
UML_EXHc(block, IF_NE, sh2->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc
|
||||
}
|
||||
#else
|
||||
UINT32 sum = 0;
|
||||
UML_LOAD(block, IREG(0), seqhead->opptr.l, IMM(0), DWORD); // load i0,*opptr,0,dword
|
||||
sum += *seqhead->opptr.l;
|
||||
void *base = memory_decrypted_read_ptr(sh2->program, SH2_CODE_XOR(seqhead->physpc));
|
||||
UML_LOAD(block, IREG(0), base, IMM(0), WORD); // load i0,base,word
|
||||
sum += seqhead->opptr.w[0];
|
||||
for (curdesc = seqhead->next; curdesc != seqlast->next; curdesc = curdesc->next)
|
||||
if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
|
||||
{
|
||||
UML_LOAD(block, IREG(1), curdesc->opptr.l, IMM(0), DWORD); // load i1,*opptr,dword
|
||||
base = memory_decrypted_read_ptr(sh2->program, SH2_CODE_XOR(curdesc->physpc));
|
||||
UML_LOAD(block, IREG(1), base, IMM(0), WORD); // load i1,*opptr,word
|
||||
UML_ADD(block, IREG(0), IREG(0), IREG(1)); // add i0,i0,i1
|
||||
sum += *curdesc->opptr.l;
|
||||
sum += curdesc->opptr.w[0];
|
||||
}
|
||||
UML_CMP(block, IREG(0), IMM(sum)); // cmp i0,sum
|
||||
UML_EXHc(block, IF_NE, sh2->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc
|
||||
@ -1551,7 +1555,7 @@ static void generate_sequence_instruction(SH2 *sh2, drcuml_block *block, compile
|
||||
|
||||
/* add an entry for the log */
|
||||
if (LOG_UML && !(desc->flags & OPFLAG_VIRTUAL_NOOP))
|
||||
log_add_disasm_comment(block, desc->pc, *desc->opptr.l);
|
||||
log_add_disasm_comment(block, desc->pc, desc->opptr.w[0]);
|
||||
|
||||
/* set the PC map variable */
|
||||
expc = (desc->flags & OPFLAG_IN_DELAY_SLOT) ? desc->pc - 1 : desc->pc;
|
||||
@ -1622,7 +1626,7 @@ static void generate_sequence_instruction(SH2 *sh2, drcuml_block *block, compile
|
||||
if (!generate_opcode(sh2, block, compiler, desc))
|
||||
{
|
||||
UML_MOV(block, MEM(&sh2->pc), IMM(desc->pc)); // mov [pc],desc->pc
|
||||
UML_MOV(block, MEM(&sh2->arg0), IMM(*desc->opptr.w)); // mov [arg0],opcode
|
||||
UML_MOV(block, MEM(&sh2->arg0), IMM(desc->opptr.w[0])); // mov [arg0],opcode
|
||||
UML_CALLC(block, cfunc_unimplemented, sh2); // callc cfunc_unimplemented
|
||||
}
|
||||
}
|
||||
@ -1653,7 +1657,7 @@ static int generate_opcode(SH2 *sh2, drcuml_block *block, compiler_state *compil
|
||||
{
|
||||
UINT32 scratch, scratch2;
|
||||
INT32 disp;
|
||||
UINT16 opcode = *desc->opptr.w;
|
||||
UINT16 opcode = desc->opptr.w[0];
|
||||
UINT8 opswitch = opcode >> 12;
|
||||
int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0);
|
||||
|
||||
@ -1830,8 +1834,7 @@ static int generate_group_0(SH2 *sh2, drcuml_block *block, compiler_state *compi
|
||||
case 0x24: // MOVBS0(Rm, Rn);
|
||||
case 0x34: // MOVBS0(Rm, Rn);
|
||||
UML_ADD(block, IREG(0), R32(0), R32(Rn)); // add r0, R0, Rn
|
||||
UML_MOV(block, IREG(1), R32(Rm)); // mov r1, Rm
|
||||
UML_AND(block, IREG(1), IREG(1), IMM(0x000000ff)); // and r1, r1, 0xff
|
||||
UML_AND(block, IREG(1), R32(Rm), IMM(0x000000ff)); // and r1, Rm, 0xff
|
||||
UML_CALLH(block, sh2->write8); // call write8
|
||||
|
||||
if (!in_delay_slot)
|
||||
@ -1843,8 +1846,7 @@ static int generate_group_0(SH2 *sh2, drcuml_block *block, compiler_state *compi
|
||||
case 0x25: // MOVWS0(Rm, Rn);
|
||||
case 0x35: // MOVWS0(Rm, Rn);
|
||||
UML_ADD(block, IREG(0), R32(0), R32(Rn)); // add r0, R0, Rn
|
||||
UML_MOV(block, IREG(1), R32(Rm)); // mov r1, Rm
|
||||
UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); // and r1, r1, 0xffff
|
||||
UML_AND(block, IREG(1), R32(Rm), IMM(0x0000ffff)); // and r1, Rm, 0xffff
|
||||
UML_CALLH(block, sh2->write16); // call write16
|
||||
|
||||
if (!in_delay_slot)
|
||||
@ -1934,7 +1936,7 @@ static int generate_group_0(SH2 *sh2, drcuml_block *block, compiler_state *compi
|
||||
if (sh2->cpu_type > CPU_TYPE_SH1)
|
||||
{
|
||||
save_fast_iregs(sh2, block);
|
||||
UML_MOV(block, MEM(&sh2->arg0), IMM(*desc->opptr.w));
|
||||
UML_MOV(block, MEM(&sh2->arg0), IMM(desc->opptr.w[0]));
|
||||
UML_CALLC(block, cfunc_MAC_L, sh2);
|
||||
load_fast_iregs(sh2, block);
|
||||
return TRUE;
|
||||
@ -2054,8 +2056,7 @@ static int generate_group_2(SH2 *sh2, drcuml_block *block, compiler_state *compi
|
||||
{
|
||||
case 0: // MOVBS(Rm, Rn);
|
||||
UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn
|
||||
UML_MOV(block, IREG(1), R32(Rm)); // mov r1, Rm
|
||||
UML_AND(block, IREG(1), IREG(1), IMM(0xff)); // and r1, r1, 0xff
|
||||
UML_AND(block, IREG(1), R32(Rm), IMM(0xff)); // and r1, Rm, 0xff
|
||||
UML_CALLH(block, sh2->write8);
|
||||
|
||||
if (!in_delay_slot)
|
||||
@ -2064,8 +2065,7 @@ static int generate_group_2(SH2 *sh2, drcuml_block *block, compiler_state *compi
|
||||
|
||||
case 1: // MOVWS(Rm, Rn);
|
||||
UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn
|
||||
UML_MOV(block, IREG(1), R32(Rm)); // mov r1, Rm
|
||||
UML_AND(block, IREG(1), IREG(1), IMM(0xffff)); // and r1, r1, 0xffff
|
||||
UML_AND(block, IREG(1), R32(Rm), IMM(0xffff)); // and r1, Rm, 0xffff
|
||||
UML_CALLH(block, sh2->write16);
|
||||
|
||||
if (!in_delay_slot)
|
||||
@ -2259,7 +2259,7 @@ static int generate_group_3(SH2 *sh2, drcuml_block *block, compiler_state *compi
|
||||
|
||||
case 4: // DIV1(Rm, Rn);
|
||||
save_fast_iregs(sh2, block);
|
||||
UML_MOV(block, MEM(&sh2->arg0), IMM(*desc->opptr.w));
|
||||
UML_MOV(block, MEM(&sh2->arg0), IMM(desc->opptr.w[0]));
|
||||
UML_CALLC(block, cfunc_DIV1, sh2);
|
||||
load_fast_iregs(sh2, block);
|
||||
return TRUE;
|
||||
@ -2302,7 +2302,7 @@ static int generate_group_3(SH2 *sh2, drcuml_block *block, compiler_state *compi
|
||||
UML_ROLINS(block, MEM(&sh2->sr), IREG(0), IMM(0), IMM(T)); // rolins [sr],i0,0,T
|
||||
#else
|
||||
save_fast_iregs(sh2, block);
|
||||
UML_MOV(block, MEM(&sh2->arg0), IMM(*desc->opptr.w));
|
||||
UML_MOV(block, MEM(&sh2->arg0), IMM(desc->opptr.w[0]));
|
||||
UML_CALLC(block, cfunc_SUBV, sh2);
|
||||
load_fast_iregs(sh2, block);
|
||||
#endif
|
||||
@ -2322,7 +2322,7 @@ static int generate_group_3(SH2 *sh2, drcuml_block *block, compiler_state *compi
|
||||
UML_ROLINS(block, MEM(&sh2->sr), IREG(0), IMM(0), IMM(T)); // rolins [sr],i0,0,T
|
||||
#else
|
||||
save_fast_iregs(sh2, block);
|
||||
UML_MOV(block, MEM(&sh2->arg0), IMM(*desc->opptr.w));
|
||||
UML_MOV(block, MEM(&sh2->arg0), IMM(desc->opptr.w[0]));
|
||||
UML_CALLC(block, cfunc_ADDV, sh2);
|
||||
load_fast_iregs(sh2, block);
|
||||
#endif
|
||||
@ -2457,7 +2457,7 @@ static int generate_group_4(SH2 *sh2, drcuml_block *block, compiler_state *compi
|
||||
case 0x2f: // MAC_W(Rm, Rn);
|
||||
case 0x3f: // MAC_W(Rm, Rn);
|
||||
save_fast_iregs(sh2, block);
|
||||
UML_MOV(block, MEM(&sh2->arg0), IMM(*desc->opptr.w));
|
||||
UML_MOV(block, MEM(&sh2->arg0), IMM(desc->opptr.w[0]));
|
||||
UML_CALLC(block, cfunc_MAC_W, sh2);
|
||||
load_fast_iregs(sh2, block);
|
||||
return TRUE;
|
||||
@ -2767,12 +2767,8 @@ static int generate_group_6(SH2 *sh2, drcuml_block *block, compiler_state *compi
|
||||
UML_CALLH(block, sh2->read8); // call read8
|
||||
UML_SEXT(block, R32(Rn), IREG(0), BYTE); // sext Rn, r0, BYTE
|
||||
|
||||
UML_CMP(block, IMM(Rn), IMM(Rm)); // cmp N, M
|
||||
UML_JMPc(block, IF_Z, compiler->labelnum); // jz compiler->labelnum
|
||||
|
||||
UML_ADD(block, R32(Rm), R32(Rm), IMM(1)); // add Rm, Rm, #1
|
||||
|
||||
UML_LABEL(block, compiler->labelnum++); // labelnum:
|
||||
if (Rm != Rn)
|
||||
UML_ADD(block, R32(Rm), R32(Rm), IMM(1)); // add Rm, Rm, #1
|
||||
|
||||
if (!in_delay_slot)
|
||||
generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE);
|
||||
@ -2783,12 +2779,8 @@ static int generate_group_6(SH2 *sh2, drcuml_block *block, compiler_state *compi
|
||||
UML_CALLH(block, sh2->read16); // call read16
|
||||
UML_SEXT(block, R32(Rn), IREG(0), WORD); // sext Rn, r0, WORD
|
||||
|
||||
UML_CMP(block, IMM(Rn), IMM(Rm)); // cmp N, M
|
||||
UML_JMPc(block, IF_Z, compiler->labelnum); // jz compiler->labelnum
|
||||
|
||||
UML_ADD(block, R32(Rm), R32(Rm), IMM(2)); // add Rm, Rm, #2
|
||||
|
||||
UML_LABEL(block, compiler->labelnum++); // labelnum:
|
||||
if (Rm != Rn)
|
||||
UML_ADD(block, R32(Rm), R32(Rm), IMM(2)); // add Rm, Rm, #2
|
||||
|
||||
if (!in_delay_slot)
|
||||
generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE);
|
||||
@ -2799,12 +2791,8 @@ static int generate_group_6(SH2 *sh2, drcuml_block *block, compiler_state *compi
|
||||
UML_CALLH(block, sh2->read32); // call read32
|
||||
UML_MOV(block, R32(Rn), IREG(0)); // mov Rn, r0
|
||||
|
||||
UML_CMP(block, IMM(Rn), IMM(Rm)); // cmp N, M
|
||||
UML_JMPc(block, IF_Z, compiler->labelnum); // jz compiler->labelnum
|
||||
|
||||
UML_ADD(block, R32(Rm), R32(Rm), IMM(4)); // add Rm, Rm, #4
|
||||
|
||||
UML_LABEL(block, compiler->labelnum++); // labelnum:
|
||||
if (Rm != Rn)
|
||||
UML_ADD(block, R32(Rm), R32(Rm), IMM(4)); // add Rm, Rm, #4
|
||||
|
||||
if (!in_delay_slot)
|
||||
generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE);
|
||||
|
@ -26,6 +26,8 @@ static int describe_group_6(SH2 *context, opcode_desc *desc, const opcode_desc *
|
||||
static int describe_group_8(SH2 *context, opcode_desc *desc, const opcode_desc *prev, UINT16 opcode);
|
||||
static int describe_group_12(SH2 *context, opcode_desc *desc, const opcode_desc *prev, UINT16 opcode);
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
INSTRUCTION PARSERS
|
||||
***************************************************************************/
|
||||
@ -37,8 +39,11 @@ static int describe_group_12(SH2 *context, opcode_desc *desc, const opcode_desc
|
||||
|
||||
int sh2_describe(void *param, opcode_desc *desc, const opcode_desc *prev)
|
||||
{
|
||||
UINT16 opcode = *desc->opptr.w;
|
||||
SH2 *context = (SH2 *)param;
|
||||
UINT16 opcode;
|
||||
|
||||
/* fetch the opcode */
|
||||
opcode = desc->opptr.w[0] = memory_decrypted_read_word(context->program, SH2_CODE_XOR(desc->physpc));
|
||||
|
||||
/* all instructions are 2 bytes and most are a single cycle */
|
||||
desc->length = 2;
|
||||
|
@ -86,14 +86,14 @@ static MACHINE_START( ultrsprt )
|
||||
|
||||
/* configure fast RAM regions for DRC */
|
||||
device_set_info_int(machine->cpu[0], CPUINFO_INT_PPC_FASTRAM_SELECT, 0);
|
||||
device_set_info_int(machine->cpu[0], CPUINFO_INT_PPC_FASTRAM_START, 0x00000000);
|
||||
device_set_info_int(machine->cpu[0], CPUINFO_INT_PPC_FASTRAM_END, 0x0007ffff);
|
||||
device_set_info_int(machine->cpu[0], CPUINFO_INT_PPC_FASTRAM_START, 0x80000000);
|
||||
device_set_info_int(machine->cpu[0], CPUINFO_INT_PPC_FASTRAM_END, 0x8007ffff);
|
||||
device_set_info_ptr(machine->cpu[0], CPUINFO_PTR_PPC_FASTRAM_BASE, vram);
|
||||
device_set_info_int(machine->cpu[0], CPUINFO_INT_PPC_FASTRAM_READONLY, 0);
|
||||
|
||||
device_set_info_int(machine->cpu[0], CPUINFO_INT_PPC_FASTRAM_SELECT, 1);
|
||||
device_set_info_int(machine->cpu[0], CPUINFO_INT_PPC_FASTRAM_START, 0x7f000000);
|
||||
device_set_info_int(machine->cpu[0], CPUINFO_INT_PPC_FASTRAM_END, 0x7f01ffff);
|
||||
device_set_info_int(machine->cpu[0], CPUINFO_INT_PPC_FASTRAM_START, 0xff000000);
|
||||
device_set_info_int(machine->cpu[0], CPUINFO_INT_PPC_FASTRAM_END, 0xff01ffff);
|
||||
device_set_info_ptr(machine->cpu[0], CPUINFO_PTR_PPC_FASTRAM_BASE, workram);
|
||||
device_set_info_int(machine->cpu[0], CPUINFO_INT_PPC_FASTRAM_READONLY, 0);
|
||||
}
|
||||
@ -110,9 +110,7 @@ static ADDRESS_MAP_START( ultrsprt_map, ADDRESS_SPACE_PROGRAM, 32 )
|
||||
AM_RANGE(0x700000e0, 0x700000e3) AM_WRITE(int_ack_w)
|
||||
AM_RANGE(0x7f000000, 0x7f01ffff) AM_RAM AM_BASE(&workram)
|
||||
AM_RANGE(0x7f700000, 0x7f703fff) AM_RAM_WRITE(palette_w) AM_BASE(&paletteram32)
|
||||
AM_RANGE(0x7fa00000, 0x7fbfffff) AM_ROM AM_SHARE(1)
|
||||
AM_RANGE(0x7fc00000, 0x7fdfffff) AM_ROM AM_SHARE(1)
|
||||
AM_RANGE(0x7fe00000, 0x7fffffff) AM_ROM AM_REGION("user1", 0) AM_SHARE(1)
|
||||
AM_RANGE(0x7f800000, 0x7f9fffff) AM_MIRROR(0x00600000) AM_ROM AM_REGION("user1", 0)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
@ -167,7 +165,7 @@ static WRITE16_HANDLER( K056800_68k_w )
|
||||
}
|
||||
|
||||
static ADDRESS_MAP_START( sound_map, ADDRESS_SPACE_PROGRAM, 16 )
|
||||
AM_RANGE(0x00000000, 0x0001ffff) AM_READ(SMH_ROM)
|
||||
AM_RANGE(0x00000000, 0x0001ffff) AM_ROM
|
||||
AM_RANGE(0x00100000, 0x00101fff) AM_RAM
|
||||
AM_RANGE(0x00200000, 0x00200007) AM_WRITE(K056800_68k_w)
|
||||
AM_RANGE(0x00200008, 0x0020000f) AM_READ(K056800_68k_r)
|
||||
|
Loading…
Reference in New Issue
Block a user