[Vm-dev] VM Maker: VMMaker.oscog-eem.790.mcz

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Tue Jul 1 19:21:00 UTC 2014


2014-07-01 4:22 GMT+02:00 <commits at source.squeak.org>:

>
> Item was changed:
>   ----- Method: LargeIntegersPlugin>>cDigitSub:len:with:len:into: (in
> category 'C core') -----
> + cDigitSub: pByteSmall len: smallLen with: pByteLarge len: largeLen into:
> pByteRes
> +       | z |
> - cDigitSub: pByteSmall
> -               len: smallLen
> -               with: pByteLarge
> -               len: largeLen
> -               into: pByteRes
> -       | z limit |
>         <var: #pByteSmall type: 'unsigned char * '>
>         <var: #pByteLarge type: 'unsigned char * '>
>         <var: #pByteRes type: 'unsigned char * '>
>
> +       z := 0. "Loop invariant is -1<=z<=1"
> +       0 to: smallLen - 1 do:
> -       z := 0.
> -       "Loop invariant is -1<=z<=1"
> -       limit := smallLen - 1.
> -       0 to: limit do:
>                 [:i |
>                 z := z + (pByteLarge at: i) - (pByteSmall at: i).
> +               pByteRes at: i put: z - (z // 256 * 256). "sign-tolerant
> form of (z bitAnd: 255)"
>

Frankly, having z declared unsigned int and just doing  pByteRes at: i put:
(z bitAnd: 16rFF) as I suggested would be way way simpler and will ALWAYS
work.
Why the hell invoke the complications of signed arithmetic when the content
pByteRes is unsigned???

Even if z is declared signed, (z bitAnd: 255) would work on a vast majority
of compiler/processor because most compiler/processor would use a
2-complement representation.
But it's technically implementation-defined.

+               z := z signedBitShift: -8].
>

i think this one is OK too on a vast majority of machines, but this is as
well technically implementation defined.
Some weird compiler/processor pair may as well fill left bits with zeroes,
or not even use 2-complement...

z here is a carry and should contain either 0, or -1 (that is UINT_MAX)
after this operation.



> +       smallLen to: largeLen - 1 do:
> -               pByteRes at: i put: z - (z // 256 * 256).
> -               "sign-tolerant form of (z bitAnd: 255)"
> -               z := z // 256].
> -       limit := largeLen - 1.
> -       smallLen to: limit do:
>                 [:i |
>                 z := z + (pByteLarge at: i) .
> +               pByteRes at: i put: z - (z // 256 * 256). "sign-tolerant
> form of (z bitAnd: 255)"
> +               z := z signedBitShift: -8].
> -               pByteRes at: i put: z - (z // 256 * 256).
> -               "sign-tolerant form of (z bitAnd: 255)"
> -               z := z // 256].
>   !
>

Isn't there another funny signed shift in Large Integer division?
This would deserve a review too, because division is inlining its own sort
of subtraction...
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20140701/d90a8f28/attachment-0001.htm


More information about the Vm-dev mailing list