Re: [hatari-devel] Suspected Hatari 2.3.0 regression (prefetch?) |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/hatari-devel Archives
]
- To: hatari-devel@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [hatari-devel] Suspected Hatari 2.3.0 regression (prefetch?)
- From: Christian Zietz <czietz@xxxxxxx>
- Date: Wed, 16 Dec 2020 18:34:45 +0100
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1608140085; bh=moOD9q2pCl/a7oYtRk5hR6KkmwxDaXENk67+pcmyPYE=; h=X-UI-Sender-Class:To:References:From:Subject:Date:In-Reply-To; b=gdMUbi9KQ8Nr40RZN0f0qvhl0FXlEals3GjENLY4KP6KbcweX/BXQucpdK4A+jJ/j HSJ1k3usfAJPTlM2xYM27kki+XvqPRSjH/GBzIltvqzG3i5xBdhvOedqtJyWt0Q7KT aFI7SpiwUgWOZAmlNSNGUlTF9Qlc3eyfjrxR6/Vo=
Eero Tamminen schrieb:
Because there aren't more programs requiring
MMU with Hatari v2.3, I suspect this issue to
be specific just to certain instructions or
addressing modes.
As I've written before: On the *68000* MOVEM from memory to registers
causes an extra memory access. Of course, in many cases this is not an
issue; however, it becomes a problem if this extra access causes a bus
error.
However, as I've also written before: I'm unsure this is true for the
*68030*. If there's no extra access on a real 68030 (which is what I
suspect), Hatari's emulation should not make this extra access, either.
As for why it does not crash with MMU enabled: This has nothing to do
with the MMU per se but with the fact that Hatari uses different code paths:
Without MMU, 68030 MOVEM.L (Ax)+,... is handled in cpuemu_23.c which is
auto-generated to contain...
/* MVMEL.L #<data>.W,(An)+ */
void REGPARAM2 op_4cd8_23_ff(uae_u32 opcode)
{
int count_cycles = 0;
uae_u32 real_opcode = opcode;
uae_u32 dstreg = real_opcode & 7;
OpcodeFamily = 37;
uae_u16 mask = get_word_ce030_prefetch(2);
uae_u32 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;
uaecptr srca;
srca = m68k_areg(regs, dstreg);
while (dmask) {
m68k_dreg(regs, movem_index1[dmask]) = x_get_long(srca);
count_cycles += 4 * CYCLE_UNIT / 2;
srca += 4;
dmask = movem_next[dmask];
}
while (amask) {
m68k_areg(regs, movem_index1[amask]) = x_get_long(srca);
count_cycles += 4 * CYCLE_UNIT / 2;
srca += 4;
amask = movem_next[amask];
}
m68k_areg(regs, dstreg) = srca;
x_get_word(srca);
ipl_fetch();
regs.irc = get_word_ce030_prefetch_opcode(4);
m68k_incpci(4);
return;
}
Note the extra access "x_get_word(srca)", which is what causes the bus
error.
With MMU, 68030 MOVEM.L (Ax)+,... is handled in cpuemu_35.c:
/* MVMEL.L #<data>.W,(An)+ */
void REGPARAM2 op_4cd8_35_ff(uae_u32 opcode)
{
int count_cycles = 0;
uae_u32 real_opcode = opcode;
uae_u32 dstreg = real_opcode & 7;
OpcodeFamily = 37;
uae_u16 mask = get_iword_mmu030c_state(2);
uae_u32 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;
uaecptr srca;
srca = m68k_areg(regs, dstreg);
mmu030_state[1] |= MMU030_STATEFLAG1_MOVEM1;
int movem_cnt = 0;
uae_u32 val;
srca = state_store_mmu030(srca);
while (dmask) {
uae_u16 nextmask = movem_next[dmask];
if (mmu030_state[0] == movem_cnt) {
if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM2) {
mmu030_state[1] &= [...]
val = mmu030_data_buffer_out;
} else {
val = get_long_mmu030c(srca);
}
m68k_dreg (regs, movem_index1[dmask]) = val;
mmu030_state[0]++;
}
srca += 4;
movem_cnt++;
dmask = nextmask;
}
while (amask) {
uae_u16 nextmask = movem_next[amask];
if (mmu030_state[0] == movem_cnt) {
if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM2) {
mmu030_state[1] &= [...]
val = mmu030_data_buffer_out;
} else {
val = get_long_mmu030c(srca);
}
m68k_areg (regs, movem_index1[amask]) = val;
mmu030_state[0]++;
}
srca += 4;
movem_cnt++;
amask = nextmask;
}
m68k_areg(regs, dstreg) = srca;
ipl_fetch();
regs.irc = get_iword_mmu030c_opcode_state(4);
m68k_incpci(4);
return;
}
Notice how this does *not* include the extra access. Which is why there
is no bus error, anymore. Hence, the emulation is contradictory: only
one function can be right about this.
Regards
Christian
--
Christian Zietz - CHZ-Soft - czietz@xxxxxxx
WWW: https://www.chzsoft.de/
PGP/GnuPG-Key-ID: 0x52CB97F66DA025CA / 0x6DA025CA