Re: Long long arithmetic

From: Richard B. Johnson (root@chaos.analogic.com)
Date: Thu Jun 08 2000 - 20:05:27 EST


On 8 Jun 2000, H. Peter Anvin wrote:

> Followup to: <39400F10.36D1DDBF@quark.vpplus.com>
> By author: Brian Gerst <bgerst@quark.vpplus.com>
> In newsgroup: linux.dev.kernel
> >
> > GCC needs library functions for some 64-bit operations on 32-bit
> > crchitectures, which are not present in the kernel. 64-bit division is
> > a common example of this. If possible, limit your code to using adds
> > and shifts when working with long longs.
> >
>
> Is there any reason we don't link the kernel with libgcc? libgcc
> doesn't do system calls, so it should be safe to link the kernel with.
>
> -hpa

You usually get more than you expect when linking with a library. The
result being some undefined symbols. When you include the cruft necessary
to handle that, you can end up with some very large dead code.

I suggest borrowing some long long stuff from the libgcc source and
putting it into the kernel. We keep getting hit by requests for long long
division.

This would quiet that and, if the resulting drivers or other code
eventually get into the kernel it will probably get fixed to not
have to use the CPU-hog divide.

Also some gcc versions make errors with 'long long'. The following:

#include <stdio.h>
long long foo = 0x12345678aa55aa55;
main()
{
   long long bar;
   bar = foo >> 32;
   printf("%Lx\n", bar);
}

Has a warning error on compile, but prints the correct answer anyway.
Gcc version 2.7.2.3 doesn't know that the above is within range.

It has broken it up into:

        .align 4
        .type foo,@object
        .size foo,8
foo:
        .long -1437226411
        .long 305419896

Which is numerically-correct, but it doesn't understand that it, not
me decided to interpret 0xaa55aa55 (the LOW word) as being too large.
(little-endian, low at the lowest address).

On Intel 32-bit machines, gcc has other problems with long-long also. This
version makes some very complex code where simple stuff would work
just fine. In particular, it doesn't minimize divide code with shifts
where possible, and uses the 'idiv' instruction (reducing the dynamic
range), where all it has to do is use 'div', allowing 64 bits to
be divided by 32 bits in one step, then correcting the sign later.

Cheers,
Dick Johnson

Penguin : Linux version 2.3.41 on an i686 machine (800.63 BogoMips).

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Jun 15 2000 - 21:00:16 EST