void _jit_create_closure(unsigned char *buf, void *func, void *closure, void *_type) { arm_inst_buf inst; /* Initialize the instruction buffer */ arm_inst_buf_init(inst, buf, buf + jit_closure_size); /* Set up the local stack frame */ arm_setup_frame(inst, 0); arm_alu_reg_imm8(inst, ARM_SUB, ARM_SP, ARM_SP, 24); /* Create the apply argument block on the stack */ arm_store_membase(inst, ARM_R0, ARM_FP, -28); arm_store_membase(inst, ARM_R1, ARM_FP, -24); arm_store_membase(inst, ARM_R2, ARM_FP, -20); arm_store_membase(inst, ARM_R3, ARM_FP, -16); arm_alu_reg_imm(inst, ARM_ADD, ARM_R3, ARM_FP, 4); arm_store_membase(inst, ARM_R3, ARM_FP, -36); arm_store_membase(inst, ARM_R0, ARM_FP, -32); /* Set up the arguments for calling "func" */ arm_mov_reg_imm(inst, ARM_R0, (int)(jit_nint)closure); arm_mov_reg_reg(inst, ARM_R1, ARM_SP); /* Call the closure handling function */ arm_call(inst, func); /* Pop the current stack frame and return */ arm_pop_frame(inst, 0); }
void _jit_gen_epilog(jit_gencode_t gen, jit_function_t func) { int reg, regset; arm_inst_buf inst; void **fixup; void **next; jit_nint offset; /* Initialize the instruction buffer */ jit_gen_load_inst_ptr(gen, inst); /* Determine which registers need to be restored when we return */ regset = 0; for(reg = 0; reg <= 15; ++reg) { if(jit_reg_is_used(gen->touched, reg) && (_jit_reg_info[reg].flags & JIT_REG_CALL_USED) == 0) { regset |= (1 << reg); } } /* Apply fixups for blocks that jump to the epilog */ fixup = (void **)(gen->epilog_fixup); while(fixup != 0) { offset = (((jit_nint)(fixup[0])) & 0x00FFFFFF) << 2; if(!offset) { next = 0; } else { next = (void **)(((unsigned char *)fixup) - offset); } arm_patch(inst, fixup, arm_inst_get_posn(inst)); fixup = next; } gen->epilog_fixup = 0; /* Pop the local stack frame and return */ arm_pop_frame(inst, regset); jit_gen_save_inst_ptr(gen, inst); /* Flush the remainder of the constant pool */ flush_constants(gen, 1); }