<div dir="ltr"><div><div><div><div><div>Note that what I wrote for + is not exactly what&#39;s going on, because + has a special bytecode and would first invoke interpreter<br>bytecodePrimAdd<br>    | rcvr arg result |<br>    rcvr := self internalStackValue: 1.<br>    arg := self internalStackValue: 0.<br>    (objectMemory areIntegers: rcvr and: arg)<br>        ifTrue: [result := (objectMemory integerValueOf: rcvr) + (objectMemory integerValueOf: arg).<br>                (objectMemory isIntegerValue: result) ifTrue:<br>                    [self internalPop: 2 thenPush: (objectMemory integerObjectOf: result).<br>                    ^ self fetchNextBytecode &quot;success&quot;]]<br>        ifFalse: [self initPrimCall.<br>                self externalizeIPandSP.<br>                self primitiveFloatAdd: rcvr toArg: arg.<br>                self internalizeIPandSP.<br>                self successful ifTrue: [^ self fetchNextBytecode &quot;success&quot;]].<br><br>    messageSelector := self specialSelector: 0.<br>    argumentCount := 1.<br>    self normalSend<br><br>And this is not accounting for JIT which is inlining some of those primitives:<br>genPrimitiveAdd<br>    | jumpNotSI jumpOvfl |<br>    &lt;var: #jumpNotSI type: #&#39;AbstractInstruction *&#39;&gt;<br>    &lt;var: #jumpOvfl type: #&#39;AbstractInstruction *&#39;&gt;<br>    cogit mclassIsSmallInteger ifFalse:<br>        [^UnimplementedPrimitive].<br>    cogit genLoadArgAtDepth: 0 into: Arg0Reg.<br>    cogit MoveR: Arg0Reg R: ClassReg.<br>    jumpNotSI := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.<br>    self genRemoveSmallIntegerTagsInScratchReg: ClassReg.<br>    cogit AddR: ReceiverResultReg R: ClassReg.<br>    jumpOvfl := cogit JumpOverflow: 0.<br>    cogit MoveR: ClassReg R: ReceiverResultReg.<br>    cogit genPrimReturn.<br>    jumpOvfl jmpTarget: (jumpNotSI jmpTarget: cogit Label).<br>    ^CompletePrimitive<br><br>Or if you are after bit ops, here is an extract of the primitive table that is not currently used in the image:<br><br>        (34 primitiveBitAndLargeIntegers)<br>        (35 primitiveBitOrLargeIntegers)<br>        (36 primitiveBitXorLargeIntegers)<br><br></div>So you might want to implement<br></div>LargePositiveInteger&gt;&gt;bitAnd: arg<br></div>    &lt;primitive: 34&gt;<br></div>    ^super bitAnd: arg<br><br></div>and see if it already speed things up for you.<br></div><div class="gmail_extra"><br><div class="gmail_quote">2016-10-14 23:09 GMT+02:00 Nicolas Cellier <span dir="ltr">&lt;<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div><div><div><div><div><div><div>But the 32bits VM is already dealing with 64 bits integers specially.<br></div>Take + for example.<br></div>SmallInteger&gt;&gt;+ calls primitive: 1 (that is primitiveAdd)<br>LargePositiveInteger&gt;&gt;+ calls primitive: 21 (that is primitiveAddLargeIntegers)<br></div>Integer&gt;&gt;+ call digitAdd: which calls primitive: &#39;primDigitAdd&#39; module:&#39;LargeIntegers&#39;<br><br></div>So what happens if you peform 1&lt;&lt;63+1 ?<br></div>It calls primitive: 21 which is doing this:<br>primitiveAddLargeIntegers<br>    &quot;Primitive arithmetic operations for large integers in 64 bit range&quot;<br>    | a b result oopResult aIsNegative bIsNegative resultIsNegative oopArg oopRcvr |<br>    &lt;export: true&gt;<br>    &lt;var: &#39;a&#39; type: &#39;usqLong&#39;&gt;<br>    &lt;var: &#39;b&#39; type: &#39;usqLong&#39;&gt;<br>    &lt;var: &#39;result&#39; type: &#39;usqLong&#39;&gt;<br><br>    oopArg := self stackValue: 0.<br>    oopRcvr := self stackValue: 1.<br>    aIsNegative := self isNegativeIntegerValueOf: oopRcvr.<br>    bIsNegative := self isNegativeIntegerValueOf: oopArg.<br>    a := self magnitude64BitValueOf: oopRcvr.<br>    b := self magnitude64BitValueOf: oopArg.<br>    self successful ifFalse:[^nil].<br>    (aIsNegative = bIsNegative)<br>        ifTrue:<br>            [&quot;Protect against overflow&quot;<br>            a &gt; (16rFFFFFFFFFFFFFFFF - b) ifTrue: [self primitiveFail. ^nil].<br>            result := a + b.<br>            resultIsNegative := aIsNegative]<br>        ifFalse:<br>            [(a &gt;= b)<br>                ifTrue:<br>                    [result := a - b.<br>                    resultIsNegative := aIsNegative]<br>                ifFalse:<br>                    [result := b - a.<br>                    resultIsNegative := bIsNegative]].<br>    oopResult := self magnitude64BitIntegerFor: result neg: resultIsNegative.<br>    self successful ifTrue:[self pop: 2 thenPush: oopResult].<br><br></div>So you see, it just perform 64 bits arithmetic primitively.<br><br></div>However, if you do 1+(1&lt;&lt;63), then you invoke:<br>primitiveAdd<br><br>    self pop2AndPushIntegerIfOK: (self stackIntegerValue: 1) + (self stackIntegerValue: 0)<br><br></div>That will fail because the argument is not a SmallInteger. Then you fallback to Integer&gt;&gt;+ which invokes digitAdd:<br><br></div>The only thing that changes with 64bits spur VM is that SmallInteger have 61bits and can represent any int in ((1&lt;&lt;60) negated to: (1&lt;&lt;60-1)). So 1+(1&lt;&lt;59) would still be a SmallInteger, but the other examples above would run unchanged.<br><div><div><div><div><br><br></div></div></div></div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">2016-10-14 0:22 GMT+02:00 Benoit St-Jean <span dir="ltr">&lt;<a href="mailto:bstjean@yahoo.com" target="_blank">bstjean@yahoo.com</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div style="color:#000;background-color:#fff;font-family:times new roman,new york,times,serif;font-size:16px"><div id="m_-1771916347915130076m_3839342526852660740yui_3_16_0_ym19_1_1476379454522_45744" dir="ltr"><span id="m_-1771916347915130076m_3839342526852660740yui_3_16_0_ym19_1_1476379454522_46014">I was wondering if the 64-bit VM (such as the one for Squeak 5.1) will support 64-bit integer arithmetic with primitives for positive integers.  Right now, 64 positive integers support bitwise operations but through code (LargePositiveInteger).  Any plan to move those calculations/operations to primitives to speed things up?  <br></span></div><div dir="ltr" id="m_-1771916347915130076m_3839342526852660740yui_3_16_0_ym19_1_1476379454522_46058"><span id="m_-1771916347915130076m_3839342526852660740yui_3_16_0_ym19_1_1476379454522_46014"><br></span></div><div dir="ltr" id="m_-1771916347915130076m_3839342526852660740yui_3_16_0_ym19_1_1476379454522_46100"><span id="m_-1771916347915130076m_3839342526852660740yui_3_16_0_ym19_1_1476379454522_46014">That would be so wonderful and nice for someone like me wanting to fully use a 64-bit architecture &amp; Squeak/Cog/Pharo/Whatever/VM for a chess engine project!</span></div><div id="m_-1771916347915130076m_3839342526852660740yui_3_16_0_ym19_1_1476379454522_45883"> </div><div class="m_-1771916347915130076m_3839342526852660740signature" id="m_-1771916347915130076m_3839342526852660740yui_3_16_0_ym19_1_1476379454522_45831">----------------- <br>Benoît St-Jean <br>Yahoo! Messenger: bstjean
 <br>Twitter: @BenLeChialeux
 <br>Pinterest: benoitstjean
 <br>Instagram: Chef_Benito<br>IRC: lamneth
 <br>Blogue: <a href="http://endormitoire.wordpress.com" target="_blank">endormitoire.wordpress.com</a>
 <br>&quot;A standpoint is an intellectual horizon of radius zero&quot;.  (A. Einstein)</div></div></div><br><br>
<br></blockquote></div><br></div>
</div></div></blockquote></div><br></div>