<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><br>Hi Nicolas,</div><div><br>On Nov 10, 2014, at 1:04 PM, Nicolas Cellier &lt;<a href="mailto:nicolas.cellier.aka.nice@gmail.com">nicolas.cellier.aka.nice@gmail.com</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><span></span></div></blockquote><blockquote type="cite"><div><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">2014-11-10 21:19 GMT+01: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">&nbsp;<br><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Nov 10, 2014 at 10:18 AM, 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> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">&nbsp;<br><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">2014-11-09 21:30 GMT+01:00 David T. Lewis <span dir="ltr">&lt;<a href="mailto:lewis@mail.msen.com" target="_blank">lewis@mail.msen.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"><div><div><br>
On Fri, Nov 07, 2014 at 12:55:03AM +0100, Nicolas Cellier wrote:<br>
&gt;<br>
&gt; I suggest using a bit xor ^ rather than subtraction - in generated code<br>
&gt;&nbsp; &nbsp; &nbsp;(receiver|mask)^mask<br>
&gt; because it is a simpler operation (it does not involve any carry)<br>
&gt;<br>
&gt; But generally, clearing a mask is rather written with bit and and bit<br>
&gt; inverse in C<br>
&gt;&nbsp; &nbsp; &nbsp;receiver &amp; ~mask<br>
&gt;<br>
&gt; The last one is even better because ~mask is trivial to evaluate at compile<br>
&gt; time if ever mask is a constant.<br>
&gt;<br>
&gt; I didn't try to measure if it makes any difference though.<br>
<br>
</div></div>I think that this may be a case where the use of C integer arithmetic<br>
is the safer choice.<br>
<br>
I tested your receiver &amp; ~mask change, and found that the generated<br>
code produced these changes in two places in interp.c (probably it<br>
will be more in oscog):<br>
<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;longAtput(thisReceiver, ((((longAt(thisReceiver)) | HashBits) - HashBits)) | ((hash &amp; HashMaskUnshifted) &lt;&lt; HashBitsOffset));<br>
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;longAtput(thisReceiver, ((((longAt(thisReceiver))) &amp; ~(HashBits))) | ((hash &amp; HashMaskUnshifted) &lt;&lt; HashBitsOffset));<br>
<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;longAtput(obj, (((hdr | (SIZE_MASK)) - (SIZE_MASK))) | ((hdr &amp; (SIZE_MASK)) - deltaBytes));<br>
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;longAtput(obj, (((hdr) &amp; ~((SIZE_MASK)))) | ((hdr &amp; (SIZE_MASK)) - deltaBytes));<br>
<br>
<br>
This looks good, and as far as I can tell it will cause no problems<br>
in practice for the two specific uses that I found in generating code<br>
for the interpreter VM.<br>
<br>
However, I do find one potential problem. If the receiver is a 64-bit<br>
value, as may be the case in a 64-bit image (image format 68002, or the<br>
upcoming 68019 64-bit Spur image), and if the argument is a constant<br>
defined in a C macro (hence presumed to be 32 bits), then we can get<br>
incorrect results from using the bitwise operations. The current<br>
implementation that uses subtraction does not have this problem.<br>
<br></blockquote><div><br></div><div>Ah yes, you're perfectly right, thanks for pointing this potential issue.<br></div><div>One would need to determine if receiver type is longer than parameter and then cast the parameter to longer type before bit-inverting... That's not difficult per se, but maybe not that easy with slang. I'll take a look.<br></div></div></div></div></blockquote><div><br></div><div>This prompts my memory.&nbsp; I changed it to use - precisely because it meant Slang didn't have to infer the size of the type.&nbsp; Let's just leave this be.&nbsp; The C compiler is probably smart enough to optimize to produce equivalent code and in the grand scheme of things this small change won't make any measurable difference.&nbsp; But making the change could indeed break 64-bit arithmetic in 32-bit contexts.&nbsp;</div></div></div></div></blockquote><div><br></div><div>I've just checked with a fairly old gcc (4.2.1), but it seems it does not so well with subtraction...<br></div><div>Here is a int bitclear(int) with a constant compiled with -02:<br><br></div><div>return (x|0x4)-0x4;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; orl&nbsp;&nbsp;&nbsp;&nbsp; $4, %edi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leal&nbsp;&nbsp;&nbsp; -4(%rdi), %eax<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leave<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret<br><br></div><div>return (x|0x4)^0x4;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; andl&nbsp;&nbsp;&nbsp; $-5, %edi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; movl&nbsp;&nbsp;&nbsp; %edi, %eax<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leave<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret<br><br></div><div>Same code for return x&amp;(~0x4);<br></div><div>(the move is only necessary because it's a function and would be removed otherwise)<br><br><div>So we could follow my first idea which was to use bitXor rather than subtraction and let the compiler do the rest...<br><br></div>Anyway, this shall not be easy to measure a difference, I agree.<br></div></div></div></div></div></blockquote><div><br></div>IMO, it will make no difference. &nbsp;Relatively low frequency register code will not be noticeable against memory access. &nbsp;Don't worry about it.<div><br></div><div><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br><br></div><div>Same thing if we replace the constant with a parameter int y, subtraction is not recogized as a bit-op:<br><br></div><div>subtraction:<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; orl&nbsp;&nbsp;&nbsp;&nbsp; %esi, %edi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; subl&nbsp;&nbsp;&nbsp; %esi, %edi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; movl&nbsp;&nbsp;&nbsp; %edi, %eax<br><br></div><div>bit xor or bit invert:<br></div><div><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; notl&nbsp;&nbsp;&nbsp; %esi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; andl&nbsp;&nbsp;&nbsp; %edi, %esi<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; movl&nbsp;&nbsp;&nbsp; %esi, %eax</div><div><br></div><div><br></div><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"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><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"><div class="gmail_extra"><div class="gmail_quote"><div><br>&nbsp;<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Here is a test program to illustrate:<br>
<br>
#include &lt;stdio.h&gt;<br>
<br>
// Constant declarations that might be used as arguments to bitClear:<br>
# define SIZE_MASK 0xfc<br>
# define LONG_SIZE_MASK 0xfffffffc<br>
<br>
int main() {<br>
&nbsp; &nbsp; &nbsp; &nbsp; // A 64 bit sqInt, e.g. in 64 bit image format 68002<br>
&nbsp; &nbsp; &nbsp; &nbsp; long long hdr = 0xffffffffffffffff;<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; long long i;<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; printf ("sizeof(hdr) ==&gt; %ld\n", sizeof(hdr));<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; // bitClear using current approach gives expected result<br>
&nbsp; &nbsp; &nbsp; &nbsp; i = (hdr | SIZE_MASK) - SIZE_MASK;<br>
&nbsp; &nbsp; &nbsp; &nbsp; printf("original implementation using bit or with subtract:\n");<br>
&nbsp; &nbsp; &nbsp; &nbsp; printf("0x%llx bitClear: 0x%x ==&gt; 0x%llx\n", hdr, SIZE_MASK, i);<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; // bitClear using proposed approach gives expected result<br>
&nbsp; &nbsp; &nbsp; &nbsp; printf("proposed implementation using bit and with negated mask:\n");<br>
&nbsp; &nbsp; &nbsp; &nbsp; i = hdr &amp; ~(SIZE_MASK);<br>
&nbsp; &nbsp; &nbsp; &nbsp; printf("0x%llx bitClear: 0x%x ==&gt; 0x%llx\n", hdr, SIZE_MASK, i);<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; // bitClear using current approach gives expected result<br>
&nbsp; &nbsp; &nbsp; &nbsp; i = (hdr | LONG_SIZE_MASK) - LONG_SIZE_MASK;<br>
&nbsp; &nbsp; &nbsp; &nbsp; printf("original implementation using bit or with subtract:\n");<br>
&nbsp; &nbsp; &nbsp; &nbsp; printf("0x%llx bitClear: 0x%x ==&gt; 0x%llx\n", hdr, LONG_SIZE_MASK, i);<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; // bitClear using proposed approach gives wrong result<br>
&nbsp; &nbsp; &nbsp; &nbsp; printf("proposed implementation using bit and with negated mask:\n");<br>
&nbsp; &nbsp; &nbsp; &nbsp; i = hdr &amp; ~(LONG_SIZE_MASK);<br>
&nbsp; &nbsp; &nbsp; &nbsp; printf("0x%llx bitClear: 0x%x ==&gt; 0x%llx\n", hdr, LONG_SIZE_MASK, i);<br>
}<br>
<br>
// Output of this test program:<br>
//<br>
// sizeof(hdr) ==&gt; 8<br>
// original implementation using bit or with subtract:<br>
// 0xffffffffffffffff bitClear: 0xfc ==&gt; 0xffffffffffffff03<br>
// proposed implementation using bit and with negated mask:<br>
// 0xffffffffffffffff bitClear: 0xfc ==&gt; 0xffffffffffffff03<br>
// original implementation using bit or with subtract:<br>
// 0xffffffffffffffff bitClear: 0xfffffffc ==&gt; 0xffffffff00000003<br>
// proposed implementation using bit and with negated mask:<br>
// 0xffffffffffffffff bitClear: 0xfffffffc ==&gt; 0x3<br></blockquote></div></div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div>best,<div>Eliot</div></div>
</div></div>
<br></blockquote></div><br></div></div>
</div></blockquote></div></body></html>