mirror of
https://github.com/holub/mame
synced 2025-04-21 16:01:56 +03:00
mips3drc: Fixed block checksumming. Fixes IRIX installer hang on ip225015. [Ryan Holtz]
This commit is contained in:
parent
01e459a711
commit
b48637a56d
@ -318,8 +318,9 @@ void mips3_device::code_compile_block(uint8_t mode, offs_t pc)
|
||||
|
||||
/* if we don't have a hash for this mode/pc, or if we are overriding all, add one */
|
||||
if (override || !m_drcuml->hash_exists(mode, seqhead->pc))
|
||||
{
|
||||
UML_HASH(block, mode, seqhead->pc); // hash mode,pc
|
||||
|
||||
}
|
||||
/* if we already have a hash, and this is the first sequence, assume that we */
|
||||
/* are recompiling due to being out of sync and allow future overrides */
|
||||
else if (seqhead == desclist)
|
||||
@ -332,8 +333,7 @@ void mips3_device::code_compile_block(uint8_t mode, offs_t pc)
|
||||
else
|
||||
{
|
||||
UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000
|
||||
UML_HASHJMP(block, m_core->mode, seqhead->pc, *m_nocode);
|
||||
// hashjmp <mode>,seqhead->pc,nocode
|
||||
UML_HASHJMP(block, m_core->mode, seqhead->pc, *m_nocode); // hashjmp <mode>,seqhead->pc,nocode
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -343,11 +343,15 @@ void mips3_device::code_compile_block(uint8_t mode, offs_t pc)
|
||||
|
||||
/* label this instruction, if it may be jumped to locally */
|
||||
if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET)
|
||||
{
|
||||
UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000
|
||||
}
|
||||
|
||||
/* iterate over instructions in the sequence and compile them */
|
||||
for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next())
|
||||
{
|
||||
generate_sequence_instruction(block, compiler, curdesc);
|
||||
}
|
||||
|
||||
/* if we need to return to the start, do it */
|
||||
if (seqlast->flags & OPFLAG_RETURN_TO_START)
|
||||
@ -362,11 +366,13 @@ void mips3_device::code_compile_block(uint8_t mode, offs_t pc)
|
||||
|
||||
/* if the last instruction can change modes, use a variable mode; otherwise, assume the same mode */
|
||||
if (seqlast->flags & OPFLAG_CAN_CHANGE_MODES)
|
||||
UML_HASHJMP(block, mem(&m_core->mode), nextpc, *m_nocode);
|
||||
// hashjmp <mode>,nextpc,nocode
|
||||
{
|
||||
UML_HASHJMP(block, mem(&m_core->mode), nextpc, *m_nocode); // hashjmp <mode>,nextpc,nocode
|
||||
}
|
||||
else if (seqlast->next() == nullptr || seqlast->next()->pc != nextpc)
|
||||
UML_HASHJMP(block, m_core->mode, nextpc, *m_nocode);
|
||||
// hashjmp <mode>,nextpc,nocode
|
||||
{
|
||||
UML_HASHJMP(block, m_core->mode, nextpc, *m_nocode); // hashjmp <mode>,nextpc,nocode
|
||||
}
|
||||
}
|
||||
|
||||
/* end the sequence */
|
||||
@ -1058,7 +1064,6 @@ void mips3_device::generate_update_cycles(drcuml_block &block, compiler_state &c
|
||||
compiler.cycles = 0;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
generate_checksum_block - generate code to
|
||||
validate a sequence of opcodes
|
||||
@ -1077,15 +1082,17 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
|
||||
{
|
||||
uint32_t sum = seqhead->opptr.l[0];
|
||||
const void *base = m_prptr(seqhead->physpc);
|
||||
UML_LOAD(block, I0, base, 0, SIZE_DWORD, SCALE_x4); // load i0,base,0,dword
|
||||
uint32_t low_bits = (seqhead->physpc & (m_data_bits == 64 ? 4 : 0)) ^ m_dword_xor;
|
||||
UML_LOAD(block, I0, base, low_bits, SIZE_DWORD, SCALE_x1); // load i0,base,0,dword
|
||||
|
||||
if (seqhead->delay.first() != nullptr
|
||||
&& !(seqhead->delay.first()->flags & OPFLAG_VIRTUAL_NOOP)
|
||||
&& seqhead->physpc != seqhead->delay.first()->physpc)
|
||||
{
|
||||
uint32_t low_bits = (seqhead->delay.first()->physpc & (m_data_bits == 64 ? 4 : 0)) ^ m_dword_xor;
|
||||
base = m_prptr(seqhead->delay.first()->physpc);
|
||||
assert(base != nullptr);
|
||||
UML_LOAD(block, I1, base, 0, SIZE_DWORD, SCALE_x4); // load i1,base,dword
|
||||
UML_LOAD(block, I1, base, low_bits, SIZE_DWORD, SCALE_x1); // load i1,base,dword
|
||||
UML_ADD(block, I0, I0, I1); // add i0,i0,i1
|
||||
|
||||
sum += seqhead->delay.first()->opptr.l[0];
|
||||
@ -1104,21 +1111,24 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
|
||||
if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
|
||||
{
|
||||
const void *base = m_prptr(seqhead->physpc);
|
||||
UML_LOAD(block, I0, base, 0, SIZE_DWORD, SCALE_x4); // load i0,base,0,dword
|
||||
UML_LOAD(block, I0, base, m_dword_xor, SIZE_DWORD, SCALE_x1); // load i0,base,0,dword
|
||||
UML_CMP(block, I0, curdesc->opptr.l[0]); // cmp i0,opptr[0]
|
||||
UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc
|
||||
}
|
||||
#else
|
||||
uint32_t sum = 0;
|
||||
const void *base = m_prptr(seqhead->physpc);
|
||||
UML_LOAD(block, I0, base, 0, SIZE_DWORD, SCALE_x4); // load i0,base,0,dword
|
||||
uint32_t low_bits = (seqhead->physpc & (m_data_bits == 64 ? 4 : 0)) ^ m_dword_xor;
|
||||
UML_LOAD(block, I0, base, low_bits, SIZE_DWORD, SCALE_x1); // 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))
|
||||
{
|
||||
base = m_prptr(curdesc->physpc);
|
||||
assert(base != nullptr);
|
||||
UML_LOAD(block, I1, base, 0, SIZE_DWORD, SCALE_x4); // load i1,base,dword
|
||||
uint32_t low_bits = (curdesc->physpc & (m_data_bits == 64 ? 4 : 0)) ^ m_dword_xor;
|
||||
UML_LOAD(block, I1, base, low_bits, SIZE_DWORD, SCALE_x1); // load i1,base,dword
|
||||
UML_ADD(block, I0, I0, I1); // add i0,i0,i1
|
||||
sum += curdesc->opptr.l[0];
|
||||
|
||||
@ -1128,11 +1138,13 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
|
||||
{
|
||||
base = m_prptr(curdesc->delay.first()->physpc);
|
||||
assert(base != nullptr);
|
||||
UML_LOAD(block, I1, base, 0, SIZE_DWORD, SCALE_x4); // load i1,base,dword
|
||||
uint32_t low_bits = (curdesc->delay.first()->physpc & (m_data_bits == 64 ? 4 : 0)) ^ m_dword_xor;
|
||||
UML_LOAD(block, I1, base, low_bits, SIZE_DWORD, SCALE_x1); // load i1,base,dword
|
||||
UML_ADD(block, I0, I0, I1); // add i0,i0,i1
|
||||
sum += curdesc->delay.first()->opptr.l[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
UML_CMP(block, I0, sum); // cmp i0,sum
|
||||
UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc
|
||||
#endif
|
||||
@ -1291,17 +1303,18 @@ void mips3_device::generate_delay_slot_and_branch(drcuml_block &block, compiler_
|
||||
{
|
||||
generate_update_cycles(block, compiler_temp, desc->targetpc, true); // <subtract cycles>
|
||||
if (desc->flags & OPFLAG_INTRABLOCK_BRANCH)
|
||||
{
|
||||
UML_JMP(block, desc->targetpc | 0x80000000); // jmp desc->targetpc | 0x80000000
|
||||
}
|
||||
else
|
||||
UML_HASHJMP(block, m_core->mode, desc->targetpc, *m_nocode);
|
||||
// hashjmp <mode>,desc->targetpc,nocode
|
||||
{
|
||||
UML_HASHJMP(block, m_core->mode, desc->targetpc, *m_nocode); // hashjmp <mode>,desc->targetpc,nocode
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
generate_update_cycles(block, compiler_temp, uml::mem(&m_core->jmpdest), true);
|
||||
// <subtract cycles>
|
||||
UML_HASHJMP(block, m_core->mode, mem(&m_core->jmpdest), *m_nocode);
|
||||
// hashjmp <mode>,<rsreg>,nocode
|
||||
generate_update_cycles(block, compiler_temp, uml::mem(&m_core->jmpdest), true); // <subtract cycles>
|
||||
UML_HASHJMP(block, m_core->mode, mem(&m_core->jmpdest), *m_nocode); // hashjmp <mode>,<rsreg>,nocode
|
||||
}
|
||||
|
||||
/* update the label */
|
||||
@ -2615,10 +2628,8 @@ bool mips3_device::generate_cop0(drcuml_block &block, compiler_state &compiler,
|
||||
UML_MOV(block, CPR032(COP0_Status), I0); // mov [Status],i0
|
||||
generate_update_mode(block);
|
||||
compiler.checkints = true;
|
||||
generate_update_cycles(block, compiler, CPR032(COP0_ErrorPC), true);
|
||||
// <subtract cycles>
|
||||
UML_HASHJMP(block, mem(&m_core->mode), CPR032(COP0_ErrorPC), *m_nocode);
|
||||
// hashjmp <mode>,[EPC],nocode
|
||||
generate_update_cycles(block, compiler, CPR032(COP0_ErrorPC), true); // <subtract cycles>
|
||||
UML_HASHJMP(block, mem(&m_core->mode), CPR032(COP0_ErrorPC), *m_nocode); // hashjmp <mode>,[EPC],nocode
|
||||
return true;
|
||||
|
||||
case 0x20: /* WAIT */
|
||||
|
Loading…
Reference in New Issue
Block a user