lightning
[Top][All Lists]
Advanced

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

Re: [Lightning] jit_qdivr_u trashes JIT_R0 on x86_64


From: Marc Nieper-Wißkirchen
Subject: Re: [Lightning] jit_qdivr_u trashes JIT_R0 on x86_64
Date: Wed, 4 Sep 2019 08:31:11 +0200

Hi Paulo,

Am So., 1. Sept. 2019 um 18:01 Uhr schrieb <address@hidden>:

[...]

> Message: 1
> Date: Sat, 31 Aug 2019 09:46:22 -0400
> From: Paulo César Pereira de Andrade
>         <address@hidden>
> To: Paul Cercueil <address@hidden>
> Cc: lightning <address@hidden>
> Subject: Re: [Lightning] jit_qdivr_u trashes JIT_R0 on x86_64

[...]

>   I believe the function your code calls is to avoid inlining identical code,
> if that is the case, you could use a simple block of code, to avoid the
> prolog/epilog cost. If it is a C function, the compiler should generate
> an optimized version, or you could write it in assembly.
>
>   For example, using the new 'live' wrapper (btw, in this specific
> example, using 'live' is not required, because it understands %r0 is
> live due to using it as a printf argument):
> """
> #define USE_JMPR    1
> .data    16
> fmt:
> .c    "%d %d %d\n"
> .code
>     jmpi main
> helper:
>     movi %v1 5
>     movi %v2 7
> #if USE_JMPR
>     jmpr %v0
> #else
>     jmpi label
> #endif
> main:
>     prolog
>     movi %v1 2
>     movi %v2 3
>     addr %r0 %v1 %v2
> #if USE_JMPR
>     movi %v0 label
> #endif
>     jmpi helper
> label:
> #if USE_JMPR
>     live %r0
> #endif
>     qdivr %v1 %v2 %v2 %v1
>     prepare
>         pushargi fmt
>         ellipsis
>         pushargr %r0
>         pushargr %v1
>         pushargr %v2
>     finishi @printf
>     ret
>     epilog
> """
>
>   Suppose 'helper' above is a common code, then, your code can
> just jump to the common code, and from the common code, jump
> back; you might also make it inside a jit function, because if the
> common code needs to spill/reload a temporary, it must have
> a stack frame, in that case, just create an block only reachable
> from a jump to the common code.
>   If the address to jump back is known, the helper code can jump
> back to it, allowing lightning to follow the jump and understand the
> live registers, otherwise, can use jmpr, passing the 'jump back'
> address in a register.
>   jmpr allows flexibility in that kind of construct, as well as different
> approaches for dispatch tables.
>   Another alternative is to use jit_tramp and jit_frame. See check/tramp.tst
> or check/ctramp.c for an example, implementing a Fibonacci number
> calculator and tail call optimized code.

To which extent is code like your example code guaranteed to work,
Paulo? For example, could we mark *all* registers live after "jmpi
helper"?

On some ports, like x86_64, a jmpi instruction needs a scratch
register, and when all registers are marked live after jmpi, the only
way to get a scratch register is to spill one live register before the
jmpi and reload it afterward.

Does GNU lightning work this way?

I have another question about your code: In the above example, the
callee-saved registers JIT_Vx are used to hold parameters for the
handler subroutine. Is it also possible to declare a caller-saved
register to use as an argument (in-going and/or out-going) for the
handler?

[...]

Cheers,

Marc



reply via email to

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