[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