[Vm-dev] Fix for broken integer arithmetic on 64 bit image/32 bit
host
David T. Lewis
lewis at mail.msen.com
Sun Nov 12 23:26:07 UTC 2006
Unfortunately, I made an error in testing this on 64 bit image/64 bit hosts,
for which this patch did *not* work.
A corrected patch is on Mantis, which now uses this Smalltalk:
isIntegerValue: intValue
^ self isDefined: 'SQ_HOST32'
inSmalltalk: [true]
comment: 'cast to int for 64 bit image on 32 bit host'
ifTrue: ((self cCoerce: intValue to: 'int')
bitXor: ((self cCoerce: intValue to: 'int') << 1)) >= 0
ifFalse: (self explicitCheckIsIntegerValue: intValue)
explicitCheckIsIntegerValue: valueWord
^ valueWord >= 16r-40000000 and: [valueWord <= 16r3FFFFFFF]
which generates the C function:
sqInt isIntegerValue(sqInt intValue) {
return
# ifdef SQ_HOST32 // cast to int for 64 bit image on 32 bit host
(((((int) intValue)) ^ ((((int) intValue)) << 1)) >= 0)
# else
(((intValue >= -1073741824) && (intValue <= 1073741823)) >= 0)
# endif // SQ_HOST32
;
}
and inlined C code such as this:
if (
# ifdef SQ_HOST32 // cast to int for 64 bit image on 32 bit host
(((((int) integerResult)) ^ ((((int) integerResult)) << 1)) >= 0)
# else
(((integerResult >= -1073741824) && (integerResult <= 1073741823)) >= 0)
# endif // SQ_HOST32
) {
Dave
On Sat, Nov 11, 2006 at 03:07:58PM -0500, David T. Lewis wrote:
>
> There is a bug (Mantis 5238) with integer arithmetic on 64 bit images running
> on 32 bit hosts.
>
> I have been pecking away at this bug for a while now, and I have come up with
> a solution. In a nutshell, the solution I'm proposing is to add C preprocessor
> capability to Slang, then change ObjectMemory>>isIntegerValue: to this:
>
> ^ self isDefined: 'SQ_HOST32'
> inSmalltalk: [true]
> comment: 'cast to int for 64 bit image on 32 bit host'
> ifTrue: ((self cCoerce: intValue to: 'int')
> bitXor: ((self cCoerce: intValue to: 'int') << 1)) >= 0
> ifFalse: (intValue bitXor: (intValue << 1)) >= 0
>
> Which generates the following C code:
>
> sqInt isIntegerValue(sqInt intValue) {
> return
> # ifdef SQ_HOST32 // cast to int for 64 bit image on 32 bit host
> ((((int) intValue)) ^ ((((int) intValue)) << 1)) >= 0
> # else
> (intValue ^ (intValue << 1)) >= 0
> # endif // SQ_HOST32
> ;
> }
>
> The method is still inlined throughout the interpreter, with generated code
> such as this:
>
> /* begin storeInteger:ofObject:withValue: */
> if (
> # ifdef SQ_HOST32 // cast to int for 64 bit image on 32 bit host
> ((((int) (evtBuf[0]))) ^ ((((int) (evtBuf[0]))) << 1)) >= 0
> # else
> ((evtBuf[0]) ^ ((evtBuf[0]) << 1)) >= 0
> # endif // SQ_HOST32
> ) {
> longAtput((arg + BaseHeaderSize) + (0 << ShiftForWord), (((evtBuf[0]) << 1) | 1));
> } else {
> /* begin primitiveFail */
> foo->successFlag = 0;
> }
>
>
> While this adds some complexity to the C code generator, it produces correct
> results on all combinations of 32/64 bit image and host, and requires no
> additional platform support files. It also preserves the speed advantage of
> Tim's current #isIntegerValue: (which unfortunately did not work for 64 bit
> images on 32 bit hosts).
>
> Comments?
>
> Dave
More information about the Vm-dev
mailing list