Пример #1
0
/*@
 * @deftypefun int jit_value_is_true (jit_value_t @var{value})
 * Determine if @var{value} is constant and non-zero.
 * @end deftypefun
@*/
int
jit_value_is_true(jit_value_t value)
{
	if(!value || !value->is_constant)
	{
		return 0;
	}
	if(value->is_nint_constant)
	{
		return (value->address != 0);
	}
	switch(jit_type_remove_tags(value->type)->kind)
	{
	case JIT_TYPE_LONG:
	case JIT_TYPE_ULONG:
		return (jit_value_get_long_constant(value) != 0);

	case JIT_TYPE_FLOAT32:
		return (jit_value_get_float32_constant(value) != (jit_float32) 0.0);

	case JIT_TYPE_FLOAT64:
		return (jit_value_get_float64_constant(value) != (jit_float64) 0.0);

	case JIT_TYPE_NFLOAT:
		return (jit_value_get_nfloat_constant(value) != (jit_nfloat) 0.0);
	}
	return 0;
}
Пример #2
0
static void
load_value(jit_gencode_t gen, jit_value_t value, int index)
{
	int opcode;
	jit_nint offset;

	if(value->is_constant)
	{
		/* Determine the type of constant to be loaded */
		switch(jit_type_normalize(value->type)->kind)
		{
		case JIT_TYPE_SBYTE:
		case JIT_TYPE_UBYTE:
		case JIT_TYPE_SHORT:
		case JIT_TYPE_USHORT:
		case JIT_TYPE_INT:
		case JIT_TYPE_UINT:
			jit_cache_opcode(gen, JIT_INTERP_OP_LDC_0_INT + index);
			jit_cache_native(gen, (jit_nint)(value->address));
			break;

		case JIT_TYPE_LONG:
		case JIT_TYPE_ULONG:
			{
				jit_long long_value;
				long_value = jit_value_get_long_constant(value);
				jit_cache_opcode(gen, JIT_INTERP_OP_LDC_0_LONG + index);
#ifdef JIT_NATIVE_INT64
				jit_cache_native(gen, long_value);
#else
				jit_cache_add_n(gen, &long_value, sizeof(long_value));
#endif
				break;
			}

		case JIT_TYPE_FLOAT32:
			{
				jit_float32 float32_value;
				float32_value = jit_value_get_float32_constant(value);
				jit_cache_opcode(gen, JIT_INTERP_OP_LDC_0_FLOAT32 + index);
				jit_cache_add_n(gen, &float32_value, sizeof(float32_value));
				break;
			}

		case JIT_TYPE_FLOAT64:
			{
				jit_float64 float64_value;
				float64_value = jit_value_get_float64_constant(value);
				jit_cache_opcode(gen, JIT_INTERP_OP_LDC_0_FLOAT64 + index);
				jit_cache_add_n	(gen, &float64_value, sizeof(float64_value));
				break;
			}

		case JIT_TYPE_NFLOAT:
			{
				jit_nfloat nfloat_value;
				nfloat_value = jit_value_get_nfloat_constant(value);
				jit_cache_opcode(gen, JIT_INTERP_OP_LDC_0_NFLOAT + index);
				jit_cache_add_n	(gen, &nfloat_value, sizeof(nfloat_value));
				break;
			}
		}
	}
	else
	{
		/* Fix the position of the value in the stack frame */
		_jit_gen_fix_value(value);

		/* Generate a local or argument access opcode, as appropriate */
		if(value->frame_offset >= 0)
		{
			/* Load a local variable value onto the stack */
			switch(index)
			{
			case 0:
				opcode = JIT_INTERP_OP_LDL_0_SBYTE;
				break;
			case 1:
				opcode = JIT_INTERP_OP_LDL_1_SBYTE;
				break;
			case 2:
				opcode = JIT_INTERP_OP_LDL_2_SBYTE;
				break;
			default:
				return;
			}
			opcode = _jit_load_opcode(opcode, value->type);
			offset = value->frame_offset;
		}
		else
		{
			/* Load an argument value onto the stack */
			switch(index)
			{
			case 0:
				opcode = JIT_INTERP_OP_LDA_0_SBYTE;
				break;
			case 1:
				opcode = JIT_INTERP_OP_LDA_1_SBYTE;
				break;
			case 2:
				opcode = JIT_INTERP_OP_LDA_2_SBYTE;
				break;
			default:
				return;
			}
			opcode = _jit_load_opcode(opcode, value->type);
			offset = -(value->frame_offset + 1);
		}

		jit_cache_opcode(gen, opcode);
		jit_cache_native(gen, offset);
	}
}
Пример #3
0
void _jit_gen_load_value
	(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);
	}

	if(value->is_constant)
	{
		/* Determine the type of constant to be loaded */
		switch(jit_type_normalize(value->type)->kind)
		{
			case JIT_TYPE_SBYTE:
			case JIT_TYPE_UBYTE:
			case JIT_TYPE_SHORT:
			case JIT_TYPE_USHORT:
			case JIT_TYPE_INT:
			case JIT_TYPE_UINT:
			{
				mov_reg_imm(gen, &inst, _jit_reg_info[reg].cpu_reg,
							(jit_nint)(value->address));
			}
			break;

			case JIT_TYPE_LONG:
			case JIT_TYPE_ULONG:
			{
				jit_long long_value;
				long_value = jit_value_get_long_constant(value);
				mov_reg_imm(gen, &inst, _jit_reg_info[reg].cpu_reg,
						    (jit_int)long_value);
				mov_reg_imm(gen, &inst, _jit_reg_info[reg].cpu_reg + 1,
						    (jit_int)(long_value >> 32));
			}
			break;

			case JIT_TYPE_FLOAT32:
			{
				jit_float32 float32_value;
				float32_value = jit_value_get_float32_constant(value);
				if(reg < 16)
				{
					mov_reg_imm(gen, &inst, _jit_reg_info[reg].cpu_reg,
							    *((int *)&float32_value));
				}
				else
				{
					mov_freg_imm_32
						(gen, &inst, _jit_reg_info[reg].cpu_reg,
					     *((int *)&float32_value));
				}
			}
			break;

			case JIT_TYPE_FLOAT64:
			case JIT_TYPE_NFLOAT:
			{
				jit_float64 float64_value;
				float64_value = jit_value_get_float64_constant(value);
				if(reg < 16)
				{
					mov_reg_imm
						(gen, &inst, _jit_reg_info[reg].cpu_reg,
						 ((int *)&float64_value)[0]);
					mov_reg_imm
						(gen, &inst, _jit_reg_info[reg].cpu_reg + 1,
						 ((int *)&float64_value)[1]);
				}
				else
				{
					mov_freg_imm_64
						(gen, &inst, _jit_reg_info[reg].cpu_reg,
					     ((int *)&float64_value)[0],
					     ((int *)&float64_value)[1]);
				}
			}
			break;
		}
	}
	else if(value->has_global_register)
Пример #4
0
void
_jit_gen_load_value(jit_gencode_t gen, int reg, int other_reg, jit_value_t value)
{
	jit_type_t type;
	int src_reg, other_src_reg;
	void *ptr;
	int offset;

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

	type = jit_type_normalize(value->type);

	/* Load zero */
	if(value->is_constant)
	{
		switch(type->kind)
		{
			case JIT_TYPE_SBYTE:
			case JIT_TYPE_UBYTE:
			case JIT_TYPE_SHORT:
			case JIT_TYPE_USHORT:
			case JIT_TYPE_INT:
			case JIT_TYPE_UINT:
			{
				if((jit_nint)(value->address) == 0)
				{
					x86_clear_reg(inst, _jit_reg_info[reg].cpu_reg);
				}
				else
				{
					x86_mov_reg_imm(inst, _jit_reg_info[reg].cpu_reg,
							(jit_nint)(value->address));
				}
			}
			break;

			case JIT_TYPE_LONG:
			case JIT_TYPE_ULONG:
			{
				jit_long long_value;
				long_value = jit_value_get_long_constant(value);
				if(long_value == 0)
				{
#ifdef JIT_NATIVE_INT64
					x86_clear_reg(inst, _jit_reg_info[reg].cpu_reg);
#else
					x86_clear_reg(inst, _jit_reg_info[reg].cpu_reg);
					x86_clear_reg(inst, _jit_reg_info[other_reg].cpu_reg);
#endif
				}
				else
				{
#ifdef JIT_NATIVE_INT64
					x86_mov_reg_imm(inst, _jit_reg_info[reg].cpu_reg,
							(jit_nint)long_value);
#else
					x86_mov_reg_imm(inst, _jit_reg_info[reg].cpu_reg,
							(jit_int)long_value);
					x86_mov_reg_imm(inst, _jit_reg_info[other_reg].cpu_reg,
							(jit_int)(long_value >> 32));
#endif
				}
			}
			break;

			case JIT_TYPE_FLOAT32:
			{
				jit_float32 float32_value;
				float32_value = jit_value_get_float32_constant(value);
				if(IS_WORD_REG(reg))
				{
					union
					{
						jit_float32 float32_value;
						jit_int int_value;
					} un;

					un.float32_value = float32_value;
					x86_mov_reg_imm(inst, _jit_reg_info[reg].cpu_reg, un.int_value);
				}
				else
				{
					if(float32_value == (jit_float32) 0.0)
					{
						x86_fldz(inst);
					}
					else if(float32_value == (jit_float32) 1.0)
					{
						x86_fld1(inst);
					}
					else
					{
						ptr = _jit_cache_alloc(&(gen->posn), sizeof(jit_float32));
						jit_memcpy(ptr, &float32_value, sizeof(float32_value));
						x86_fld(inst, ptr, 0);
					}
				}
			}
			break;

			case JIT_TYPE_FLOAT64:
			{
				jit_float64 float64_value;
				float64_value = jit_value_get_float64_constant(value);
				if(IS_WORD_REG(reg))
				{
					union
					{
						jit_float64 float64_value;
						jit_int int_value[2];
					} un;

					un.float64_value = float64_value;
					x86_mov_reg_imm(inst, _jit_reg_info[reg].cpu_reg,
							un.int_value[0]);
					x86_mov_reg_imm(inst, _jit_reg_info[other_reg].cpu_reg,
							un.int_value[1]);
				}
				else
				{
					if(float64_value == (jit_float64) 0.0)
					{
						x86_fldz(inst);
					}
					else if(float64_value == (jit_float64) 1.0)
					{
						x86_fld1(inst);
					}
					else
					{
						ptr = _jit_cache_alloc(&(gen->posn), sizeof(jit_float64));
						jit_memcpy(ptr, &float64_value, sizeof(float64_value));
						x86_fld(inst, ptr, 1);
					}
				}
			}
			break;

			case JIT_TYPE_NFLOAT:
			{
				jit_nfloat nfloat_value;
				nfloat_value = jit_value_get_nfloat_constant(value);
				if(IS_WORD_REG(reg) && sizeof(jit_nfloat) == sizeof(jit_float64))
				{
					union
					{
						jit_nfloat nfloat_value;
						jit_int int_value[2];
					} un;

					un.nfloat_value = nfloat_value;
					x86_mov_reg_imm(inst, _jit_reg_info[reg].cpu_reg,
							un.int_value[0]);
					x86_mov_reg_imm(inst, _jit_reg_info[other_reg].cpu_reg,
							un.int_value[1]);
				}
				else
				{
					if(nfloat_value == (jit_nfloat) 0.0)
					{
						x86_fldz(inst);
					}
					else if(nfloat_value == (jit_nfloat) 1.0)
					{
						x86_fld1(inst);
					}
					else
					{
						ptr = _jit_cache_alloc(&(gen->posn), sizeof(jit_nfloat));
						jit_memcpy(ptr, &nfloat_value, sizeof(nfloat_value));
						if(sizeof(jit_nfloat) == sizeof(jit_float64))
						{
							x86_fld(inst, ptr, 1);
						}
						else
						{
							x86_fld80_mem(inst, ptr);
						}
					}
				}
			}
			break;
		}
	}
	else if(value->in_register || value->in_global_register)