[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
- Re: [Lightning] jit_qdivr_u trashes JIT_R0 on x86_64,
Marc Nieper-Wißkirchen <=