(head*halfPower) as: ByteArray.{This is independent of my recent changes of LargeIntegers plugin as it happens BEFORE these changes and is related to primitive 29 rather than to the plugin...Hi,before I continue, i've noticed that the large integer multiply seems broken on v3 object memory (cog & stack)Note that this does not happen on Spur.
Here are the symptoms:
halfPower := 10000.
s := 111111111111111.
head := s quo: halfPower.
tail := s - (head * halfPower).
head as: ByteArray.
(1 to: halfPower digitLength) collect: [:i | halfPower digitAt: i] as: ByteArray.
}.the correct result is:
#(#[199 25 70 150 2] #[16 39] #[112 237 78 18 14 101])the wrong result I obtained with SVN revision 3651 compiled by myself is:
#(#[199 25 70 150 2] #[16 39] #[112 237 78 18 254 61])The most significant bits (above 32) are wrong...The pattern I obtain is (with most significant bit put back left)2r00111101 << 8 + 2r11111110 "wrong result"2r01100101 << 8 + 2r00001110 "Correct result"I completely fail to infer what's going on from this pattern...This is on MacOSX clang --version
Apple LLVM version 7.3.0 (clang-703.0.29)
Target: x86_64-apple-darwin15.4.0This goes thru primitiveMultiplyLargeIntegers (29)
oopResult := self magnitude64BitIntegerFor: result neg: aIsNegative ~= bIsNegative.
-> sz > 4
ifTrue: [objectMemory storeLong64: 0 ofObject: newLargeInteger withValue: magnitude](which I changed recently)then:
storeLong64: longIndex ofObject: oop withValue: value
<var: #value type: #sqLong>
self flag: #endianness.
self long32At: oop + self baseHeaderSize + (longIndex << 3) put: (self cCode: [value] inSmalltalk: [value bitAnd: 16rFFFFFFFF]);
long32At: oop + self baseHeaderSize + (longIndex << 3) + 4 put: (value >> 32).
^valueI don't see anything wrong with this code...
Well, using a shift on signed value is not that good, but it works for at least 3 reasons:
- we throw the signBit extension away
- slang inlining misses the signedness difference, and the generated C code is correct.
- Anyway, in our case, the sign bit was 0...
Previous implementation in magnitude64BitIntegerFor:neg: was:
sz > 4 ifTrue:
[objectMemory storeLong32: 1 ofObject: newLargeInteger withValue: magnitude >> 32].
objectMemory
storeLong32: 0
ofObject: newLargeInteger
withValue: (self cCode: [magnitude] inSmalltalk: [magnitude bitAnd: 16rFFFFFFFF])Not much different, except that the high 32 bits and low 32 bits are written in a different order...
If I had a server I'd like to bisect- from which version does this happens- for which OS- for which compilerWithout such information, I think I'll have to debug it either thru simulator or directly in gdb, but I feel like I'm really losing my time :(And I've got a 2nd problem like this one...