washingtondc-emu / washingtondc

Open-source Sega Dreamcast emulator
http://www.washemu.org
GNU General Public License v3.0
240 stars 7 forks source link

jit register juggling before function call emits #75

Open snickerbockers opened 4 years ago

snickerbockers commented 4 years ago

Before function calls, the jit often emits code with redundant register moves:

000056078E16B630: push rbp
000056078E16B631: mov rbp, rsp
000056078E16B634: movabs rbx, 0x56078c4a6440
000056078E16B63E: mov ebx, dword ptr [rbx]
000056078E16B640: movabs r15, 0x56078d28018c
000056078E16B64A: mov edi, ebx
000056078E16B64C: mov ebx, edi
000056078E16B64E: add rsp, -8
000056078E16B652: movabs r10, 0x7f67f0000930
000056078E16B65C: call r10

in this case, emit_read_32_slot is creating the move, but there are several other implementations in the JIT with similar logic.

        move_slot_to_reg(blk, addr_slot, REG_ARG0);
        evict_register(blk, &gen_reg_state, REG_ARG0);
        native_mem_read_32(blk, map);

It happens because the slot residency gets moved from ebx to edi in move_slot_to_reg, and then evict_register moves it back to ebx to protect it from the function call emitted by native_mem_read_32. It should instead remember that there is still a copy of the slot in ebx and update the residency to point to that without emitting a mov instruction.