void
_jit_gen_move_top(jit_gencode_t gen, int reg)
{
	if(IS_FLOAT_REG(reg))
	{
		jit_cache_setup_output(2);
		x86_fstp(inst, fp_stack_index(gen, reg));
		jit_cache_end_output();
	}
}
Beispiel #2
0
void _jit_gen_spill_reg(jit_gencode_t gen, int reg,
						int other_reg, jit_value_t value)
{
	int offset;

	/* Make sure that we have sufficient space */
	jit_cache_setup_output(32);
	if(flush_if_too_far(gen))
	{
		jit_gen_load_inst_ptr(gen, inst);
	}

	/* Output an appropriate instruction to spill the value */
	if(value->has_global_register)
	{
		arm_mov_reg_reg(inst, _jit_reg_info[value->global_reg].cpu_reg,
						_jit_reg_info[reg].cpu_reg);
	}
	else
	{
		_jit_gen_fix_value(value);
		offset = (int)(value->frame_offset);
		if(reg < 16)
		{
			arm_store_membase(inst, reg, ARM_FP, offset);
			if(other_reg != -1)
			{
				/* Spill the other word register in a pair */
				offset += sizeof(void *);
				arm_store_membase(inst, other_reg, ARM_FP, offset);
			}
		}
		else if(jit_type_normalize(value->type)->kind == JIT_TYPE_FLOAT32)
		{
			arm_store_membase_float32(inst, reg - 16, ARM_FP, offset);
		}
		else
		{
			arm_store_membase_float64(inst, reg - 16, ARM_FP, offset);
		}
	}

	/* End the code output process */
	jit_cache_end_output();
}
void
_jit_gen_spill_top(jit_gencode_t gen, int reg, jit_value_t value, int pop)
{
	int offset;
	if(IS_FLOAT_REG(reg))
	{
		/* Make sure that we have sufficient space */
		jit_cache_setup_output(16);

		/* Fix the value in place within the local variable frame */
		_jit_gen_fix_value(value);

		/* Output an appropriate instruction to spill the value */
		offset = (int)(value->frame_offset);

		/* Spill the top of the floating-point register stack */
		switch(jit_type_normalize(value->type)->kind)
		{
			case JIT_TYPE_FLOAT32:
			{
				x86_fst_membase(inst, X86_EBP, offset, 0, pop);
			}
			break;

			case JIT_TYPE_FLOAT64:
			{
				x86_fst_membase(inst, X86_EBP, offset, 1, pop);
			}
			break;

			case JIT_TYPE_NFLOAT:
			{
				x86_fst80_membase(inst, X86_EBP, offset);
				if(!pop)
				{
					x86_fld80_membase(inst, X86_EBP, offset);
				}
			}
			break;
		}

		/* End the code output process */
		jit_cache_end_output();
	}
}
void _jit_gen_spill_reg(jit_gencode_t gen, int reg,
						int other_reg, jit_value_t value)
{
	int offset;

	/* Make sure that we have sufficient space */
	jit_cache_setup_output(16);

	/* If the value is associated with a global register, then copy to that */
	if(value->has_global_register)
	{
		reg = _jit_reg_info[reg].cpu_reg;
		other_reg = _jit_reg_info[value->global_reg].cpu_reg;
		x86_mov_reg_reg(inst, other_reg, reg, sizeof(void *));
		jit_cache_end_output();
		return;
	}

	/* Fix the value in place within the local variable frame */
	_jit_gen_fix_value(value);

	/* Output an appropriate instruction to spill the value */
	offset = (int)(value->frame_offset);
	if(IS_WORD_REG(reg))
	{
		/* Spill a word register.  If the value is smaller than a word,
		   then we write the entire word.  The local stack frame is
		   allocated such that the extra bytes will be simply ignored */
		reg = _jit_reg_info[reg].cpu_reg;
		x86_mov_membase_reg(inst, X86_EBP, offset, reg, 4);
		if(other_reg != -1)
		{
			/* Spill the other word register in a pair */
			reg = _jit_reg_info[other_reg].cpu_reg;
			offset += sizeof(void *);
			x86_mov_membase_reg(inst, X86_EBP, offset, reg, 4);
		}
	}
	else
	{
		/* Spill the top of the floating-point register stack */
		switch(jit_type_normalize(value->type)->kind)
		{
			case JIT_TYPE_FLOAT32:
			{
				x86_fst_membase(inst, X86_EBP, offset, 0, 1);
			}
			break;

			case JIT_TYPE_FLOAT64:
			{
				x86_fst_membase(inst, X86_EBP, offset, 1, 1);
			}
			break;

			case JIT_TYPE_NFLOAT:
			{
				x86_fst80_membase(inst, X86_EBP, offset);
			}
			break;
		}
	}

	/* End the code output process */
	jit_cache_end_output();
}