[Vm-dev] CCodeGeneration bug or gcc compiler bug?
Eliot Miranda
eliot.miranda at gmail.com
Sat Apr 6 06:37:06 UTC 2013
Hi Nicolas,
I think this is bad parenthesization. I think it's fixed in the Cog
branch (at least I remember fixing it). Try it in Cog. Its late but I'll
try and find the fix some time soon.
On Fri, Apr 5, 2013 at 1:52 PM, Nicolas Cellier <
nicolas.cellier.aka.nice at gmail.com> wrote:
>
> Let me think aloud...
>
> THE CONTEXT:
>
> backport of LargeIntegersPlugin v2.0 (32 bit native word order) to
> Interpreter VM
>
> THE BUG:
>
> The Vm crashes with
> http://smalltalkhub.com/#!/~nice/NiceVMExperiments/versions/VMMaker-nice.315
>
> THE OFFENDING METHOD:
>
> InterpreterPrimitives>>magnitude64BitIntegerFor: magnitude neg: isNegative
> "Return a Large Integer object for the given integer magnitude and
> sign"
> | newLargeInteger largeClass lowWord highWord sz isSmall smallVal
> highWord2 |
> <var: 'magnitude' type: #usqLong>
> <var: 'lowWord' type: #usqInt>
> <var: 'highWord' type: #usqInt>
> <var: 'highWord2' type: #usqInt>
>
> isSmall := isNegative
> ifTrue: [magnitude <= 16r40000000]
> ifFalse: [magnitude < 16r40000000].
> isSmall ifTrue:
> [smallVal := self cCoerceSimple: magnitude to: #sqInt.
> isNegative ifTrue: [smallVal := 0 - smallVal].
> ^objectMemory integerObjectOf: smallVal].
> largeClass := isNegative
> ifTrue:[self classLargeNegativeInteger]
> ifFalse:[self classLargePositiveInteger].
> lowWord := magnitude bitAnd: 16rFFFFFFFF.
> highWord := magnitude >> 32.
> highWord = 0
> ifTrue: [sz := 4]
> ifFalse:
> [sz := 5.
> (highWord2 := highWord >> 8) = 0 ifFalse: [sz := sz + 1].
> (highWord2 := highWord2 >> 8) = 0 ifFalse: [sz := sz + 1].
> (highWord2 := highWord2 >> 8) = 0 ifFalse: [sz := sz + 1].].
> newLargeInteger := objectMemory instantiateClass: largeClass
> indexableSize: sz.
> objectMemory storeLong32: 0 ofObject: newLargeInteger withValue:
> lowWord.
> sz > 4 ifTrue: [objectMemory storeLong32: 1 ofObject: newLargeInteger
> withValue: highWord].
> ^newLargeInteger
>
> THE CORRECTED METHOD:
>
> just replace the assignment
>
> isNegative
> ifTrue:[ largeClass := self classLargeNegativeInteger]
> ifFalse:[ largeClass := self classLargePositiveInteger].
>
> THE OFFENDING GENERATED CODE:
>
> in src/vm/interp.c
>
> sqInt magnitude64BitIntegerForneg(usqLong magnitude, sqInt isNegative) {
> register struct foo * foo = &fum;
> usqInt highWord;
> usqInt highWord2;
> sqInt isSmall;
> sqInt largeClass;
> usqInt lowWord;
> sqInt newLargeInteger;
> sqInt smallVal;
> sqInt sz;
> sqInt oop;
> sqInt oop1;
>
> isSmall = (isNegative
> ? magnitude <= 1073741824
> : magnitude < 1073741824);
> if (isSmall) {
> smallVal = ((sqInt) magnitude);
> if (isNegative) {
> smallVal = 0 - smallVal;
> }
> return ((smallVal << 1) | 1);
> }
> largeClass = (isNegative
> ? /* begin fetchPointer:ofObject: */(oop =
> foo->specialObjectsOop),longAt((oop + (BASE_HEADER_SIZE)) +
> (ClassLargeNegativeInteger << (SHIFT_FOR_WORD)))
> : /* begin fetchPointer:ofObject: */(oop1 =
> foo->specialObjectsOop),longAt((oop1 + (BASE_HEADER_SIZE)) +
> (ClassLargePositiveInteger << (SHIFT_FOR_WORD))));
> lowWord = magnitude & 4294967295U;
> highWord = magnitude >> 32;
> if (highWord == 0) {
> sz = 4;
> } else {
> sz = 5;
> if (!(((highWord2 = ((usqInt) highWord) >> 8)) == 0)) {
> sz += 1;
> }
> if (!(((highWord2 = ((usqInt) highWord2) >> 8)) == 0)) {
> sz += 1;
> }
> if (!(((highWord2 = ((usqInt) highWord2) >> 8)) == 0)) {
> sz += 1;
> }
> }
> newLargeInteger = instantiateClassindexableSize(largeClass, sz);
> long32Atput((newLargeInteger + (BASE_HEADER_SIZE)) + (0 << 2),
> lowWord);
> if (sz > 4) {
> long32Atput((newLargeInteger + (BASE_HEADER_SIZE)) + (1 << 2),
> highWord);
> }
> return newLargeInteger;
> }
>
> THE CORRECTED GENERATED CODE:
>
> Just change the ()?: assignment:
>
> largeClass = (isNegative
> ? /* begin fetchPointer:ofObject: */(oop =
> foo->specialObjectsOop),longAt((oop + (BASE_HEADER_SIZE)) +
> (ClassLargeNegativeInteger << (SHIFT_FOR_WORD)))
> : /* begin fetchPointer:ofObject: */(oop1 =
> foo->specialObjectsOop),longAt((oop1 + (BASE_HEADER_SIZE)) +
> (ClassLargePositiveInteger << (SHIFT_FOR_WORD))));
>
> with an explicit if:
>
> if (isNegative) {
> /* begin fetchPointer:ofObject: */
> oop = foo->specialObjectsOop;
> largeClass = longAt((oop + (BASE_HEADER_SIZE)) +
> (ClassLargeNegativeInteger << (SHIFT_FOR_WORD)));
> } else {
> /* begin fetchPointer:ofObject: */
> oop1 = foo->specialObjectsOop;
> largeClass = longAt((oop1 + (BASE_HEADER_SIZE)) +
> (ClassLargePositiveInteger << (SHIFT_FOR_WORD)));
> }
>
> THE OFFENDING METHOD JUST WORKS IN COG BUT GENERATED CODE IS DIFFERENT:
>
> largeClass = (isNegative
> ? longAt((GIV(specialObjectsOop) + BaseHeaderSize) +
> (ClassLargeNegativeInteger << ShiftForWord))
> : longAt((GIV(specialObjectsOop) + BaseHeaderSize) +
> (ClassLargePositiveInteger << ShiftForWord)));
>
> THE QUESTION:
>
> I just don't understand what is incorrect in the (t)?a,b:c,d; construct...
> Could it be that it is interpreted:
>
> ((t)?a,b:c),d;
>
> Ah if so, maybe that would explain the warning about oop1 being
> potentially used before assigned! (a bulb just enlighten)
>
> In this case we have a bug in the generator (probably a known one since we
> rearely ever use x := test ifTrue: [] ifFalse: [] in Slang)...
>
> Nicolas
>
>
>
>
>
>
--
best,
Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20130405/95b7045d/attachment.htm
More information about the Vm-dev
mailing list