[squeak-dev] 64 bit integer arithmetic

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Fri Oct 14 21:09:51 UTC 2016


But the 32bits VM is already dealing with 64 bits integers specially.
Take + for example.
SmallInteger>>+ calls primitive: 1 (that is primitiveAdd)
LargePositiveInteger>>+ calls primitive: 21 (that is
primitiveAddLargeIntegers)
Integer>>+ call digitAdd: which calls primitive: 'primDigitAdd'
module:'LargeIntegers'

So what happens if you peform 1<<63+1 ?
It calls primitive: 21 which is doing this:
primitiveAddLargeIntegers
    "Primitive arithmetic operations for large integers in 64 bit range"
    | a b result oopResult aIsNegative bIsNegative resultIsNegative oopArg
oopRcvr |
    <export: true>
    <var: 'a' type: 'usqLong'>
    <var: 'b' type: 'usqLong'>
    <var: 'result' type: 'usqLong'>

    oopArg := self stackValue: 0.
    oopRcvr := self stackValue: 1.
    aIsNegative := self isNegativeIntegerValueOf: oopRcvr.
    bIsNegative := self isNegativeIntegerValueOf: oopArg.
    a := self magnitude64BitValueOf: oopRcvr.
    b := self magnitude64BitValueOf: oopArg.
    self successful ifFalse:[^nil].
    (aIsNegative = bIsNegative)
        ifTrue:
            ["Protect against overflow"
            a > (16rFFFFFFFFFFFFFFFF - b) ifTrue: [self primitiveFail.
^nil].
            result := a + b.
            resultIsNegative := aIsNegative]
        ifFalse:
            [(a >= b)
                ifTrue:
                    [result := a - b.
                    resultIsNegative := aIsNegative]
                ifFalse:
                    [result := b - a.
                    resultIsNegative := bIsNegative]].
    oopResult := self magnitude64BitIntegerFor: result neg:
resultIsNegative.
    self successful ifTrue:[self pop: 2 thenPush: oopResult].

So you see, it just perform 64 bits arithmetic primitively.

However, if you do 1+(1<<63), then you invoke:
primitiveAdd

    self pop2AndPushIntegerIfOK: (self stackIntegerValue: 1) + (self
stackIntegerValue: 0)

That will fail because the argument is not a SmallInteger. Then you
fallback to Integer>>+ which invokes digitAdd:

The only thing that changes with 64bits spur VM is that SmallInteger have
61bits and can represent any int in ((1<<60) negated to: (1<<60-1)). So
1+(1<<59) would still be a SmallInteger, but the other examples above would
run unchanged.



2016-10-14 0:22 GMT+02:00 Benoit St-Jean <bstjean at yahoo.com>:

> I was wondering if the 64-bit VM (such as the one for Squeak 5.1) will
> support 64-bit integer arithmetic with primitives for positive integers.
> Right now, 64 positive integers support bitwise operations but through code
> (LargePositiveInteger).  Any plan to move those calculations/operations to
> primitives to speed things up?
>
> That would be so wonderful and nice for someone like me wanting to fully
> use a 64-bit architecture & Squeak/Cog/Pharo/Whatever/VM for a chess engine
> project!
>
> -----------------
> Benoît St-Jean
> Yahoo! Messenger: bstjean
> Twitter: @BenLeChialeux
> Pinterest: benoitstjean
> Instagram: Chef_Benito
> IRC: lamneth
> Blogue: endormitoire.wordpress.com
> "A standpoint is an intellectual horizon of radius zero".  (A. Einstein)
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20161014/085a5b06/attachment.htm


More information about the Squeak-dev mailing list