Hi
I'm doing a pass on the two complement chapter and small integer implementation
and I wanted to check the SmallInteger>>primitiveAdd see below:
stackIntegerValue extracts from a smalltalk integer the 31 encoding number bit.
I imagine that this is correct.
sqInt
stackIntegerValue(sqInt offset) {
DECL_MAYBE_SQ_GLOBAL_STRUCT
sqInt integerPointer;
integerPointer = longAt(GIV(stackPointer) + (offset * BytesPerWord));
/* begin checkedIntegerValueOf: */
if ((integerPointer & 1)) {
return (integerPointer >> 1);
}
else {
/* begin primitiveFail */
if (GIV(primFailCode) == 0) {
GIV(primFailCode) = 1;
}
return 0;
}
}
Now I have three questions:
- is two complement used to manage small integers at VM level?
I saw digitAdd on Integer and it deals with large integer.
- integerResult = (stackIntegerValue(1)) + (stackIntegerValue(0));
performs the real add. I imagine that it comes from plain C. Now does
anybody has an idea
where I could find the definition of such + procedure?
In ANSI C
- from the books, performing 54 - 5 is equivalent to adding the two
complement
i.e. 54 + 5' (two complement)
this work well for 54 - 5 correct results and we can follow it looking
at binary operations:
(2r110110 - 2r101) bitString
--> '0000000000000000000000000110001'
(2r110110 bitString)
--> '0000000000000000000000000110110'
2r101 bitString
--> '0000000000000000000000000000101'
2r101 negated bitString
--> '1111111111111111111111111111011'
Now doing 5 - 15 does not (or I miss something ilke always subtracting the
smaller one and taking the two complement of the smaller…)
so does anybody has the answer on how to perform 5 - 15 ?
static void
primitiveAdd(void) {
DECL_MAYBE_SQ_GLOBAL_STRUCT
sqInt integerResult;
char *sp;
/* begin pop2AndPushIntegerIfOK: */
integerResult = (stackIntegerValue(1)) + (stackIntegerValue(0));
if (GIV(primFailCode) == 0) {
if ((integerResult ^ (integerResult << 1)) >= 0) {
/* begin pop:thenPush: */
longAtput(sp = GIV(stackPointer) + ((2 - 1) *
BytesPerWord), ((integerResult << 1) | 1));
GIV(stackPointer) = sp;
}
else {
/* begin success: */
if (!(0)) {
if (GIV(primFailCode) == 0) {
/* Don't overwrite an error code that
has already been set. */
GIV(primFailCode) = 1;
}
}
}
}
}
Stef