Alien-LibJIT

 view release on metacpan or  search on metacpan

libjit/jit/jit-rules-arm.c  view on Meta::CPAN

	arm_load_membase_float64(*inst, reg, ARM_PC, 0);

	/* Add the constant to the pool, which may cause a flush */
	jit_gen_save_inst_ptr(gen, *inst);
	add_constant_dword(gen, value1, value2, fixup, 1);
	jit_gen_load_inst_ptr(gen, *inst);
}

/*
 * Output a branch instruction.
 */
static void output_branch
		(jit_function_t func, arm_inst_buf *inst, int cond, jit_insn_t insn)
{
	jit_block_t block;
	int offset;
	//block = jit_block_from_label(func, (jit_label_t)(insn->dest));
	if((insn->flags & JIT_INSN_VALUE1_IS_LABEL) != 0)
	{
		/* "address_of_label" instruction */
		block = jit_block_from_label(func, (jit_label_t)(insn->value1));
	}
	else
	{
		block = jit_block_from_label(func, (jit_label_t)(insn->dest));
	}
	if(!block)
	{
		return;
	}
	if(arm_inst_get_posn(*inst) >= arm_inst_get_limit(*inst))
	{
		/* The buffer has overflowed, so don't worry about fixups */
		return;
	}
	if(block->address)
	{
		/* We already know the address of the block */
		arm_branch(*inst, cond, block->address);
	}
	else
	{
		/* Output a placeholder and record on the block's fixup list */
		if(block->fixup_list)
		{
			offset = (int)(((unsigned char *)arm_inst_get_posn(*inst)) -
					((unsigned char *)(block->fixup_list)));
		}
		else
		{
			offset = 0;
		}
		arm_branch_imm(*inst, cond, offset);
		block->fixup_list = (void *)(arm_inst_get_posn(*inst) - 1);
	}
}

/*
 * Throw a builtin exception.
 */
static void throw_builtin
		(arm_inst_buf *inst, jit_function_t func, int cond, int type)
{
	arm_inst_word *patch;

	/* Branch past the following code if "cond" is not true */
	patch = arm_inst_get_posn(*inst);
	arm_branch_imm(*inst, cond ^ 0x01, 0);

	/* We need to update "catch_pc" if we have a "try" block */
	if(func->builder->setjmp_value != 0)
	{
		_jit_gen_fix_value(func->builder->setjmp_value);
		arm_mov_reg_reg(*inst, ARM_WORK, ARM_PC);
		arm_store_membase(*inst, ARM_WORK, ARM_FP,
				   func->builder->setjmp_value->frame_offset +
						   jit_jmp_catch_pc_offset);
	}

	/* Push the exception type onto the stack */
	arm_mov_reg_imm(*inst, ARM_WORK, type);
	arm_push_reg(*inst, ARM_WORK);

	/* Call the "jit_exception_builtin" function, which will never return */
	arm_call(*inst, jit_exception_builtin);

	/* Back-patch the previous branch instruction */
	arm_patch(*inst, patch, arm_inst_get_posn(*inst));
}

/*
 * Jump to the current function's epilog.
 */
static void jump_to_epilog
		(jit_gencode_t gen, arm_inst_buf *inst, jit_block_t block)
{
	int offset;

	/* If the epilog is the next thing that we will output,
	   then fall through to the epilog directly */
	if(_jit_block_is_final(block))
	{
		return;
	}

	/* Bail out if the instruction buffer has overflowed */
	if(arm_inst_get_posn(*inst) >= arm_inst_get_limit(*inst))
	{
		return;
	}

	/* Output a placeholder for the jump and add it to the fixup list */
	if(gen->epilog_fixup)
	{
		offset = (int)(((unsigned char *)arm_inst_get_posn(*inst)) -
				((unsigned char *)(gen->epilog_fixup)));
	}
	else
	{
		offset = 0;
	}



( run in 0.330 second using v1.01-cache-2.11-cpan-119454b85a5 )