From: John M M. <jo...@sm...> - 2004-04-08 00:53:02
|
Ned I looked at this a year back in terms of checking for large integers that fit into 32bit since there is routines to load smallish large integers into 32bits. This made messing with calculations absolute 512MB > < 2 billion really fast. However this is rare in practice, some thought is required to watch out for large postive/negative integers and not screw up signage, and as Andreas pointed out to me small integer math is like 99.999ish %, with perhaps some float mixed in. followed by that large integer stuff requiring a send. Mmmm I'm not sure I've a change set, perhaps some C code if you want to look at it? On Apr 7, 2004, at 3:54 PM, Ned Konz wrote: > On Tuesday 06 April 2004 3:48 pm, Ian Piumarta wrote: >> On 06 Apr 2004, at 23:50, Yoshiki Ohshima wrote: >>> how about using "01" for OOP >>> and "00" for SmallInteger? Some processor's addressing mode let us >>> access the word-aligned memory with such pointer, while "no-tag" for >>> SmallInteger may save some bit-operations. >> >> Just another data point: some Smalltalk implementations put the >> SmallInteger tag in the topmost bit. This makes SI tag and overflow >> checks after arithmetic simpler: addition and subtraction work >> in-place, plus you can just look at the sign flag after the operation >> instead of "mask + test-zero" or "shift + xor + sign-test". >> >> On architectures where you can set the sign flag during move this can >> also often eliminate any need to mask and test on the tag bit; after a >> move you can "trap" immediately on (non-)SI oops. > > On a related note, does it seem wasteful to anyone but me that we do > the > following in primBytecodeAdd: > > int rcvr; > int arg; > > rcvr = longAt(localSP - (1 * 4)); > arg = longAt(localSP - (0 * 4)); > if (((rcvr & arg) & 1) != 0) /* areIntegers: rcvr and: arg */ > { > result = ((rcvr >> 1)) + ((arg >> 1)); > if ((result ^ (result << 1)) >= 0) /* isIntegerValue: result */ > { > /* begin internalPop:thenPush: */ > longAtput(localSP -= (2 - 1) * 4, ((result << 1) | 1)); > /* begin fetchNextBytecode */ > currentBytecode = byteAt(++localIP); > goto l9; > } > } > else > { > /* Try to add them as a float */ > /* If success, we're done. Get the next bytecode and loop */ > } > > /* otherwise, do a normal send */ > > > For a total operation count (not counting the stack load/store) of: > 1 AND > 2 bit tests > 2 right shifts > 2 left shifts > 1 OR > 1 XOR > 1 ADD > > when for the majority of additions (those that don't overflow 31 bits) > we only > have to add the top two values (resetting one low bit first so that we > don't > get a carry from B0 to B1). > > Seems like we could save the shifts in most cases by looking at the > top two > bits of the receiver and argument; if the sign bits are different or > the high > bits (B30) are both the same as the sign bits we aren't going to get > any > overflow. > > -- > Ned Konz > http://bike-nomad.com > GPG key ID: BEEA7EFE > > > ------------------------------------------------------- > This SF.Net email is sponsored by: IBM Linux Tutorials > Free Linux tutorial presented by Daniel Robbins, President and CEO of > GenToo technologies. Learn everything from fundamentals to system > administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click > _______________________________________________ > Squeak-VMdev mailing list > Squ...@li... > https://lists.sourceforge.net/lists/listinfo/squeak-vmdev > > -- ======================================================================== === John M. McIntosh <jo...@sm...> 1-800-477-2659 Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com ======================================================================== === |