Esempio n. 1
0
/*
 * 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);
}
Esempio n. 2
0
/*
 * Flush the contents of the constant pool.
 */
static void flush_constants(jit_gencode_t gen, int after_epilog)
{
	arm_inst_buf inst;
	arm_inst_word *patch;
	arm_inst_word *current;
	arm_inst_word *fixup;
	int index, value, offset;

	/* Bail out if there are no constants to flush */
	if(!(gen->num_constants))
	{
		return;
	}

	/* Initialize the cache output pointer */
	jit_gen_load_inst_ptr(gen, inst);

	/* Jump over the constant pool if it is being output inline */
	if(!after_epilog)
	{
		patch = arm_inst_get_posn(inst);
		arm_jump_imm(inst, 0);
	}
	else
	{
		patch = 0;
	}

	/* Align the constant pool, if requested */
	if(gen->align_constants && (((int)arm_inst_get_posn(inst)) & 7) != 0)
	{
		arm_inst_add(inst, 0);
	}

	/* Output the constant values and apply the necessary fixups */
	for(index = 0; index < gen->num_constants; ++index)
	{
		current = arm_inst_get_posn(inst);
		arm_inst_add(inst, gen->constants[index]);
		fixup = gen->fixup_constants[index];
		while(fixup != 0)
		{
			if((*fixup & 0x0F000000) == 0x05000000)
			{
				/* Word constant fixup */
				value = *fixup & 0x0FFF;
				offset = ((arm_inst_get_posn(inst) - 1 - fixup) * 4) - 8;
				*fixup = ((*fixup & ~0x0FFF) | offset);
			}
			else
			{
				/* Floating-point constant fixup */
				value = (*fixup & 0x00FF) * 4;
				offset = ((arm_inst_get_posn(inst) - 1 - fixup) * 4) - 8;
				*fixup = ((*fixup & ~0x00FF) | (offset / 4));
			}
			if(value)
			{
				fixup -= value;
			}
			else
			{
				fixup = 0;
			}
		}
	}

	/* Backpatch the jump if necessary */
	if(!after_epilog)
	{
		arm_patch(inst, patch, arm_inst_get_posn(inst));
	}

	/* Flush the pool state and restart */
	gen->num_constants = 0;
	gen->align_constants = 0;
	gen->first_constant_use = 0;
	jit_gen_save_inst_ptr(gen, inst);
}