[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [MiNT] PML trouble with -m68020-60



Miro Kropáček wrote:
    I have just discovered that my libm.a (PML) for -m68020-60 is
    totally wrong. I had never tested it before, now I'm sure.

What what what? I use it on "daily" basis, all my software is compiled
with 020-60 version (Zorro's stuff included!). I've never experienced
any troubles.

There are multiple troubles.

1) When a function returns a double, GCC returns it differently according to the CPU option.
- for 68000 and ColdFire, doubles are returned into d0/d1.
- for m68020-60, doubles are returned into fp0.

This is the default behavior of GCC for m68k. The fact that the register used are different among configurations introduces incompatibilities between them, that's why mixing objects compiled with different CPU options is forbidden.

There are unfortunate side effects. The C language allows to call functions without a prototype (=madness). If no prototype is given, GCC will assume the return value is an int and returned into d0, while the real value is actually returned into fp0. This means that math.h must absolutely be included in any case to provide prototypes.
This has to be confirmed, I have not investigated that issue.
Maybe there are always troubles without math.h so it is never forgotten and there are never problems.

Also, assembler routines must be aware of that difference among CPU options, and return the values into the right register.

Some m68k targets don't use this default behavior, and return the doubles into d0/d1 in any case. GCC 2.95.3 and GCC 4.x for MiNT use the default behavior (different registers), I really wonder if this is a good thing.

2) PML uses the __M68881__ define to check which version we are compiling, unfortunately it is wrong because that define is only set with -m68881 and not -m68020-60. The correct define, at least for GCC 4.x, is __HAVE_68881__ which indicates that the FPU must be used.

As a result, PML for -m68020-60 has always been compiled using the 68000 implementation, which can be wrong because of 1). Fortunately, that implementation is often written in C, so it is correct in any case. But it does not use the dedicated FPU instructions. If some 68000 implementations use assembler and return the values into d0/d1, it is wrong.

3) libm.a is not always used.
- when the result of math functions can be determined at compile time, GCC replaces it by constants. - GCC provides math-68881.h, it contains inline implementations of the math functions using the equivalent FPU instructions. That file should be automatically included by math.h, but I'm pretty sure it is not the case right now. To be investigated.
- as last resort, libm.a is used.
So when it seems there is no trouble with -lm, it may not be used as much as we would imagine.

As you see, big mess.
I really think we should drop PML and fdlibm and use another libm from an actively maintained project (Newlib, BSD...), since there is nothing specific to the OS.

--
Vincent Rivière