<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">2014-07-01 0:56 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"><br><div class="gmail_extra"><br><br><div class="gmail_quote">2014-07-01 0:41 GMT+02:00 Eliot Miranda <span dir="ltr">&lt;<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>&gt;</span>:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> <br><div dir="ltr">Hi All,<div><br></div><div>   sorry for that noise...<br><div><div class="gmail_extra">

<br><br><div class="gmail_quote"><div><div class="h5">On Mon, Jun 30, 2014 at 12:24 PM, Eliot Miranda <span dir="ltr">&lt;<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Hi All,<div><br></div><div>    I recently eliminated the optimization in Slang that replaces a division by a power of two with a shift, because the code cast the argument to signed, and hence broke unsigned division.  That&#39;s what used to be controlled by the UseRightShiftForDivide class var of CCodeGenerator.</div>



<div><br></div><div>Yesterday I found out that that optimization is the only thing that&#39;s keeping the LargeIntegers plugin afloat.  To whit:</div><div><br></div><div>LargeIntegersPlugin&gt;&gt;cDigitSub: pByteSmall<div>



<span style="white-space:pre-wrap">                </span>len: smallLen</div><div><span style="white-space:pre-wrap">                </span>with: pByteLarge</div><div><span style="white-space:pre-wrap">                </span>len: largeLen</div><div><span style="white-space:pre-wrap">                </span>into: pByteRes</div>



<div><span style="white-space:pre-wrap">        </span>| z limit |</div><div><span style="white-space:pre-wrap">        </span>&lt;var: #pByteSmall type: &#39;unsigned char * &#39;&gt;</div><div><span style="white-space:pre-wrap">        </span>&lt;var: #pByteLarge type: &#39;unsigned char * &#39;&gt;</div>



<div><span style="white-space:pre-wrap">        </span>&lt;var: #pByteRes type: &#39;unsigned char * &#39;&gt;</div><div><br></div><div><span style="white-space:pre-wrap">        </span>z := 0.</div><div><span style="white-space:pre-wrap">        </span>&quot;Loop invariant is -1&lt;=z&lt;=1&quot;</div>



<div><span style="white-space:pre-wrap">        </span>limit := smallLen - 1.</div><div><span style="white-space:pre-wrap">        </span>0 to: limit do: </div><div><span style="white-space:pre-wrap">                </span>[:i | </div><div>
<span style="white-space:pre-wrap">                </span>z := z + (pByteLarge at: i) - (pByteSmall at: i).</div><div><span style="white-space:pre-wrap">                </span>pByteRes at: i put: z - (z // 256 * 256).</div><div><span style="white-space:pre-wrap">                </span>&quot;sign-tolerant form of (z bitAnd: 255)&quot;</div>



<div><span style="white-space:pre-wrap">                </span>z := z // 256].</div><div><span style="white-space:pre-wrap">        </span>limit := largeLen - 1.</div><div><span style="white-space:pre-wrap">        </span>smallLen to: limit do: </div>



<div><span style="white-space:pre-wrap">                </span>[:i | </div><div><span style="white-space:pre-wrap">                </span>z := z + (pByteLarge at: i) .</div><div><span style="white-space:pre-wrap">                </span>pByteRes at: i put: z - (z // 256 * 256).</div>



<div><span style="white-space:pre-wrap">                </span>&quot;sign-tolerant form of (z bitAnd: 255)&quot;</div><div><span style="white-space:pre-wrap">                </span>z := z // 256].</div><div><br></div><div>The &quot;z := z // 256&quot;&#39;s at the end of the loops were being generated as</div>



<div><div>        z = ((sqInt) z) &gt;&gt; 8;</div><div> which is essential for the signed arithmetic implicit in &quot;z := z + (pByteLarge at: i) - (pByteSmall at: i)&quot; to work.</div></div><div><br></div><div>So what&#39;s the right thing to do?</div>



<div><br></div><div>In C -1 // 256 = 0, but in Smalltalk -1 // 256 = -1 (// rounds towards - infinity), whereas  (-1 quo: 256) = 0 (quo: rounds towards 0).</div><div><br></div><div>I could modify the code generator to generate Smalltalk semantics for //, but its not pretty (one has to check signedness, check if there&#39;s a remainder, etc).</div>



<div><br></div><div>What I&#39;d like is to have a signed bitShift:.  Wait you say, bitShift: is signed.  Ah, but the code generator generates unsigned shifts for all bitShift:&#39;s !!!!.</div><div><br></div><div>So some ideas:</div>



<div><br></div><div>1. change bitShift: to obey the type of the receiver (Slang allows one to type variables, defaulting to a singed long). This is my preference, but it risks breaking a good handful of negative bitShift: uses in plugins (which is where I&#39;m worried about regressions).</div>



<div><br></div><div>2. change bitShift: to obey explicit casts, generating a signed shift for </div><div>   foo asInteger bitShift: expr</div><div>   (self cCoerceSimple: #foo to: #sqInt) bitShift: expr</div><div>Seriously?!?! this stinks.</div>



<div><br></div><div>3. write</div><div><span style="white-space:pre-wrap">        </span>z := self cCode: [z &gt;&gt;= 8] inSmalltalk: [z // 256]</div><br>Seriously?!?! this stinks too.</div><div><br><div>Anything else that makes any sense?</div>


<span><font color="#888888"><div></div></font></span></div></div></blockquote><div><br></div></div></div><div>Doh:</div><div><br></div><div>Intger methdos for *VMMaker</div><div>signedBitShift: anInteger</div><div><span style="white-space:pre-wrap">        </span>&quot;For historical reasons Slang generates an unsigned shift from all of the shift operators &gt;&gt;, &lt;&lt; &amp; bitShift:.</div>


<div><span style="white-space:pre-wrap">        </span> These are too deeply entrenched to try and redefine the semantics.  So instead we provide a signed bitShift:</div><div><span style="white-space:pre-wrap">        </span> that signals to Slang that its argument should be cast to signed, not to unsigned, when being shifted.&quot;</div>


<div><span style="white-space:pre-wrap">        </span>^self bitShift: anInteger </div></div><div><br></div><div>apologies</div>-- <br>best,<div>Eliot</div>
</div></div></div></div>
<br></blockquote><div><br></div><div>Though remember that signed right shift is theoretically implementation defined (though I&#39;m not aware of a compiler/processor providing 0 expansion), and that signed right shift behavior is undefined in case of overflow...<br>
</div></div></div></div></blockquote><div>signed left shift is undefined in case of overflow<br></div><div>I should better read again before sending...<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>
<a href="http://stackoverflow.com/questions/4009885/arithmetic-bit-shift-on-a-signed-integer" target="_blank">http://stackoverflow.com/questions/4009885/arithmetic-bit-shift-on-a-signed-integer</a><br></div><div>C is a very strange language... Portable?<br>

</div><div>I just hate its (lack of) signed integer arithmetic model.<br></div></div><br></div></div>
</blockquote></div><br></div></div>