/*
 * Check a 2D array access operation for exception conditions.
 */
static void Check2DArrayAccess(MDUnroll *unroll, int reg, int reg2, int reg3,
							   unsigned char *pc, unsigned char *label)
{
#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS
	md_inst_ptr patch1;
#endif
	md_inst_ptr patch2;
	md_inst_ptr patch3;

#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS
	/* Check the array reference against NULL */
	arm_test_reg_imm8(unroll->out, ARM_CMP, reg, 0);
	patch1 = unroll->out;
	arm_branch_imm(unroll->out, ARM_CC_EQ, 0);
#endif

	/* Check the array bounds.  We assume that we can use the link
	   register as a work register because "lr" would have been
	   saved on entry to "_ILCVMInterpreter" */
	arm_load_membase(unroll->out, ARM_WORK, reg, 12);
	arm_alu_reg_reg(unroll->out, ARM_SUB, reg2, reg2, ARM_WORK);
	arm_load_membase(unroll->out, ARM_LINK, reg, 16);
	arm_test_reg_reg(unroll->out, ARM_CMP, reg2, ARM_LINK);
	patch2 = unroll->out;
	arm_branch_imm(unroll->out, ARM_CC_LT_UN, 0);
	arm_alu_reg_reg(unroll->out, ARM_ADD, reg2, reg2, ARM_WORK);
	patch3 = unroll->out;
	arm_jump_imm(unroll->out, 0);
	arm_patch(patch2, unroll->out);
	arm_load_membase(unroll->out, ARM_WORK, reg, 24);
	arm_alu_reg_reg(unroll->out, ARM_SUB, reg3, reg3, ARM_WORK);
	arm_load_membase(unroll->out, ARM_LINK, reg, 28);
	arm_test_reg_reg(unroll->out, ARM_CMP, reg3, ARM_LINK);
	patch2 = unroll->out;
	arm_branch_imm(unroll->out, ARM_CC_LT_UN, 0);
	arm_alu_reg_reg(unroll->out, ARM_ADD, reg3, reg3, ARM_WORK);
	arm_load_membase(unroll->out, ARM_WORK, reg, 12);
	arm_alu_reg_reg(unroll->out, ARM_ADD, reg2, reg2, ARM_WORK);

	/* Re-execute the current instruction in the interpreter */
#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS
	arm_patch(patch1, unroll->out);
#endif
	arm_patch(patch3, unroll->out);
	ReExecute(unroll, pc, label);

	/* Compute the address of the array element */
	arm_patch(patch2, unroll->out);
	arm_load_membase(unroll->out, ARM_WORK, reg, 20);
	arm_mul_reg_reg(unroll->out, reg2, reg2, ARM_WORK);
	arm_load_membase(unroll->out, ARM_WORK, reg, 32);
	arm_mul_reg_reg(unroll->out, reg3, reg3, ARM_WORK);
	arm_alu_reg_reg(unroll->out, ARM_ADD, reg2, reg2, reg3);
	arm_load_membase(unroll->out, ARM_WORK, reg, 4);
	arm_mul_reg_reg(unroll->out, reg2, reg2, ARM_WORK);
	arm_load_membase(unroll->out, reg, reg, 8);
	arm_alu_reg_reg(unroll->out, ARM_ADD, reg, reg, reg2);
}
示例#2
0
void *_jit_gen_redirector(jit_gencode_t gen, jit_function_t func)
{
	void *ptr, *entry;
	arm_inst_buf inst;
	jit_gen_load_inst_ptr(gen, inst);
	ptr = (void *)&(func->entry_point);
	entry = gen->posn.ptr;
	arm_load_membase(inst, ARM_WORK, ARM_PC, 0);
	arm_load_membase(inst, ARM_PC, ARM_WORK, 0);
	arm_inst_add(inst, (unsigned int)ptr);
	jit_gen_save_inst_ptr(gen, inst);
	return entry;
}
示例#3
0
/*
 * Load an immediate value into a word register.  If the value is
 * complicated, then add an entry to the constant pool.
 */
static void mov_reg_imm
	(jit_gencode_t gen, arm_inst_buf *inst, int reg, int value)
{
	arm_inst_word *fixup;

	/* Bail out if the value is not complex enough to need a pool entry */
	if(!arm_is_complex_imm(value))
	{
		arm_mov_reg_imm(*inst, reg, value);
		return;
	}

	/* Output a placeholder to load the value later */
	fixup = arm_inst_get_posn(*inst);
	arm_load_membase(*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(gen, value, fixup);
	jit_gen_load_inst_ptr(gen, *inst);
}