Subject: Re: sysinst bug and errors
To: Dave Huang <khym@azeotrope.org>
From: Frederick Bruckman <fredb@immanent.net>
List: port-mac68k
Date: 09/03/2002 20:57:56
On Tue, 3 Sep 2002, Dave Huang wrote:

> On Tue, 3 Sep 2002, Frederick Bruckman wrote:
> > What happens if you build a kernel without FPSP (with or without FPU)?
>
> If I'm not mistaken, options FPSP only matters if you're running on a
> 68[LC]040... sys/arch/mac68k/mac68k/locore.s does a
>   cmpl    #FPU_68040,_C_LABEL(fputype) | 68040 FPU?
> and only calls the FPSP routines if the comparison is true. So a kernel
> without FPSP shouldn't be any different on an '030 machine.

What about this bit in vectors.s...?

#ifdef FPSP
        ASVECTOR(bsun)          /* 48: FPCP branch/set on unordered cond */
        ASVECTOR(inex)          /* 49: FPCP inexact result */
        ASVECTOR(dz)            /* 50: FPCP divide by zero */
        ASVECTOR(unfl)          /* 51: FPCP underflow */
        ASVECTOR(operr)         /* 52: FPCP operand error */
        ASVECTOR(ovfl)          /* 53: FPCP overflow */
        ASVECTOR(snan)          /* 54: FPCP signalling NAN */
#else
        VECTOR(fpfault)         /* 48: FPCP branch/set on unordered cond */
        VECTOR(fpfault)         /* 49: FPCP inexact result */
        VECTOR(fpfault)         /* 50: FPCP divide by zero */
        VECTOR(fpfault)         /* 51: FPCP underflow */
        VECTOR(fpfault)         /* 52: FPCP operand error */
        VECTOR(fpfault)         /* 53: FPCP overflow */
        VECTOR(fpfault)         /* 54: FPCP signalling NAN */
#endif

It looks to me, that if you take any kind of FP exception (that is, if
you try to do any useful work with floating point), you're jumping
straight into the FPSP code. You should then trap with an "fpunsupp",
and jump into the FPU_EMULATE code (by virtue of the bit below), but
the 68040X instructions aren't emulated, so that's as far as you'll go.

> I do wonder about this bit of code around line 581 of locore.s though:
>
> ENTRY_NOPROFILE(fpunsupp)
> #if defined(M68040)
>         cmpl    #FPU_68040,_C_LABEL(fputype) | 68040 FPU?
>         jne     _C_LABEL(illinst)       | no, treat as illinst
> #ifdef FPSP
>         jmp     _ASM_LABEL(fpsp_unsupp) | yes, go handle it
> #endif
> Lfp_unsupp:
> #endif /* M68040 */
> #ifdef FPU_EMULATE
>         clrl    %sp@-                   | stack adjust count
>         moveml  #0xFFFF,%sp@-           | save registers
>         moveq   #T_FPEMULD,%d0          | denote as FP emulation trap
>         jra     _ASM_LABEL(fault)       | do it
> #else
>         jra     _C_LABEL(illinst)
> #endif
>
> Shouldn't that jne _C_LABEL(illinst)       | no, treat as illinst
> be a jne _C_LABEL(Lfp_unsupp)?
>
> CVS says:
>
> revision 1.80
> date: 1997/06/29 06:07:39;  author: scottr;  state: Exp;  lines: +590 -745
> Get several cleanup chores out of the way.  The code is functionally
> identical to the previous incarnation.
>
> However, a diff between 1.79 and 1.80 shows:
> -       cmpl    #FPU_68040,_fputype     | 68040? (see fpu.c)
> -       jne     Lfp_unsupp              | no, treat as illinst
> +       cmpl    #FPU_68040,_C_LABEL(fputype) | 68040 FPU?
> +       jne     _C_LABEL(illinst)       | no, treat as illinst
>
> which doesn't look like a functionally identical change to me :)

You're right! It really could have been broken that long, too, because
th last time we visited this, we found FPU_EMULATE actually works in
kernels without M68040 and FPSP. Your catch explains the M68040 part,
but I still think its wrong to fill the vector table with jumps to
code containing 68040X instructions on anything but a full 68040.

Frederick