Example #1
0
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);
}
Example #2
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);
}