[Vm-dev] Re: 64bits Alien testSignedLong failing

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Thu Aug 18 01:41:42 UTC 2016


Arghh... I forgot this one which is preempting my asUnsignedInteger cast:


generateIntegerObjectOf: msgNode on: aStream indent: level
    "Generate the C code for this message onto the given stream."
    | expr castToSqint |
    expr := msgNode args first.
    aStream nextPutAll: '(('.
    "Note that the default type of an integer constant in C is int.  Hence
we /must/
     cast constants to long if in the 64-bit world, since e.g. in 64-bits
        (int)(16r1FFFFF << 3) = (int)16rFFFFFFF8 = -8
     whereas
        (long)(16r1FFFFF << 3) = (long) 16rFFFFFFF8 = 4294967288."
    castToSqint := expr isConstant and: [vmClass isNil or: [vmClass
objectMemoryClass wordSize = 8]].
    castToSqint ifTrue:
        [aStream nextPutAll: '(sqInt)'].
    self emitCExpression: expr on: aStream.
    aStream
        nextPutAll: ' << ';
        print: vmClass objectMemoryClass numSmallIntegerTagBits;
        nextPutAll: ') | 1)'

I think we should completely remove this from translationDictionary... It's
not object oriented.

2016-08-18 3:19 GMT+02:00 Nicolas Cellier <
nicolas.cellier.aka.nice at gmail.com>:

> The test fails with -2^31 and 2^31-1
> It's not so amazing, because when I debug, I find this incorrect version:
>
>    64769    sqInt
>    64770    signed32BitIntegerFor(sqInt integerValue)
>    64771    {
> -> 64772        return (((((int) integerValue)) << 3) | 1);
>    64773
>    64774    }
>    64775
>
> of course, the shift will overflow for large positive or large negative
> 32bits int.
> But I don't understand how it's been generated...
> I would expect
>     return ((((usqInt)((int) integerValue)) << 3) | 1);
>
> Indeed:
>
> signed32BitIntegerFor: integerValue
>     "Answer a full 32 bit integer object for the given integer value.
>      N.B.  Returning in each arm separately enables Slang inlining.
>      /Don't/ return the ifTrue:ifFalse: unless Slang inlining of
> conditionals is fixed."
>     <inline: true>
>     objectMemory hasSixtyFourBitImmediates
>         ifTrue:
>             [^objectMemory integerObjectOf:
>                 (self cCode: [self cCoerceSimple: integerValue to: #int]
>                     inSmalltalk: [(integerValue bitAnd: 16r7FFFFFFF)
>                                 - ((integerValue >> 31 anyMask: 1)
>                                     ifTrue: [-16r100000000]
>                                     ifFalse: [0])])]
>         ifFalse:
>             [^self noInlineSigned32BitIntegerFor: integerValue]
>
> has the cast to int.
> Then there is another cast here:
>
> integerObjectOf: value
>     "Convert the integer value, assumed to be in SmallInteger range, into
> a tagged SmallInteger object.
>      In C, use a shift and an add to set the tag bit.
>      In Smalltalk we have to work harder because the simulator works with
> strictly positive bit patterns."
>     <returnTypeC: #sqInt>
>     ^self
>         cCode: [value asUnsignedInteger << self numTagBits + 1]
>         inSmalltalk: [value << self numTagBits
>                     + (value >= 0
>                         ifTrue: [1]
>                         ifFalse: [16r10000000000000001])]
>
> and asUnsignedInteger is translated like this by CCodeGenerator:
>
> generateAsUnsignedInteger: msgNode on: aStream indent: level
>     "Generate the C code for this message onto the given stream."
>
>     aStream nextPutAll:'((usqInt)'.
>     self emitCExpression: msgNode receiver on: aStream.
>     aStream nextPut: $)
>
> How the hell could the hardcoded (usqInt) be not generated?
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20160818/1e18df2f/attachment-0001.htm


More information about the Vm-dev mailing list