[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