[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Lightning register liveliness
From: |
Paul Cercueil |
Subject: |
Lightning register liveliness |
Date: |
Thu, 09 Jan 2020 00:26:40 -0300 |
Hi Paulo,
I am facing a problem related to register liveliness. I could only
reproduce it on MinGW, I never faced it on Linux x86_64 or MIPS.
Here is an example code to reproduce the issue (sorry for the length).
It is not important to understand what the code does; what is important
to see, is that my JIT_V0 (== rbx), which is set at the very beginning
of the code and read back at the last opcode (provided that the node2
beqi branch is taken), is overwritten by the call to jit_ltr_u.
I know that Lightning assumes that the caller-saved registers are dead
after a function call, but there's no function call here.
Could you give me some light in why Lightning uses my registers? Do I
have to use jit_live() somewhere here?
Thanks,
-Paul
----------------------------------------------------
#include <lightning.h>
#define ADDR_REG JIT_V(JIT_V_NUM - 1)
#define CYCLE_REG JIT_V(JIT_V_NUM - 2)
int main(int argc, char **argv)
{
jit_state_t *_jit;
jit_node_t *node1, *node2, *node3;
init_jit(argv[0]);
_jit = jit_new_state();
jit_prolog();
jit_tramp(256);
jit_ldxi_i(JIT_V0, ADDR_REG, 0x40); // <---- JIT_V0 is set here,
jit_movi(JIT_V1, 0);
jit_addi(JIT_R2, JIT_V0, 0x40); // <---- JIT_V0 read here,
jit_andi(JIT_R2, JIT_R2, 0x1f9fffff);
node1 = jit_bgti(JIT_R2, 0x200000);
jit_andi(JIT_R1, JIT_R2, 0x1ffffc);
jit_lshi(JIT_R1, JIT_R1, 1);
jit_addr(JIT_R1, JIT_R1, ADDR_REG);
jit_stxi(0x51e0, JIT_R1, JIT_V1);
jit_movi(JIT_R1, 0x30000000);
jit_patch(node1);
jit_addr(JIT_R2, JIT_R2, JIT_R1);
jit_ldxi_i(JIT_V1, ADDR_REG, 0x8);
jit_str_s(JIT_R2, JIT_V1);
jit_ldxi_i(JIT_V2, ADDR_REG, 0x14);
jit_addi(JIT_V2, JIT_V2, 0x4);
jit_stxi_i(0x14, ADDR_REG, JIT_V2);
jit_ldxi_i(JIT_V2, ADDR_REG, 0x10);
jit_addi(JIT_V1, JIT_V2, 0x4);
jit_andi(JIT_R2, JIT_V1, 0x10000000);
jit_rshi_u(JIT_R2, JIT_R2, 6);
jit_ori(JIT_R2, JIT_R2, 0x1f9fffff);
jit_andr(JIT_V1, JIT_V1, JIT_R2);
jit_movi(JIT_R2, 0x30000000);
jit_addr(JIT_V1, JIT_V1, JIT_R2);
jit_ldr_i(JIT_V1, JIT_V1);
jit_ldxi_i(JIT_V3, ADDR_REG, 0x18);
jit_addi(JIT_V3, JIT_V3, 1);
jit_ldxi_i(JIT_V4, ADDR_REG, 0x28);
jit_extr_us(JIT_R0, JIT_V4);
jit_addr(JIT_V2, JIT_V2, JIT_V1);
jit_extr_us(JIT_V1, JIT_V3);
jit_stxi_i(0x18, ADDR_REG, JIT_V3);
jit_ltr_u(JIT_V1, JIT_V1, JIT_R0);
jit_stxi_i(0xc, ADDR_REG, JIT_R0);
jit_subi(CYCLE_REG, CYCLE_REG, 0x14);
node2 = jit_beqi(JIT_V1, 0);
jit_movi(JIT_V0, 0x80065ff8);
jit_stxi_i(0x8, ADDR_REG, JIT_V1);
jit_stxi_i(0x10, ADDR_REG, JIT_V2);
node3 = jit_jmpi();
jit_patch(node2);
jit_stxi_i(0xc, ADDR_REG, JIT_V0); // <---- JIT_V0 read here
jit_ret();
jit_epilog();
jit_emit();
jit_disassemble();
jit_clear_state();
jit_destroy_state();
return 0;
}
----------------------------------------------------
----------------------------------------------------
# ./test.exe
0x1250000 movsxd rbx,DWORD PTR [r15+0x40]
0x1250004 xor rdi,rdi
0x1250007 lea r11,[rbx+0x40]
0x125000b and r11,0x1f9fffff
0x1250012 cmp r11,0x200000
0x1250019 jg 0x1250040
0x125001f mov r10d,0x1ffffc
0x1250025 and r10,r11
0x1250028 lea r10,[r10*2+0x0]
0x1250030 add r10,r15
0x1250033 mov QWORD PTR [r10+0x51e0],rdi
0x125003a mov r10d,0x30000000
0x1250040 add r11,r10
0x1250043 movsxd rdi,DWORD PTR [r15+0x8]
0x1250047 mov WORD PTR [r11],di
0x125004b movsxd rsi,DWORD PTR [r15+0x14]
0x125004f add rsi,0x4
0x1250053 mov DWORD PTR [r15+0x14],esi
0x1250057 movsxd rsi,DWORD PTR [r15+0x10]
0x125005b lea rdi,[rsi+0x4]
0x125005f mov r11d,0x10000000
0x1250065 and r11,rdi
0x1250068 shr r11,0x6
0x125006c or r11,0x1f9fffff
0x1250073 and rdi,r11
0x1250076 mov r11d,0x30000000
0x125007c add rdi,r11
0x125007f movsxd rdi,DWORD PTR [rdi]
0x1250082 movsxd r12,DWORD PTR [r15+0x18]
0x1250086 add r12,0x1
0x125008a movsxd r13,DWORD PTR [r15+0x28]
0x125008e movzx rax,r13w
0x1250092 add rsi,rdi
0x1250095 movzx rdi,r12w
0x1250099 mov DWORD PTR [r15+0x18],r12d
0x125009d xor rbx,rbx <--------- RBX is cleared here!!
0x12500a0 cmp rdi,rax
0x12500a3 setb bl
0x12500a6 mov rdi,rbx
0x12500a9 mov DWORD PTR [r15+0xc],eax
0x12500ad sub r14,0x14
0x12500b1 test rdi,rdi
0x12500b4 je 0x12500d0
0x12500ba mov ebx,0x80065ff8
0x12500bf mov DWORD PTR [r15+0x8],edi
0x12500c3 mov DWORD PTR [r15+0x10],esi
0x12500c7 jmp 0x0 # __major_image_version__
0x12500cc nop DWORD PTR [rax+0x0]
0x12500d0 mov DWORD PTR [r15+0xc],ebx
----------------------------------------------------
- Lightning register liveliness,
Paul Cercueil <=