From 86205daf1ba2a353270b425888c14127655d47db Mon Sep 17 00:00:00 2001 From: Anthony Pesch Date: Thu, 23 Nov 2017 23:15:16 -0500 Subject: [PATCH] made rsi / rdi registers callee-saved on windows made xmm registers caller-saved on linux / mac added x64_backend_push_regs and x64_backend_pop_regs helpers --- src/jit/backend/x64/x64_backend.cc | 218 +++++++++++++--------- src/jit/backend/x64/x64_dispatch.cc | 33 +--- src/jit/backend/x64/x64_local.h | 4 +- src/jit/jit_backend.h | 28 +-- src/jit/passes/register_allocation_pass.c | 18 +- 5 files changed, 164 insertions(+), 137 deletions(-) diff --git a/src/jit/backend/x64/x64_backend.cc b/src/jit/backend/x64/x64_backend.cc index f5e1e46c..851bcdd6 100644 --- a/src/jit/backend/x64/x64_backend.cc +++ b/src/jit/backend/x64/x64_backend.cc @@ -15,34 +15,6 @@ extern "C" { * x64 register layout */ -/* %rax %eax %ax %al <-- both: temporary - %rcx %ecx %cx %cl <-- both: argument - %rdx %edx %dx %dl <-- both: argument - %rbx %ebx %bx %bl <-- both: available (callee saved) - %rsp %esp %sp %spl <-- both: reserved - %rbp %ebp %bp %bpl <-- both: available (callee saved) - %rsi %esi %si %sil <-- msvc: available (callee saved), amd64: argument - %rdi %edi %di %dil <-- msvc: available (callee saved), amd64: argument - %r8 %r8d %r8w %r8b <-- both: argument - %r9 %r9d %r9w %r9b <-- both: argument - %r10 %r10d %r10w %r10b <-- both: available (not callee saved) - %r11 %r11d %r11w %r11b <-- both: available (not callee saved) - %r12 %r12d %r12w %r12b <-- both: available (callee saved) - %r13 %r13d %r13w %r13b <-- both: available (callee saved) - %r14 %r14d %r14w %r14b <-- both: available (callee saved) - %r15 %r15d %r15w %r15b <-- both: available (callee saved) - - msvc calling convention uses rcx, rdx, r8, r9 for arguments - amd64 calling convention uses rdi, rsi, rdx, rcx, r8, r9 for arguments - both use the same xmm registers for floating point arguments - our largest function call uses only 3 arguments - msvc is left with rax, rsi, rdi, r10 and r11 - amd64 is left with rax, r8, r9, r10 and r11 - - rax is used as a scratch register - r10, r11, xmm1 are used for constant not eliminated by const propagation - r14, r15 are reserved for the context and memory pointers */ - /* clang-format off */ #if PLATFORM_WINDOWS const int x64_arg0_idx = Xbyak::Operand::RCX; @@ -64,29 +36,64 @@ const Xbyak::Reg64 guestctx(Xbyak::Operand::R14); const Xbyak::Reg64 guestmem(Xbyak::Operand::R15); const struct jit_register x64_registers[] = { - {"rbx", JIT_REG_I64 | JIT_CALLEE_SAVED, (const void *)&Xbyak::util::rbx}, - {"rbp", JIT_REG_I64 | JIT_CALLEE_SAVED, (const void *)&Xbyak::util::rbp}, + {"rax", JIT_RESERVED | JIT_CALLER_SAVE | JIT_REG_I64, (const void *)&Xbyak::util::rax}, + {"rcx", JIT_RESERVED | JIT_CALLER_SAVE | JIT_REG_I64, (const void *)&Xbyak::util::rcx}, + {"rdx", JIT_RESERVED | JIT_CALLER_SAVE | JIT_REG_I64, (const void *)&Xbyak::util::rdx}, + {"rbx", JIT_ALLOCATE | JIT_CALLEE_SAVE | JIT_REG_I64, (const void *)&Xbyak::util::rbx}, + {"rsp", JIT_RESERVED | JIT_CALLEE_SAVE | JIT_REG_I64, (const void *)&Xbyak::util::rsp}, + {"rbp", JIT_ALLOCATE | JIT_CALLEE_SAVE | JIT_REG_I64, (const void *)&Xbyak::util::rbp}, #if PLATFORM_WINDOWS - {"rsi", JIT_REG_I64 | JIT_CALLER_SAVED, (const void *)&Xbyak::util::rsi}, - {"rdi", JIT_REG_I64 | JIT_CALLER_SAVED, (const void *)&Xbyak::util::rdi}, + {"rsi", JIT_ALLOCATE | JIT_CALLEE_SAVE | JIT_REG_I64, (const void *)&Xbyak::util::rsi}, + {"rdi", JIT_ALLOCATE | JIT_CALLEE_SAVE | JIT_REG_I64, (const void *)&Xbyak::util::rdi}, + {"r8", JIT_RESERVED | JIT_CALLER_SAVE | JIT_REG_I64, (const void *)&Xbyak::util::r8}, + {"r9", JIT_RESERVED | JIT_CALLER_SAVE | JIT_REG_I64, (const void *)&Xbyak::util::r9}, #else - {"r8", JIT_REG_I64 | JIT_CALLER_SAVED, (const void *)&Xbyak::util::r8}, - {"r9", JIT_REG_I64 | JIT_CALLER_SAVED, (const void *)&Xbyak::util::r9}, + {"rsi", JIT_RESERVED | JIT_CALLER_SAVE | JIT_REG_I64, (const void *)&Xbyak::util::rsi}, + {"rdi", JIT_RESERVED | JIT_CALLER_SAVE | JIT_REG_I64, (const void *)&Xbyak::util::rdi}, + {"r8", JIT_ALLOCATE | JIT_CALLER_SAVE | JIT_REG_I64, (const void *)&Xbyak::util::r8}, + {"r9", JIT_ALLOCATE | JIT_CALLER_SAVE | JIT_REG_I64, (const void *)&Xbyak::util::r9}, +#endif + {"r10", JIT_ALLOCATE | JIT_CALLER_SAVE | JIT_REG_I64, (const void *)&Xbyak::util::r10}, + {"r11", JIT_ALLOCATE | JIT_CALLER_SAVE | JIT_REG_I64, (const void *)&Xbyak::util::r11}, + {"r12", JIT_ALLOCATE | JIT_CALLEE_SAVE | JIT_REG_I64, (const void *)&Xbyak::util::r12}, + {"r13", JIT_ALLOCATE | JIT_CALLEE_SAVE | JIT_REG_I64, (const void *)&Xbyak::util::r13}, + {"r14", JIT_RESERVED | JIT_CALLEE_SAVE | JIT_REG_I64, (const void *)&Xbyak::util::r14}, + {"r15", JIT_RESERVED | JIT_CALLEE_SAVE | JIT_REG_I64, (const void *)&Xbyak::util::r15}, +#if PLATFORM_WINDOWS + {"xmm0", JIT_RESERVED | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm0}, + {"xmm1", JIT_RESERVED | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm1}, + {"xmm2", JIT_RESERVED | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm2}, + {"xmm3", JIT_RESERVED | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm3}, + {"xmm4", JIT_RESERVED | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm4}, + {"xmm5", JIT_RESERVED | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm5}, + {"xmm6", JIT_ALLOCATE | JIT_CALLEE_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm6}, + {"xmm7", JIT_ALLOCATE | JIT_CALLEE_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm7}, + {"xmm8", JIT_ALLOCATE | JIT_CALLEE_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm8}, + {"xmm9", JIT_ALLOCATE | JIT_CALLEE_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm9}, + {"xmm10", JIT_ALLOCATE | JIT_CALLEE_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm10}, + {"xmm11", JIT_ALLOCATE | JIT_CALLEE_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm11}, + {"xmm12", JIT_ALLOCATE | JIT_CALLEE_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm12}, + {"xmm13", JIT_ALLOCATE | JIT_CALLEE_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm13}, + {"xmm14", JIT_ALLOCATE | JIT_CALLEE_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm14}, + {"xmm15", JIT_ALLOCATE | JIT_CALLEE_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm15}, +#else + {"xmm0", JIT_RESERVED | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm0}, + {"xmm1", JIT_RESERVED | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm1}, + {"xmm2", JIT_RESERVED | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm2}, + {"xmm3", JIT_RESERVED | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm3}, + {"xmm4", JIT_RESERVED | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm4}, + {"xmm5", JIT_RESERVED | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm5}, + {"xmm6", JIT_ALLOCATE | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm6}, + {"xmm7", JIT_ALLOCATE | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm7}, + {"xmm8", JIT_ALLOCATE | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm8}, + {"xmm9", JIT_ALLOCATE | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm9}, + {"xmm10", JIT_ALLOCATE | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm10}, + {"xmm11", JIT_ALLOCATE | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm11}, + {"xmm12", JIT_ALLOCATE | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm12}, + {"xmm13", JIT_ALLOCATE | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm13}, + {"xmm14", JIT_ALLOCATE | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm14}, + {"xmm15", JIT_ALLOCATE | JIT_CALLER_SAVE | JIT_REG_F64 | JIT_REG_V128, (const void *)&Xbyak::util::xmm15}, #endif - {"r10", JIT_REG_I64 | JIT_CALLER_SAVED, (const void *)&Xbyak::util::r10}, - {"r11", JIT_REG_I64 | JIT_CALLER_SAVED, (const void *)&Xbyak::util::r11}, - {"r12", JIT_REG_I64 | JIT_CALLEE_SAVED, (const void *)&Xbyak::util::r12}, - {"r13", JIT_REG_I64 | JIT_CALLEE_SAVED, (const void *)&Xbyak::util::r13}, - {"xmm6", JIT_REG_F64 | JIT_REG_V128 | JIT_CALLEE_SAVED, (const void *)&Xbyak::util::xmm6}, - {"xmm7", JIT_REG_F64 | JIT_REG_V128 | JIT_CALLEE_SAVED, (const void *)&Xbyak::util::xmm7}, - {"xmm8", JIT_REG_F64 | JIT_REG_V128 | JIT_CALLEE_SAVED, (const void *)&Xbyak::util::xmm8}, - {"xmm9", JIT_REG_F64 | JIT_REG_V128 | JIT_CALLEE_SAVED, (const void *)&Xbyak::util::xmm9}, - {"xmm10", JIT_REG_F64 | JIT_REG_V128 | JIT_CALLEE_SAVED, (const void *)&Xbyak::util::xmm10}, - {"xmm11", JIT_REG_F64 | JIT_REG_V128 | JIT_CALLEE_SAVED, (const void *)&Xbyak::util::xmm11}, - {"xmm12", JIT_REG_F64 | JIT_REG_V128 | JIT_CALLEE_SAVED, (const void *)&Xbyak::util::xmm12}, - {"xmm13", JIT_REG_F64 | JIT_REG_V128 | JIT_CALLEE_SAVED, (const void *)&Xbyak::util::xmm13}, - {"xmm14", JIT_REG_F64 | JIT_REG_V128 | JIT_CALLEE_SAVED, (const void *)&Xbyak::util::xmm14}, - {"xmm15", JIT_REG_F64 | JIT_REG_V128 | JIT_CALLEE_SAVED, (const void *)&Xbyak::util::xmm15} }; const int x64_num_registers = ARRAY_SIZE(x64_registers); @@ -127,6 +134,60 @@ Xbyak::Xmm x64_backend_xmm(struct x64_backend *backend, return xmm; } +int x64_backend_push_regs(struct x64_backend *backend, int mask) { + int size = 0; + + auto &e = *backend->codegen; + + for (int i = 0; i < x64_num_registers; i++) { + const struct jit_register *r = &x64_registers[i]; + + if ((r->flags & mask) != mask) { + continue; + } + + if (r->flags & JIT_REG_I64) { + Xbyak::Reg reg = *(const Xbyak::Reg *)r->data; + CHECK(reg.isREG()); + size += 8; + e.mov(e.qword[e.rsp - size], reg); + } else if (r->flags & (JIT_REG_F64 | JIT_REG_V128)) { + Xbyak::Xmm xmm = *(const Xbyak::Xmm *)r->data; + CHECK(xmm.isXMM()); + size += 16; + e.movdqu(e.ptr[e.rsp - size], xmm); + } + } + + return size; +} + +void x64_backend_pop_regs(struct x64_backend *backend, int mask) { + int size = 0; + + auto &e = *backend->codegen; + + for (int i = 0; i < x64_num_registers; i++) { + const struct jit_register *r = &x64_registers[i]; + + if ((r->flags & mask) != mask) { + continue; + } + + if ((r->flags & JIT_REG_I64)) { + Xbyak::Reg reg = *(const Xbyak::Reg *)r->data; + CHECK(reg.isREG()); + size += 8; + e.mov(reg, e.qword[e.rsp - size]); + } else if (r->flags & (JIT_REG_F64 | JIT_REG_V128)) { + Xbyak::Xmm xmm = *(const Xbyak::Xmm *)r->data; + CHECK(xmm.isXMM()); + size += 16; + e.movdqu(xmm, e.ptr[e.rsp - size]); + } + } +} + void x64_backend_load_mem(struct x64_backend *backend, const struct ir_value *dst, const Xbyak::RegExp &src_exp) { @@ -306,33 +367,19 @@ static void x64_backend_emit_thunks(struct x64_backend *backend) { backend->load_thunk[i] = e.getCurr(); -/* save caller-saved registers and offset the stack an extra 8 bytes to - align it */ -#if PLATFORM_WINDOWS - e.push(e.rsi); - e.push(e.rdi); -#else - e.push(e.r8); - e.push(e.r9); -#endif - e.push(e.r10); - e.push(e.r11); - e.sub(e.rsp, X64_STACK_SHADOW_SPACE + 8); + /* save caller-saved registers that our code uses and ensure stack is + 16-byte aligned */ + int save_mask = JIT_ALLOCATE | JIT_CALLER_SAVE; + int offset = x64_backend_push_regs(backend, save_mask); + offset = ALIGN_UP(offset + X64_STACK_SHADOW_SPACE + 8, 16) - 8; + e.sub(e.rsp, offset); /* call the mmio handler */ e.call(e.rax); /* restore caller-saved registers */ - e.add(e.rsp, X64_STACK_SHADOW_SPACE + 8); - e.pop(e.r11); - e.pop(e.r10); -#if PLATFORM_WINDOWS - e.pop(e.rdi); - e.pop(e.rsi); -#else - e.pop(e.r9); - e.pop(e.r8); -#endif + e.add(e.rsp, offset); + x64_backend_pop_regs(backend, save_mask); /* save mmio handler result */ e.mov(dst, e.rax); @@ -346,34 +393,19 @@ static void x64_backend_emit_thunks(struct x64_backend *backend) { e.align(32); backend->store_thunk = e.getCurr(); - -/* save caller-saved registers and offset the stack an extra 8 bytes to - align it */ -#if PLATFORM_WINDOWS - e.push(e.rsi); - e.push(e.rdi); -#else - e.push(e.r8); - e.push(e.r9); -#endif - e.push(e.r10); - e.push(e.r11); - e.sub(e.rsp, X64_STACK_SHADOW_SPACE + 8); + /* save caller-saved registers that our code uses and ensure stack is + 16-byte aligned */ + int save_mask = JIT_ALLOCATE | JIT_CALLER_SAVE; + int offset = x64_backend_push_regs(backend, save_mask); + offset = ALIGN_UP(offset + X64_STACK_SHADOW_SPACE + 8, 16) - 8; + e.sub(e.rsp, offset); /* call the mmio handler */ e.call(e.rax); /* restore caller-saved registers */ - e.add(e.rsp, X64_STACK_SHADOW_SPACE + 8); - e.pop(e.r11); - e.pop(e.r10); -#if PLATFORM_WINDOWS - e.pop(e.rdi); - e.pop(e.rsi); -#else - e.pop(e.r9); - e.pop(e.r8); -#endif + e.add(e.rsp, offset); + x64_backend_pop_regs(backend, save_mask); /* return to jit code */ e.ret(); diff --git a/src/jit/backend/x64/x64_dispatch.cc b/src/jit/backend/x64/x64_dispatch.cc index f25e9cb6..5dc20c09 100644 --- a/src/jit/backend/x64/x64_dispatch.cc +++ b/src/jit/backend/x64/x64_dispatch.cc @@ -75,6 +75,7 @@ void x64_dispatch_emit_thunks(struct x64_backend *backend) { struct jit_guest *guest = backend->base.guest; auto &e = *backend->codegen; + int stack_offset = 0; /* emit dispatch thunks */ { @@ -152,18 +153,12 @@ void x64_dispatch_emit_thunks(struct x64_backend *backend) { backend->dispatch_enter = e.getCurr(); - /* create stack frame */ - e.push(e.rbx); - e.push(e.rbp); -#if PLATFORM_WINDOWS - e.push(e.rdi); - e.push(e.rsi); -#endif - e.push(e.r12); - e.push(e.r13); - e.push(e.r14); - e.push(e.r15); - e.sub(e.rsp, X64_STACK_SIZE + 8); + /* create stack frame and ensure stack is 16-byte aligned. note, the stack + is currently unaligned due to the 8-byte return address that was pushed + when this thunk was called */ + stack_offset = x64_backend_push_regs(backend, JIT_CALLEE_SAVE); + stack_offset = ALIGN_UP(stack_offset + X64_STACK_SIZE + 8, 16) - 8; + e.sub(e.rsp, stack_offset); /* assign fixed registers */ e.mov(guestctx, (uint64_t)guest->ctx); @@ -184,17 +179,9 @@ void x64_dispatch_emit_thunks(struct x64_backend *backend) { backend->dispatch_exit = e.getCurr(); /* destroy stack frame */ - e.add(e.rsp, X64_STACK_SIZE + 8); - e.pop(e.r15); - e.pop(e.r14); - e.pop(e.r13); - e.pop(e.r12); -#if PLATFORM_WINDOWS - e.pop(e.rsi); - e.pop(e.rdi); -#endif - e.pop(e.rbp); - e.pop(e.rbx); + e.add(e.rsp, stack_offset); + x64_backend_pop_regs(backend, JIT_CALLEE_SAVE); + e.ret(); } diff --git a/src/jit/backend/x64/x64_local.h b/src/jit/backend/x64/x64_local.h index 829cb9cd..8a42ef2b 100644 --- a/src/jit/backend/x64/x64_local.h +++ b/src/jit/backend/x64/x64_local.h @@ -51,7 +51,7 @@ struct x64_backend { /* * backend functionality used by emitters */ -#define X64_THUNK_SIZE 1024 +#define X64_THUNK_SIZE 8192 #define X64_STACK_SIZE 1024 #if PLATFORM_WINDOWS @@ -79,6 +79,8 @@ Xbyak::Reg x64_backend_reg(struct x64_backend *backend, const struct ir_value *v); Xbyak::Xmm x64_backend_xmm(struct x64_backend *backend, const struct ir_value *v); +int x64_backend_push_regs(struct x64_backend *backend, int mask); +void x64_backend_pop_regs(struct x64_backend *backend, int mask); void x64_backend_load_mem(struct x64_backend *backend, const struct ir_value *dst, const Xbyak::RegExp &src_exp); diff --git a/src/jit/jit_backend.h b/src/jit/jit_backend.h index 4b010e4c..3faf5a87 100644 --- a/src/jit/jit_backend.h +++ b/src/jit/jit_backend.h @@ -27,33 +27,37 @@ struct jit_guest; #endif enum { + /* allocate to this register */ + JIT_ALLOCATE = 0x1, + /* don't allocate to this register */ + JIT_RESERVED = 0x2, /* register is callee-saved */ - JIT_CALLEE_SAVED = 0x1, + JIT_CALLEE_SAVE = 0x4, /* register is caller-saved */ - JIT_CALLER_SAVED = 0x2, + JIT_CALLER_SAVE = 0x8, /* result must contain arg0. this signals the register allocator to insert a copy from arg0 to result if it fails to reuse the same register for both. this is required by several operations, namely binary arithmetic ops on x64, which only take two operands */ - JIT_REUSE_ARG0 = 0x4, + JIT_REUSE_ARG0 = 0x10, /* argument is optional */ - JIT_OPTIONAL = 0x8, + JIT_OPTIONAL = 0x20, /* argument can be in a 64-bit or less int register */ - JIT_REG_I64 = 0x10, + JIT_REG_I64 = 0x40, /* argument can be in a 64-bit or less float register */ - JIT_REG_F64 = 0x20, + JIT_REG_F64 = 0x80, /* argument can be in a 128-bit or less vector register */ - JIT_REG_V128 = 0x40, + JIT_REG_V128 = 0x100, /* argument can be a 32-bit or less int immediate */ - JIT_IMM_I32 = 0x80, + JIT_IMM_I32 = 0x200, /* argument can be a 64-bit or less int immediate */ - JIT_IMM_I64 = 0x100, + JIT_IMM_I64 = 0x400, /* argument can be a 32-bit or less float immediate */ - JIT_IMM_F32 = 0x200, + JIT_IMM_F32 = 0x800, /* argument can be a 64-bit or less float immediate */ - JIT_IMM_F64 = 0x400, + JIT_IMM_F64 = 0x1000, /* argument can be a block reference */ - JIT_IMM_BLK = 0x800, + JIT_IMM_BLK = 0x2000, JIT_TYPE_MASK = JIT_REG_I64 | JIT_REG_F64 | JIT_REG_V128 | JIT_IMM_I32 | JIT_IMM_I64 | JIT_IMM_F32 | JIT_IMM_F64 | JIT_IMM_BLK, }; diff --git a/src/jit/passes/register_allocation_pass.c b/src/jit/passes/register_allocation_pass.c index 04711635..9260f9ca 100644 --- a/src/jit/passes/register_allocation_pass.c +++ b/src/jit/passes/register_allocation_pass.c @@ -91,12 +91,14 @@ struct ra { static int ra_reg_can_store(const struct jit_register *reg, const struct ir_value *v) { - if (ir_is_int(v->type) && v->type <= VALUE_I64) { - return reg->flags & JIT_REG_I64; - } else if (ir_is_float(v->type) && v->type <= VALUE_F64) { - return reg->flags & JIT_REG_F64; - } else if (ir_is_vector(v->type) && v->type <= VALUE_V128) { - return reg->flags & JIT_REG_V128; + if (reg->flags & JIT_ALLOCATE) { + if (ir_is_int(v->type) && v->type <= VALUE_I64) { + return reg->flags & JIT_REG_I64; + } else if (ir_is_float(v->type) && v->type <= VALUE_F64) { + return reg->flags & JIT_REG_F64; + } else if (ir_is_vector(v->type) && v->type <= VALUE_V128) { + return reg->flags & JIT_REG_V128; + } } return 0; } @@ -222,7 +224,7 @@ static void ra_validate(struct ra *ra, struct ir *ir, struct ir_block *block) { for (int i = 0; i < ra->num_registers; i++) { const struct jit_register *reg = &ra->registers[i]; - if (reg->flags & JIT_CALLER_SAVED) { + if (reg->flags & JIT_CALLER_SAVE) { active[i] = NULL; } } @@ -315,7 +317,7 @@ static void ra_spill_tmps(struct ra *ra, struct ir *ir, /* only spill caller-saved regs */ struct ra_bin *bin = ra_get_bin(tmp->value->reg); - if (!(bin->reg->flags & JIT_CALLER_SAVED)) { + if (!(bin->reg->flags & JIT_CALLER_SAVE)) { continue; }