lightning
[Top][All Lists]
Advanced

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

Re: [Lightning] JIT_R11 trashed by jit_callr on MIPS32


From: Paul Cercueil
Subject: Re: [Lightning] JIT_R11 trashed by jit_callr on MIPS32
Date: Tue, 28 Oct 2014 19:38:25 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Icedove/31.0

Hi Paulo, thanks for the response.
Comments inlined below.

On 28/10/2014 00:03, Paulo César Pereira de Andrade wrote:
Em 27/10/2014 17:52, "Paul Cercueil" <address@hidden
<mailto:address@hidden>> escreveu:
 >
 > Hi,

   Hi,

 > I've been working for some time now on my spare time on a
MIPS-to-Lightning dynamic recompiler: https://github.com/pcercuei/lightrec/

   It looks very nice. On a quick look I only suggest not using
JIT_RA0, as you should be aware it is not available on all ports,
on ix86 parameters are passes on stack, and on ia64 the first
register argument has a variable value.

Thanks! But I know this very well. The problem is that I cannot use the jit_pushargr/jit_pushargi macros as they make Lightning crash (with an assertion failure). This is because all my blocks of code are created without a jit_prolog/jit_epilog; if I were to use them, it would create an enormous amount of overhead as Lightning would save/restore the registers on the stack for every single block of code recompiled, while I handle that elsewhere (in the "wrapper" block).


 > It abuses Lightning a little bit, in the way that it doesn't use
functions - the generated code directly jumps to the next block of code,
recompiling it if needed. It works fine on MIPS32 for now, except for
one point: jit_callr trashes the JIT_R11 register...

   I am afraid this is expected :(

 > Here's a minimal test case:
 >
 > <paul:~/dev/gcw0/lightrec> $ cat minimal.c
 > #include <lightning.h>
 >
 > static void get_new_function(void) { return &end_execution; }
 >
 > int main(int argc, char **argv)
 > {
 >         jit_state_t *_jit;
 >         init_jit(argv[0]);
 >
 >         _jit = jit_new_state();
 >
 >         jit_movi(JIT_R11, 54);
 >         jit_movi(JIT_R0, &get_new_function);
 >         jit_callr(JIT_R0);
 >
 >         jit_retval(JIT_R0);
 >         jit_addr(JIT_R0, JIT_R0, JIT_R11);
 >         jit_jmpr(JIT_R0);
 >
 >         jit_emit();
 >         jit_disassemble();
 >         jit_clear_state();
 >         jit_destroy_state();
 >         finish_jit();
 >
 >         return 0;
 > }
 >
 > The code basically sets the JIT_R11 register to 54, call
"get_new_function", adds JIT_R11 to the value returned and jumps to that
new address.
 >
 > This is what I obtain:
 >
 > opendingux:/media/data/local/home # ./minimal
 >         0x77295000      li      t9,54
 >         0x77295004      lui     v0,0x40
 >         0x77295008      ori     v0,v0,0x9d0
 >         0x7729500c      move    t9,v0
 >         0x77295010      jalr    v0
 >         0x77295014      nop
 >         0x77295018      addu    v0,v0,t9
 >         0x7729501c      jr      v0
 >         0x77295020      nop
 >
 > The LUI/ORI correspond the load of the address of get_new_function.
The jalr is the jit_callr. But between those, the JIT_R11 (register $t9
here) is trashed for no good reason.
 >
 > My current workaround is to completely avoid the use of JIT_R11, but
it would be great if it could be fixed :).

   Remember that JIT_R11 is not callee save, so, lightning is
supposed to be allowed to clobber it. A backend specific comment
should be added to the documentation about such special cases.

   t9 is the pic register. Lightning does not know if it is calling a
pic C function so if the jit_callr argument is not t9, it will set it to
the function pointer. A workaround in your code would be to
know about that.

Allright, I didn't know that. I knew about $gp (register #26) but not about $t9. Then I guess I will discard it when compiling on MIPS.


 > Thanks,
 >
 > Paul
 >

Thanks,
Paulo


Regards,

Paul



reply via email to

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