On Wed, Oct 28, 2026 at 8:29 AM Laurent Vivier <[email protected]> wrote:
>
> Le 03/09/2026 à 06:45, 54weasels a écrit :
> > Why this change is made & How it will be used:
> > The 68881/68882 FPUs require fsave/frestore instructions to read/write
> > state frames. QEMU only fully implemented this for the 68040. The Sun-3
> > uses a 68881 FPU, and the boot ROM executes `fsave` to probe FPU presence.
> > This patch adds basic 68881 FPU state frame handling (NULL frame) to
> > accurately simulate an idle FPU state.
> >
> > Impact on existing functionality:
> > Fixes FPU detection for 68881/68882 across all M68k boards without
> > affecting 68040 specific state logic.
> >
> > Signed-off-by: 54weasels <[email protected]>
> > ---
> > target/m68k/translate.c | 20 +++++++++++++-------
> > 1 file changed, 13 insertions(+), 7 deletions(-)
> >
> > diff --git a/target/m68k/translate.c b/target/m68k/translate.c
> > index 138c89d3e5..c89ef213ed 100644
> > --- a/target/m68k/translate.c
> > +++ b/target/m68k/translate.c
> > @@ -5364,11 +5364,11 @@ DISAS_INSN(frestore)
> > gen_exception(s, s->base.pc_next, EXCP_PRIVILEGE);
> > return;
> > }
> > - if (m68k_feature(s->env, M68K_FEATURE_M68040)) {
> > + if (m68k_feature(s->env, M68K_FEATURE_FPU)) {
>
> This is not correct for 68060, it has FPU feature bit set but not 040 featuer
> bit, so it will be
> managed as 68881/68882. To keep existing behavior, it needs to call
> disas_undef()
>
Good catch, thanks. In v6 I'll leave the 68040 path as it is and add an
explicit branch for M68020/M68030 (NULL frame). Everything else, 68060
included, goes to disas_undef() as it does today.
> > SRC_EA(env, addr, OS_LONG, 0, NULL);
> > /* FIXME: check the state frame */
> > } else {
> > - disas_undef(env, s, insn);
> > + disas_undef_fpu(env, s, insn);
>
> unrelated, needs a separate patch or omitted.
>
Agreed, I'll drop the disas_undef_fpu() change.
> > }
> > }
> >
> > @@ -5379,12 +5379,18 @@ DISAS_INSN(fsave)
> > return;
> > }
> >
> > - if (m68k_feature(s->env, M68K_FEATURE_M68040)) {
> > - /* always write IDLE */
> > - TCGv idle = tcg_constant_i32(0x41000000);
> > - DEST_EA(env, insn, OS_LONG, idle, NULL);
> > + if (m68k_feature(s->env, M68K_FEATURE_FPU)) {
> > + TCGv frame;
> > + if (m68k_feature(s->env, M68K_FEATURE_M68040)) {
> > + /* 68040 FSAVE: always write IDLE */
> > + frame = tcg_constant_i32(0x41000000);
>
> same as previously
>
>
> > + } else {
> > + /* 68881/68882 FSAVE: always write NULL frame */
> > + frame = tcg_constant_i32(0x00000000);
> > + }
> > + DEST_EA(env, insn, OS_LONG, frame, NULL);
> > } else {
> > - disas_undef(env, s, insn);
> > + disas_undef_fpu(env, s, insn);
>
> same as previously
>
> > }
> > }
> > #endif
>
> Thanks,
> Laurent