Hello Luis,<br><br>Sorry for the long silence, I was held up elsewhere.<br><br><div class="gmail_quote">On Mon, Mar 30, 2009 at 9:05 AM, Luís Oliveira <span dir="ltr"><<a href="mailto:luismbo@gmail.com">luismbo@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">2009/3/28 Jean-Claude Beaudoin <<a href="mailto:jean.claude.beaudoin@gmail.com">jean.claude.beaudoin@gmail.com</a>>:<br>

<div class="im">> Recent versions of GCC appear to be leaving spurious bits in the %eax<br>
> register used to return the value of a C function on x86 based platforms<br>
> when the return type is narrower than 32 bits (ie: short or char).<br>
<br>
</div>Is that a GCC bug or is that behaviour here to stay?</blockquote><div><br>As far as GCC is concerned there is no bug of its own in that area.<br>The oldest version of GCC I still have access to (3.4.6) shows that<br>
even back then GCC emitted code on the caller side that always<br>extracted from %eax only the relevant bits and widened properly<br>the result.  I suspect that GCC has always done this although maybe<br>not with the most efficient instruction sequence.  What changed,<br>
starting in 4.1.X (I think),  is that GCC started to use the upper part<br>of %eax on the callee side trusting that this would not influence the<br>caller side.  I would even say that 4.3 started to use this behavior<br>extensively.<br>
<br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
I'd like to make this work for all the supported Lisps but only when<br>
necessary. Can we check at compile time whether this workaround is<br>
needed? For example, would the following work? Define abs() with a<br>
short/char return value and check whether the upper bits are masked<br>
away.</blockquote><div><br>I just tried your idea and it works.  Here is the code I used:<br><br><br>--------------------------------------------------<br>;;~/bin/sbcl<br><br>(define-alien-routine ("abs" my-uabs) unsigned-char (i int :in))<br>
(define-alien-routine ("abs" my-abs) char (i int :in))<br><br>(format t "~%(my-abs #x0101) = ~S~%" (my-abs #x0101))<br>(format t "~%(my-abs #x080) = ~S~%" (my-abs #x080))<br>(format t "~%(my-uabs #x0101) = ~S~%" (my-uabs #x0101))<br>
(format t "~%(my-uabs #x181) = ~S~%" (my-uabs #x181))<br><br><br>(let ((val (my-uabs #x181)))<br>  (cond ((= #x81 val)<br>     (format t "unsigned-char widened properly.~%")<br>     )<br>    ((= #x181 val)<br>
     (format t "unsigned-char NOT widened properly.~%")<br>     )<br>    ((> 0 val)<br>     (format t "unsigned-char got sign extended!~%")<br>     )<br>    (t (format t "Stupefying result! val = ~D (#x~X).~%" val val))<br>
    )<br>  )<br><br><br>;(quit)<br>--------------------------------------------------------<br><br>The proper results should be 1, -128, 1, 129.<br><br>SBCL got partially fixed in 1.0.25 for the "signed char" and "signed short" case, and<br>
I submitted a patch to be hopefully included in 1.0.28 for the "unsigned" cases.<br>Prior to these, every other version of SBCL out there has the weakness.<br>By the way, CMUCL has the same problem.<br><br>Cheers,<br>
<br>Jean-Claude Beaudoin<br><br> </div><br></div><br>