tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Tinycc-devel] SSE calling convention bug


From: Michael Matz
Subject: Re: [Tinycc-devel] SSE calling convention bug
Date: Mon, 28 Oct 2019 09:32:23 +0000 (UTC)
User-agent: Alpine 2.21 (LSU 202 2017-01-01)

Hi,

On Sun, 27 Oct 2019, Herman ten Brugge via Tinycc-devel wrote:

> Look like the code in x86_64-gen.c is wrong. It should read:
> 
>                 if (sse_reg) { /* avoid redundant movaps %xmm0, %xmm0 */
>                     /* movaps %xmm1, %xmmN */
>                     o(0x280f);
>                     o(0xc1 + ((sse_reg+1) << 3));
>                     /* movaps %xmm0, %xmmN */
>                     o(0x280f);
>                     o(0xc0 + (sse_reg << 3));
>                 }

Yes.


Ciao,
Michael.

> 
> The problem occurs when sse_reg == 1. Because then xmm1 is overwritten before
> it is copied.
> 
>     Herman
> 
> On 2019-10-27 07:32, Christian Jullien wrote:
> > Trying your sample with mod on Windows -m64/-m32 I get:
> >
> > c: >tcc -m32 foo.c && foo
> > 5.000000
> >
> > c:>tcc -m64 foo.c && foo
> > 5.000000
> >
> > It only return 3.0000 on Linux x64 (I've not tested your code on Linux x86).
> >
> > C.
> >
> >
> > -----Original Message-----
> > From: Tinycc-devel [mailto:tinycc-devel-bounces+eligis=address@hidden]
> > On Behalf Of Shachaf Ben-Kiki
> > Sent: Saturday, October 26, 2019 12:59
> > To: address@hidden
> > Subject: [Tinycc-devel] SSE calling convention bug
> >
> > Hello,
> >
> > I ran into a bug in the SSE function call code in x86_64-gen.c. It's
> > in the following lines, in gfunc_call:
> >
> >                  if (sse_reg) { /* avoid redundant movaps %xmm0, %xmm0 */
> >                      /* movaps %xmm0, %xmmN */
> >                      o(0x280f);
> >                      o(0xc0 + (sse_reg << 3));
> >                      /* movaps %xmm1, %xmmN */
> >                      o(0x280f);
> >                      o(0xc1 + ((sse_reg+1) << 3));
> >                  }
> >
> > When sse_reg is %xmm1, this generates
> >
> >      0f 28 c8                movaps %xmm0,%xmm1
> >      0f 28 d1                movaps %xmm1,%xmm2
> >
> > Such that the first mov overwrites xmm1 before the second mov uses it.
> > Since the registers are used in reverse order and only one or two at a
> > time, I think swapping the order of the movs should be sufficient to
> > fix it.
> >
> > Here's a test case:
> >
> > #include <stdio.h>
> >
> > struct Point {
> >    float x;
> >    float y;
> > };
> >
> > struct Rect {
> >    struct Point top_left;
> >    struct Point size;
> > };
> >
> > float foo(struct Point p, struct Rect r) {
> >    return r.size.x;
> > }
> >
> > int main(int argc, char **argv) {
> >    struct Point p = {1, 2};
> >    struct Rect r = {{3, 4}, {5, 6}};
> >    printf("%f\n", foo(p, r));
> >    return 0;
> > }
> >
> > This program should print 5, but it prints 3 in tcc.
> >
> > Is this the right place to post this? I can post it elsewhere, or send
> > a patch (it took a while to track this down but I think the fix should
> > be easy).
> >
> > Thanks,
> >      Shachaf
> >
> > _______________________________________________
> > Tinycc-devel mailing list
> > address@hidden
> > https://lists.nongnu.org/mailman/listinfo/tinycc-devel
> >
> >
> 
> 
> _______________________________________________
> Tinycc-devel mailing list
> address@hidden
> https://lists.nongnu.org/mailman/listinfo/tinycc-devel
> 
> 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]