mpn_rshift / mpn_lshift bug on m68000
Linus Nordberg
linus at swox.com
Tue Oct 21 18:18:44 CEST 2003
Hi,
It seems like the mailing list archive has trouble displaying the
attachments I used for the previous three messages.
For the record, we proudly present once again the three bug reports
from Patrick Pelissier. Drum rolls...
--
Linus Nordberg
List admin
Swox AB <http://swox.com/>
---------------------------------------------------------------------
From: Patrick Pelissier <Patrick.Pelissier at loria.fr>
Subject: Re: mpn_rshift / mpn_lshift bug on m68000
Cc: gmp-bugs at swox.com
Date: Sat, 18 Oct 2003 10:56:14 +0200
Kevin Ryde wrote:
> But yes, if the value is 16-bits and it's passed with garbage in the
> upper part then we have to account for that.
>
> I think the PalmOS tools use int==16bits, but I'm not sure we ever got
> as far as actually running on that, so I don't know if there's an
> actual problem or merely a hypothetical one.
>
> I guess we can load just 16-bits either way, since the shift count is
> only ever 1 to 31.
But mc68k are big endian :)
If it int=16, you should read
movew 10(a7),d0
Otherwise, if int=32, and you want to read the lower part :
movew 12(a7),d0
>Feel free to propose a patch.
Maybe a separate asm file for 16-bits mc68k ?
---------------------------------------------------------------------
From: Patrick Pelissier <Patrick.Pelissier at loria.fr>
Subject: Re: mpn_rshift / mpn_lshift bug on m68000
Cc: gmp-bugs at swox.com
Date: Mon, 20 Oct 2003 12:42:25 +0200
> I tried deliberately sticking a random value in the upper part, and
> mpn_lshift still worked fine.
Or course, because:
1. mc68000 is big endian!
2. The real shift count is modulo 32: the important bits are the 5
lowest bits.
Here is what happens:
movew #258,-(sp) ; Garbash due to an old call
jsr dummy_thing
movew #4,-(sp) ; Push count (int)
movel #16,-(sp) ; Push size (long)
movel #$DEADDEA0,-(sp) ; Push src (void*)
movel #$ABCDABC0,-(sp) ; Push dest (void*)
Here the stack looks like:
sp-> 003BF8: $AB, $CD, $AB, $C0, $DE, $AD, $DE, $A0
003C00: $00, $00, $00, $10, $00, $04, $01, $02
Then the call:
jsr __gmpn_rshift
...
__gmpn_rshift:
C Save used registers on the stack.
moveml d2-d6/a2, M(-,sp)
C Copy the arguments to registers.
movel M(sp,28), res_ptr
movel M(sp,32), s_ptr
movel M(sp,36), s_size
movel M(sp,40), cnt
Here:
res_ptr = ABCDABC0
s_ptr = DEADDEA0
s_size = 123
cnt = 4*65536+258
So the real shift is (4*65536+258)%32=2, not 4 :)
Your trick works only for little endian processors (such as x86).
> We ask that bug reports include a sample program exhibiting the
> claimed bad behaviour in order to ensure that a reported problem
> really is a problem.
Every programs which use mpn_rshift/mpn_lshift (ie every GMP programs
?) is buggy.
I have tested myself a small MPFR/GMP program for mc68000, and after
using the assembly debugger, I have found what the problem was. After a
small fix to rshift.asm/lshift.asm, it works fine. It isn't a
hypothetical problem, but a real tested one.
If you really want, I can put a test case, but it appears that you
can't test it on a real mc68000. Nevertheless, if you are not already
convinced, I can send you such a program.
Sincerely,
Patrick Pelissier
---------------------------------------------------------------------
From: Patrick Pelissier <Patrick.Pelissier at loria.fr>
Subject: Re: mpn_rshift / mpn_lshift bug on m68000
To: gmp-bugs at swox.com
Date: Tue, 21 Oct 2003 10:44:21 +0200
> I had an idea the stack is kept longword aligned.
No. Until on 68000 (I am not sure for mcpu32, but I am sure it isn't
the case on 68000).
> If you think that's
> not the case then please post a program / compiler info / etc
> illustrating that, or more to the point illustrating the problem
> you're concerned about.
I thought I have explained everything.
> Yes, see "reporting bugs" in the manual. We ask for all that info so
> as to have something definite to fix or refute (as the case may be).
I have added the smallest test case I can do. There is the .c, the
.s and the .i.
It doesn't work on mc68000 systems.
Compiler is gcc v3.3.1 and GNU Binutils v2.14.
GMP 4.1.2 build with host=mc68000-gnu-linux.
The results of rshift/lshift are incorrect.
> We have a netbsd 68040 among our test systems.
It isn't a 68000!
Maybe try to use the -mshort -mc68000 options of gcc compiler.
See
http://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/M680x0-Options.html#M680x0%20Options
Build GMP on netbsd 68040 with theses options, and try the test. I
hope you will see the bug.
Sincerely,
Patrick Pelissier
More information about the gmp-bugs
mailing list