|
|
@ -59,479 +59,378 @@ typedef jit_int (*jit_cf_i_D_func)(jit_nfloat value); |
|
|
|
typedef jit_int (*jit_cf_i_DD_func)(jit_nfloat value1, jit_nfloat value2); |
|
|
|
|
|
|
|
/*
|
|
|
|
* NOTE: The result type is already set in const_result. |
|
|
|
* NOTE: The result type is already set in the result struct. |
|
|
|
*/ |
|
|
|
static int |
|
|
|
apply_conv(jit_constant_t *const_result, jit_value_t value, int overflow_check) |
|
|
|
apply_conv(jit_constant_t *result, jit_value_t value, int overflow_check) |
|
|
|
{ |
|
|
|
jit_type_t srctype; |
|
|
|
jit_constant_t const_value; |
|
|
|
|
|
|
|
srctype = jit_type_promote_int(jit_type_normalize(value->type)); |
|
|
|
if(!srctype) |
|
|
|
jit_constant_t constant; |
|
|
|
constant.type = jit_type_promote_int(jit_type_normalize(value->type)); |
|
|
|
if(!constant.type) |
|
|
|
{ |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
const_value.type = srctype; |
|
|
|
switch(srctype->kind) |
|
|
|
switch(constant.type->kind) |
|
|
|
{ |
|
|
|
case JIT_TYPE_INT: |
|
|
|
const_value.un.int_value = value->address; |
|
|
|
constant.un.int_value = value->address; |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_TYPE_UINT: |
|
|
|
const_value.un.uint_value = value->address; |
|
|
|
constant.un.uint_value = value->address; |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_TYPE_LONG: |
|
|
|
#ifdef JIT_NATIVE_INT64 |
|
|
|
const_value.un.long_value = value->address; |
|
|
|
constant.un.long_value = value->address; |
|
|
|
#else |
|
|
|
const_value.un.long_value = *(jit_long *)(value->address); |
|
|
|
constant.un.long_value = *((jit_long *) value->address); |
|
|
|
#endif |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_TYPE_ULONG: |
|
|
|
#ifdef JIT_NATIVE_INT64 |
|
|
|
const_value.un.ulong_value = value->address; |
|
|
|
constant.un.ulong_value = value->address; |
|
|
|
#else |
|
|
|
const_value.un.ulong_value = *(jit_ulong *)(value->address); |
|
|
|
constant.un.ulong_value = *((jit_ulong *) value->address); |
|
|
|
#endif |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_TYPE_FLOAT32: |
|
|
|
const_value.un.float32_value = *(jit_float32 *)(value->address); |
|
|
|
constant.un.float32_value = *((jit_float32 *) value->address); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_TYPE_FLOAT64: |
|
|
|
const_value.un.float64_value = *(jit_float64 *)(value->address); |
|
|
|
constant.un.float64_value = *((jit_float64 *) value->address); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_TYPE_NFLOAT: |
|
|
|
const_value.un.nfloat_value = *(jit_nfloat *)(value->address); |
|
|
|
constant.un.nfloat_value = *((jit_nfloat *) value->address); |
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
return jit_constant_convert(const_result, &const_value, |
|
|
|
const_result->type, overflow_check); |
|
|
|
return jit_constant_convert(result, &constant, result->type, |
|
|
|
overflow_check); |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
|
* NOTE: value1 is guaranteed to be valid and a constant n entry of each |
|
|
|
* of the apply_* functions. |
|
|
|
* This is checked on entry of the public _jit_opcode_apply function. |
|
|
|
*/ |
|
|
|
static int |
|
|
|
apply_i_i(jit_constant_t *const_result, jit_value_t value1, |
|
|
|
apply_i_i(jit_constant_t *result, jit_value_t value, |
|
|
|
jit_cf_i_i_func intrinsic) |
|
|
|
{ |
|
|
|
if(value1->is_nint_constant) |
|
|
|
{ |
|
|
|
const_result->un.int_value = (*intrinsic)(value1->address); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
result->un.int_value = intrinsic(value->address); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_i_ii(jit_constant_t *const_result, |
|
|
|
apply_i_ii(jit_constant_t *result, |
|
|
|
jit_value_t value1, jit_value_t value2, |
|
|
|
jit_cf_i_ii_func intrinsic) |
|
|
|
{ |
|
|
|
if(value1->is_nint_constant && value2 && value2->is_nint_constant) |
|
|
|
{ |
|
|
|
const_result->un.int_value = (*intrinsic)(value1->address, |
|
|
|
value2->address); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
result->un.int_value = intrinsic(value1->address, value2->address); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_i_piii(jit_constant_t *const_result, |
|
|
|
apply_i_piii(jit_constant_t *result, |
|
|
|
jit_value_t value1, jit_value_t value2, |
|
|
|
jit_cf_i_piii_func intrinsic) |
|
|
|
{ |
|
|
|
if(value1->is_nint_constant && value2 && value2->is_nint_constant) |
|
|
|
{ |
|
|
|
return (*intrinsic)(&(const_result->un.int_value), |
|
|
|
value1->address, value2->address); |
|
|
|
} |
|
|
|
return 0; |
|
|
|
return intrinsic(&result->un.int_value, |
|
|
|
value1->address, value2->address); |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_i_iI(jit_constant_t *const_result, |
|
|
|
apply_i_iI(jit_constant_t *result, |
|
|
|
jit_value_t value1, jit_value_t value2, |
|
|
|
jit_cf_i_iI_func intrinsic) |
|
|
|
{ |
|
|
|
if(value1->is_nint_constant && value2 && value2->is_nint_constant) |
|
|
|
{ |
|
|
|
const_result->un.int_value = (*intrinsic)(value1->address, |
|
|
|
value2->address); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
result->un.int_value = intrinsic(value1->address, value2->address); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_i_II(jit_constant_t *const_result, |
|
|
|
apply_i_II(jit_constant_t *result, |
|
|
|
jit_value_t value1, jit_value_t value2, |
|
|
|
jit_cf_i_II_func intrinsic) |
|
|
|
{ |
|
|
|
if(value1->is_nint_constant && value2 && value2->is_nint_constant) |
|
|
|
{ |
|
|
|
const_result->un.int_value = (*intrinsic)(value1->address, value2->address); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
result->un.int_value = intrinsic(value1->address, value2->address); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_I_I(jit_constant_t *const_result, jit_value_t value1, |
|
|
|
apply_I_I(jit_constant_t *result, jit_value_t value, |
|
|
|
jit_cf_I_I_func intrinsic) |
|
|
|
{ |
|
|
|
if(value1->is_nint_constant) |
|
|
|
{ |
|
|
|
const_result->un.uint_value = (*intrinsic)(value1->address); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
result->un.uint_value = intrinsic(value->address); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_I_II(jit_constant_t *const_result, |
|
|
|
apply_I_II(jit_constant_t *result, |
|
|
|
jit_value_t value1, jit_value_t value2, |
|
|
|
jit_cf_I_II_func intrinsic) |
|
|
|
{ |
|
|
|
if(value1->is_nint_constant && value2 && value2->is_nint_constant) |
|
|
|
{ |
|
|
|
const_result->un.uint_value = (*intrinsic)(value1->address, value2->address); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
result->un.uint_value = intrinsic(value1->address, value2->address); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_i_pIII(jit_constant_t *const_result, |
|
|
|
apply_i_pIII(jit_constant_t *result, |
|
|
|
jit_value_t value1, jit_value_t value2, |
|
|
|
jit_cf_i_pIII_func intrinsic) |
|
|
|
{ |
|
|
|
if(value1->is_nint_constant && value2 && value2->is_nint_constant) |
|
|
|
{ |
|
|
|
return (*intrinsic)(&(const_result->un.uint_value), |
|
|
|
value1->address, value2->address); |
|
|
|
} |
|
|
|
return 0; |
|
|
|
return intrinsic(&result->un.uint_value, |
|
|
|
value1->address, value2->address); |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_l_l(jit_constant_t *const_result, jit_value_t value1, |
|
|
|
apply_l_l(jit_constant_t *result, jit_value_t value1, |
|
|
|
jit_cf_l_l_func intrinsic) |
|
|
|
{ |
|
|
|
#ifdef JIT_NATIVE_INT64 |
|
|
|
const_result->un.long_value = (*intrinsic)(value1->address); |
|
|
|
result->un.long_value = intrinsic(value1->address); |
|
|
|
#else |
|
|
|
const_result->un.long_value = (*intrinsic)(*(jit_long *)(value1->address)); |
|
|
|
result->un.long_value = intrinsic(*((jit_long *) value1->address)); |
|
|
|
#endif |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_l_ll(jit_constant_t *const_result, |
|
|
|
apply_l_ll(jit_constant_t *result, |
|
|
|
jit_value_t value1, jit_value_t value2, |
|
|
|
jit_cf_l_ll_func intrinsic) |
|
|
|
{ |
|
|
|
if(value2 && value2->is_constant) |
|
|
|
{ |
|
|
|
#ifdef JIT_NATIVE_INT64 |
|
|
|
const_result->un.long_value = (*intrinsic)(value1->address, |
|
|
|
value2->address); |
|
|
|
result->un.long_value = intrinsic(value1->address, value2->address); |
|
|
|
#else |
|
|
|
const_result->un.long_value = (*intrinsic)(*(jit_long *)(value1->address), |
|
|
|
*(jit_long *)(value2->address)); |
|
|
|
result->un.long_value = intrinsic(*((jit_long *) value1->address), |
|
|
|
*((jit_long *) value2->address)); |
|
|
|
#endif |
|
|
|
return 1; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_i_plll(jit_constant_t *const_result, |
|
|
|
apply_i_plll(jit_constant_t *result, |
|
|
|
jit_value_t value1, jit_value_t value2, |
|
|
|
jit_cf_i_plll_func intrinsic) |
|
|
|
{ |
|
|
|
if(value2 && value2->is_constant) |
|
|
|
{ |
|
|
|
#ifdef JIT_NATIVE_INT64 |
|
|
|
return (*intrinsic)(&(const_result->un.long_value), |
|
|
|
value1->address, value2->address); |
|
|
|
return intrinsic(&result->un.long_value, |
|
|
|
value1->address, value2->address); |
|
|
|
#else |
|
|
|
return (*intrinsic)(&(const_result->un.long_value), |
|
|
|
*(jit_long *)(value1->address), |
|
|
|
*(jit_long *)(value2->address)); |
|
|
|
return intrinsic(&result->un.long_value, |
|
|
|
*((jit_long *) value1->address), |
|
|
|
*((jit_long *) value2->address)); |
|
|
|
#endif |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_i_l(jit_constant_t *const_result, |
|
|
|
apply_i_l(jit_constant_t *result, |
|
|
|
jit_value_t value, jit_cf_i_l_func intrinsic) |
|
|
|
{ |
|
|
|
#ifdef JIT_NATIVE_INT64 |
|
|
|
const_result->un.int_value = (*intrinsic)(value->address); |
|
|
|
result->un.int_value = intrinsic(value->address); |
|
|
|
#else |
|
|
|
const_result->un.int_value = (*intrinsic)(*(jit_long *)(value->address)); |
|
|
|
result->un.int_value = intrinsic(*((jit_long *) value->address)); |
|
|
|
#endif |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_i_ll(jit_constant_t *const_result, |
|
|
|
apply_i_ll(jit_constant_t *result, |
|
|
|
jit_value_t value1, jit_value_t value2, |
|
|
|
jit_cf_i_ll_func intrinsic) |
|
|
|
{ |
|
|
|
if(value2 && value2->is_constant) |
|
|
|
{ |
|
|
|
#ifdef JIT_NATIVE_INT64 |
|
|
|
const_result->un.int_value = (*intrinsic)(value1->address, |
|
|
|
value2->address); |
|
|
|
result->un.int_value = intrinsic(value1->address, value2->address); |
|
|
|
#else |
|
|
|
const_result->un.int_value = (*intrinsic)(*(jit_long *)(value1->address), |
|
|
|
*(jit_long *)(value2->address)); |
|
|
|
result->un.int_value = intrinsic(*((jit_long *) value1->address), |
|
|
|
*((jit_long *) value2->address)); |
|
|
|
#endif |
|
|
|
return 1; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_l_lI(jit_constant_t *const_result, |
|
|
|
apply_l_lI(jit_constant_t *result, |
|
|
|
jit_value_t value1, jit_value_t value2, |
|
|
|
jit_cf_l_lI_func intrinsic) |
|
|
|
{ |
|
|
|
if(value2 && value2->is_nint_constant) |
|
|
|
{ |
|
|
|
#ifdef JIT_NATIVE_INT64 |
|
|
|
const_result->un.long_value = (*intrinsic)(value1->address, |
|
|
|
value2->address); |
|
|
|
result->un.long_value = intrinsic(value1->address, value2->address); |
|
|
|
#else |
|
|
|
const_result->un.long_value = (*intrinsic)(*(jit_long *)(value1->address), |
|
|
|
value2->address); |
|
|
|
result->un.long_value = intrinsic(*((jit_long *) value1->address), |
|
|
|
value2->address); |
|
|
|
#endif |
|
|
|
return 1; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_L_L(jit_constant_t *const_result, jit_value_t value, |
|
|
|
apply_L_L(jit_constant_t *result, jit_value_t value, |
|
|
|
jit_cf_L_L_func intrinsic) |
|
|
|
{ |
|
|
|
#ifdef JIT_NATIVE_INT64 |
|
|
|
const_result->un.ulong_value = (*intrinsic)(value->address); |
|
|
|
result->un.ulong_value = intrinsic(value->address); |
|
|
|
#else |
|
|
|
const_result->un.ulong_value = (*intrinsic)(*(jit_ulong *)(value->address)); |
|
|
|
result->un.ulong_value = intrinsic(*((jit_ulong *) value->address)); |
|
|
|
#endif |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_L_LL(jit_constant_t *const_result, |
|
|
|
apply_L_LL(jit_constant_t *result, |
|
|
|
jit_value_t value1, jit_value_t value2, |
|
|
|
jit_cf_L_LL_func intrinsic) |
|
|
|
{ |
|
|
|
if(value2 && value2->is_constant) |
|
|
|
{ |
|
|
|
#ifdef JIT_NATIVE_INT64 |
|
|
|
const_result->un.ulong_value = (*intrinsic)(value1->address, |
|
|
|
value2->address); |
|
|
|
result->un.ulong_value = intrinsic(value1->address, value2->address); |
|
|
|
#else |
|
|
|
const_result->un.ulong_value = (*intrinsic)(*(jit_ulong *)(value1->address), |
|
|
|
*(jit_ulong *)(value2->address)); |
|
|
|
result->un.ulong_value = intrinsic(*((jit_ulong *) value1->address), |
|
|
|
*((jit_ulong *) value2->address)); |
|
|
|
#endif |
|
|
|
return 1; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_i_pLLL(jit_constant_t *const_result, |
|
|
|
apply_i_pLLL(jit_constant_t *result, |
|
|
|
jit_value_t value1, jit_value_t value2, |
|
|
|
jit_cf_i_pLLL_func intrinsic) |
|
|
|
{ |
|
|
|
if(value2 && value2->is_constant) |
|
|
|
{ |
|
|
|
#ifdef JIT_NATIVE_INT64 |
|
|
|
return (*intrinsic)(&(const_result->un.ulong_value), |
|
|
|
value1->address, value2->address); |
|
|
|
return intrinsic(&result->un.ulong_value, |
|
|
|
value1->address, value2->address); |
|
|
|
#else |
|
|
|
return (*intrinsic)(&(const_result->un.ulong_value), |
|
|
|
*(jit_ulong *)(value1->address), |
|
|
|
*(jit_ulong *)(value2->address)); |
|
|
|
return intrinsic(&result->un.ulong_value, |
|
|
|
*((jit_ulong *) value1->address), |
|
|
|
*((jit_ulong *) value2->address)); |
|
|
|
#endif |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_i_LL(jit_constant_t *const_result, |
|
|
|
apply_i_LL(jit_constant_t *result, |
|
|
|
jit_value_t value1, jit_value_t value2, |
|
|
|
jit_cf_i_LL_func intrinsic) |
|
|
|
{ |
|
|
|
if(value2 && value2->is_constant) |
|
|
|
{ |
|
|
|
#ifdef JIT_NATIVE_INT64 |
|
|
|
const_result->un.int_value = (*intrinsic)(value1->address, |
|
|
|
value2->address); |
|
|
|
result->un.int_value = intrinsic(value1->address, value2->address); |
|
|
|
#else |
|
|
|
const_result->un.int_value = (*intrinsic)(*(jit_ulong *)(value1->address), |
|
|
|
*(jit_ulong *)(value2->address)); |
|
|
|
result->un.int_value = intrinsic(*((jit_ulong *) value1->address), |
|
|
|
*((jit_ulong *) value2->address)); |
|
|
|
#endif |
|
|
|
return 1; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_L_LI(jit_constant_t *const_result, |
|
|
|
apply_L_LI(jit_constant_t *result, |
|
|
|
jit_value_t value1, jit_value_t value2, |
|
|
|
jit_cf_L_LI_func intrinsic) |
|
|
|
{ |
|
|
|
if(value2 && value2->is_nint_constant) |
|
|
|
{ |
|
|
|
#ifdef JIT_NATIVE_INT64 |
|
|
|
const_result->un.ulong_value = (*intrinsic)(value1->address, |
|
|
|
value2->address); |
|
|
|
result->un.ulong_value = intrinsic(value1->address, value2->address); |
|
|
|
#else |
|
|
|
const_result->un.ulong_value = (*intrinsic)(*(jit_ulong *)(value1->address), |
|
|
|
value2->address); |
|
|
|
result->un.ulong_value = intrinsic(*((jit_ulong *) value1->address), |
|
|
|
value2->address); |
|
|
|
#endif |
|
|
|
return 1; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_f_f(jit_constant_t *const_result, jit_value_t value, |
|
|
|
apply_f_f(jit_constant_t *result, jit_value_t value, |
|
|
|
jit_cf_f_f_func intrinsic) |
|
|
|
{ |
|
|
|
const_result->un.float32_value = (*intrinsic)(*(jit_float32 *)(value->address)); |
|
|
|
result->un.float32_value = intrinsic(*((jit_float32 *) value->address)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_f_ff(jit_constant_t *const_result, |
|
|
|
apply_f_ff(jit_constant_t *result, |
|
|
|
jit_value_t value1, jit_value_t value2, |
|
|
|
jit_cf_f_ff_func intrinsic) |
|
|
|
{ |
|
|
|
if(value2 && value2->is_constant) |
|
|
|
{ |
|
|
|
const_result->un.float32_value = (*intrinsic)(*(jit_float32 *)(value1->address), |
|
|
|
*(jit_float32 *)(value2->address)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
result->un.float32_value = intrinsic(*((jit_float32 *) value1->address), |
|
|
|
*((jit_float32 *) value2->address)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_i_f(jit_constant_t *const_result, jit_value_t value, |
|
|
|
apply_i_f(jit_constant_t *result, jit_value_t value, |
|
|
|
jit_cf_i_f_func intrinsic) |
|
|
|
{ |
|
|
|
const_result->un.int_value = (*intrinsic)(*(jit_float32 *)(value->address)); |
|
|
|
result->un.int_value = intrinsic(*((jit_float32 *) value->address)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_i_ff(jit_constant_t *const_result, |
|
|
|
apply_i_ff(jit_constant_t *result, |
|
|
|
jit_value_t value1, jit_value_t value2, |
|
|
|
jit_cf_i_ff_func intrinsic) |
|
|
|
{ |
|
|
|
if(value2 && value2->is_constant) |
|
|
|
{ |
|
|
|
const_result->un.int_value = (*intrinsic)(*(jit_float32 *)(value1->address), |
|
|
|
*(jit_float32 *)(value2->address)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
result->un.int_value = intrinsic(*((jit_float32 *) value1->address), |
|
|
|
*((jit_float32 *) value2->address)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_d_d(jit_constant_t *const_result, jit_value_t value, |
|
|
|
apply_d_d(jit_constant_t *result, jit_value_t value, |
|
|
|
jit_cf_d_d_func intrinsic) |
|
|
|
{ |
|
|
|
const_result->un.float64_value = (*intrinsic)(*(jit_float64 *)(value->address)); |
|
|
|
result->un.float64_value = intrinsic(*((jit_float64 *) value->address)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_d_dd(jit_constant_t *const_result, |
|
|
|
apply_d_dd(jit_constant_t *result, |
|
|
|
jit_value_t value1, jit_value_t value2, |
|
|
|
jit_cf_d_dd_func intrinsic) |
|
|
|
{ |
|
|
|
if(value2 && value2->is_constant) |
|
|
|
{ |
|
|
|
const_result->un.float64_value = (*intrinsic)(*(jit_float64 *)(value1->address), |
|
|
|
*(jit_float64 *)(value2->address)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
result->un.float64_value = intrinsic(*((jit_float64 *) value1->address), |
|
|
|
*((jit_float64 *) value2->address)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_i_d(jit_constant_t *const_result, jit_value_t value, |
|
|
|
apply_i_d(jit_constant_t *result, jit_value_t value, |
|
|
|
jit_cf_i_d_func intrinsic) |
|
|
|
{ |
|
|
|
const_result->un.int_value = (*intrinsic)(*(jit_float64 *)(value->address)); |
|
|
|
result->un.int_value = intrinsic(*((jit_float64 *) value->address)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_i_dd(jit_constant_t *const_result, |
|
|
|
apply_i_dd(jit_constant_t *result, |
|
|
|
jit_value_t value1, jit_value_t value2, |
|
|
|
jit_cf_i_dd_func intrinsic) |
|
|
|
{ |
|
|
|
if(value2 && value2->is_constant) |
|
|
|
{ |
|
|
|
const_result->un.int_value = (*intrinsic)(*(jit_float64 *)(value1->address), |
|
|
|
*(jit_float64 *)(value2->address)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
result->un.int_value = intrinsic(*((jit_float64 *) value1->address), |
|
|
|
*((jit_float64 *) value2->address)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_D_D(jit_constant_t *const_result, jit_value_t value, |
|
|
|
apply_D_D(jit_constant_t *result, jit_value_t value, |
|
|
|
jit_cf_D_D_func intrinsic) |
|
|
|
{ |
|
|
|
const_result->un.nfloat_value = (*intrinsic)(*(jit_nfloat *)(value->address)); |
|
|
|
result->un.nfloat_value = intrinsic(*((jit_nfloat *) value->address)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_D_DD(jit_constant_t *const_result, |
|
|
|
apply_D_DD(jit_constant_t *result, |
|
|
|
jit_value_t value1, jit_value_t value2, |
|
|
|
jit_cf_D_DD_func intrinsic) |
|
|
|
{ |
|
|
|
if(value2 && value2->is_constant) |
|
|
|
{ |
|
|
|
const_result->un.nfloat_value = (*intrinsic)(*(jit_nfloat *)(value1->address), |
|
|
|
*(jit_nfloat *)(value2->address)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
result->un.nfloat_value = intrinsic(*((jit_nfloat *) value1->address), |
|
|
|
*((jit_nfloat *) value2->address)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
apply_i_D(jit_constant_t *const_result, |
|
|
|
apply_i_D(jit_constant_t *result, |
|
|
|
jit_value_t value, jit_cf_i_D_func intrinsic) |
|
|
|
{ |
|
|
|
const_result->un.int_value = (*intrinsic)(*(jit_nfloat *)(value->address)); |
|
|
|
result->un.int_value = intrinsic(*((jit_nfloat *) value->address)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
@ -540,243 +439,256 @@ apply_i_DD(jit_constant_t *const_result, |
|
|
|
jit_value_t value1, jit_value_t value2, |
|
|
|
jit_cf_i_DD_func intrinsic) |
|
|
|
{ |
|
|
|
if(value2 && value2->is_constant) |
|
|
|
{ |
|
|
|
const_result->un.int_value = (*intrinsic)(*(jit_nfloat *)(value1->address), |
|
|
|
*(jit_nfloat *)(value2->address)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
const_result->un.int_value = intrinsic(*((jit_nfloat *) value1->address), |
|
|
|
*((jit_nfloat *) value2->address)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
static jit_value_t |
|
|
|
apply_opcode(jit_function_t func, const _jit_intrinsic_info_t *opcode_info, |
|
|
|
jit_type_t dest_type, jit_value_t value1, jit_value_t value2) |
|
|
|
jit_type_t type, jit_value_t value1, jit_value_t value2) |
|
|
|
{ |
|
|
|
jit_constant_t const_result; |
|
|
|
int result = 0; |
|
|
|
int success = 0; |
|
|
|
|
|
|
|
const_result.type = dest_type; |
|
|
|
jit_constant_t result; |
|
|
|
result.type = type; |
|
|
|
switch(opcode_info->signature) |
|
|
|
{ |
|
|
|
case JIT_SIG_i_i: |
|
|
|
result = apply_i_i(&const_result, value1, |
|
|
|
(jit_cf_i_i_func) opcode_info->intrinsic); |
|
|
|
success = apply_i_i(&result, value1, |
|
|
|
(jit_cf_i_i_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_i_ii: |
|
|
|
result = apply_i_ii |
|
|
|
(&const_result, value1, value2, |
|
|
|
(jit_cf_i_ii_func) opcode_info->intrinsic); |
|
|
|
success = apply_i_ii(&result, value1, value2, |
|
|
|
(jit_cf_i_ii_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_i_piii: |
|
|
|
result = apply_i_piii(&const_result, value1, value2, |
|
|
|
(jit_cf_i_piii_func) opcode_info->intrinsic); |
|
|
|
success = apply_i_piii(&result, value1, value2, |
|
|
|
(jit_cf_i_piii_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_i_iI: |
|
|
|
result = apply_i_iI(&const_result, value1, value2, |
|
|
|
(jit_cf_i_iI_func) opcode_info->intrinsic); |
|
|
|
success = apply_i_iI(&result, value1, value2, |
|
|
|
(jit_cf_i_iI_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_i_II: |
|
|
|
result = apply_i_II(&const_result, value1, value2, |
|
|
|
(jit_cf_i_II_func) opcode_info->intrinsic); |
|
|
|
success = apply_i_II(&result, value1, value2, |
|
|
|
(jit_cf_i_II_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_I_I: |
|
|
|
result = apply_I_I(&const_result, value1, |
|
|
|
(jit_cf_I_I_func) opcode_info->intrinsic); |
|
|
|
success = apply_I_I(&result, value1, |
|
|
|
(jit_cf_I_I_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_I_II: |
|
|
|
result = apply_I_II(&const_result, value1, value2, |
|
|
|
(jit_cf_I_II_func) opcode_info->intrinsic); |
|
|
|
success = apply_I_II(&result, value1, value2, |
|
|
|
(jit_cf_I_II_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_i_pIII: |
|
|
|
result = apply_i_pIII(&const_result, value1, value2, |
|
|
|
(jit_cf_i_pIII_func) opcode_info->intrinsic); |
|
|
|
success = apply_i_pIII(&result, value1, value2, |
|
|
|
(jit_cf_i_pIII_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_l_l: |
|
|
|
result = apply_l_l(&const_result, value1, |
|
|
|
(jit_cf_l_l_func) opcode_info->intrinsic); |
|
|
|
success = apply_l_l(&result, value1, |
|
|
|
(jit_cf_l_l_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_l_ll: |
|
|
|
result = apply_l_ll(&const_result, value1, value2, |
|
|
|
(jit_cf_l_ll_func) opcode_info->intrinsic); |
|
|
|
success = apply_l_ll(&result, value1, value2, |
|
|
|
(jit_cf_l_ll_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_i_plll: |
|
|
|
result = apply_i_plll(&const_result, value1, value2, |
|
|
|
(jit_cf_i_plll_func) opcode_info->intrinsic); |
|
|
|
success = apply_i_plll(&result, value1, value2, |
|
|
|
(jit_cf_i_plll_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_i_l: |
|
|
|
result = apply_i_l(&const_result, value1, |
|
|
|
(jit_cf_i_l_func) opcode_info->intrinsic); |
|
|
|
success = apply_i_l(&result, value1, |
|
|
|
(jit_cf_i_l_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_i_ll: |
|
|
|
result = apply_i_ll(&const_result, value1, value2, |
|
|
|
(jit_cf_i_ll_func) opcode_info->intrinsic); |
|
|
|
success = apply_i_ll(&result, value1, value2, |
|
|
|
(jit_cf_i_ll_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_l_lI: |
|
|
|
result = apply_l_lI(&const_result, value1, value2, |
|
|
|
(jit_cf_l_lI_func) opcode_info->intrinsic); |
|
|
|
success = apply_l_lI(&result, value1, value2, |
|
|
|
(jit_cf_l_lI_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_L_L: |
|
|
|
result = apply_L_L(&const_result, value1, |
|
|
|
(jit_cf_L_L_func) opcode_info->intrinsic); |
|
|
|
success = apply_L_L(&result, value1, |
|
|
|
(jit_cf_L_L_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_L_LL: |
|
|
|
result = apply_L_LL(&const_result, value1, value2, |
|
|
|
(jit_cf_L_LL_func) opcode_info->intrinsic); |
|
|
|
success = apply_L_LL(&result, value1, value2, |
|
|
|
(jit_cf_L_LL_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_i_pLLL: |
|
|
|
result = apply_i_pLLL(&const_result, value1, value2, |
|
|
|
(jit_cf_i_pLLL_func) opcode_info->intrinsic); |
|
|
|
success = apply_i_pLLL(&result, value1, value2, |
|
|
|
(jit_cf_i_pLLL_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_i_LL: |
|
|
|
result = apply_i_LL(&const_result, value1, value2, |
|
|
|
(jit_cf_i_LL_func) opcode_info->intrinsic); |
|
|
|
success = apply_i_LL(&result, value1, value2, |
|
|
|
(jit_cf_i_LL_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_L_LI: |
|
|
|
result = apply_L_LI(&const_result, value1, value2, |
|
|
|
(jit_cf_L_LI_func) opcode_info->intrinsic); |
|
|
|
success = apply_L_LI(&result, value1, value2, |
|
|
|
(jit_cf_L_LI_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_f_f: |
|
|
|
result = apply_f_f(&const_result, value1, |
|
|
|
(jit_cf_f_f_func) opcode_info->intrinsic); |
|
|
|
success = apply_f_f(&result, value1, |
|
|
|
(jit_cf_f_f_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_f_ff: |
|
|
|
result = apply_f_ff(&const_result, value1, value2, |
|
|
|
(jit_cf_f_ff_func) opcode_info->intrinsic); |
|
|
|
success = apply_f_ff(&result, value1, value2, |
|
|
|
(jit_cf_f_ff_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_i_f: |
|
|
|
result = apply_i_f(&const_result, value1, |
|
|
|
(jit_cf_i_f_func) opcode_info->intrinsic); |
|
|
|
success = apply_i_f(&result, value1, |
|
|
|
(jit_cf_i_f_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_i_ff: |
|
|
|
result = apply_i_ff(&const_result, value1, value2, |
|
|
|
(jit_cf_i_ff_func) opcode_info->intrinsic); |
|
|
|
success = apply_i_ff(&result, value1, value2, |
|
|
|
(jit_cf_i_ff_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_d_d: |
|
|
|
result = apply_d_d(&const_result, value1, |
|
|
|
(jit_cf_d_d_func) opcode_info->intrinsic); |
|
|
|
success = apply_d_d(&result, value1, |
|
|
|
(jit_cf_d_d_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_d_dd: |
|
|
|
result = apply_d_dd(&const_result, value1, value2, |
|
|
|
(jit_cf_d_dd_func) opcode_info->intrinsic); |
|
|
|
success = apply_d_dd(&result, value1, value2, |
|
|
|
(jit_cf_d_dd_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_i_d: |
|
|
|
result = apply_i_d(&const_result, value1, |
|
|
|
(jit_cf_i_d_func) opcode_info->intrinsic); |
|
|
|
success = apply_i_d(&result, value1, |
|
|
|
(jit_cf_i_d_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_i_dd: |
|
|
|
result = apply_i_dd(&const_result, value1, value2, |
|
|
|
(jit_cf_i_dd_func) opcode_info->intrinsic); |
|
|
|
success = apply_i_dd(&result, value1, value2, |
|
|
|
(jit_cf_i_dd_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_D_D: |
|
|
|
result = apply_D_D(&const_result, value1, |
|
|
|
(jit_cf_D_D_func) opcode_info->intrinsic); |
|
|
|
success = apply_D_D(&result, value1, |
|
|
|
(jit_cf_D_D_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_D_DD: |
|
|
|
result = apply_D_DD(&const_result, value1, value2, |
|
|
|
(jit_cf_D_DD_func) opcode_info->intrinsic); |
|
|
|
success = apply_D_DD(&result, value1, value2, |
|
|
|
(jit_cf_D_DD_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_i_D: |
|
|
|
result = apply_i_D(&const_result, value1, |
|
|
|
(jit_cf_i_D_func) opcode_info->intrinsic); |
|
|
|
success = apply_i_D(&result, value1, |
|
|
|
(jit_cf_i_D_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_i_DD: |
|
|
|
result = apply_i_DD(&const_result, value1, value2, |
|
|
|
(jit_cf_i_DD_func) opcode_info->intrinsic); |
|
|
|
success = apply_i_DD(&result, value1, value2, |
|
|
|
(jit_cf_i_DD_func) opcode_info->intrinsic); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_conv: |
|
|
|
result = apply_conv(&const_result, value1, 0); |
|
|
|
success = apply_conv(&result, value1, 0); |
|
|
|
break; |
|
|
|
|
|
|
|
case JIT_SIG_conv_ovf: |
|
|
|
result = apply_conv(&const_result, value1, 1); |
|
|
|
success = apply_conv(&result, value1, 1); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
if(result) |
|
|
|
if(!success) |
|
|
|
{ |
|
|
|
return jit_value_create_constant(func, &const_result); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
return jit_value_create_constant(func, &result); |
|
|
|
} |
|
|
|
|
|
|
|
jit_value_t |
|
|
|
_jit_opcode_apply(jit_function_t func, jit_uint opcode, jit_type_t dest_type, |
|
|
|
jit_value_t value1, jit_value_t value2) |
|
|
|
static jit_value_t |
|
|
|
_jit_opcode_apply_helper(jit_function_t func, jit_uint opcode, jit_type_t type, |
|
|
|
jit_value_t value1, jit_value_t value2) |
|
|
|
{ |
|
|
|
const _jit_intrinsic_info_t *opcode_info; |
|
|
|
|
|
|
|
if(!func || opcode >= JIT_OP_NUM_OPCODES) |
|
|
|
{ |
|
|
|
return 0; |
|
|
|
} |
|
|
|
if((value1 == 0) || !value1->is_constant) |
|
|
|
{ |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
opcode_info = &_jit_intrinsics[opcode]; |
|
|
|
const _jit_intrinsic_info_t *opcode_info = &_jit_intrinsics[opcode]; |
|
|
|
|
|
|
|
if((opcode_info->flags & _JIT_INTRINSIC_FLAG_MASK) == _JIT_INTRINSIC_FLAG_NONE) |
|
|
|
jit_short flag = opcode_info->flags & _JIT_INTRINSIC_FLAG_MASK; |
|
|
|
if (flag != _JIT_INTRINSIC_FLAG_NONE) |
|
|
|
{ |
|
|
|
return apply_opcode(func, opcode_info, dest_type, value1, value2); |
|
|
|
} |
|
|
|
if (flag != _JIT_INTRINSIC_FLAG_NOT) |
|
|
|
{ |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
if((opcode_info->flags & _JIT_INTRINSIC_FLAG_MASK) == _JIT_INTRINSIC_FLAG_NOT) |
|
|
|
{ |
|
|
|
jit_value_t value; |
|
|
|
|
|
|
|
opcode = opcode_info->flags & ~_JIT_INTRINSIC_FLAG_MASK; |
|
|
|
if(opcode >= JIT_OP_NUM_OPCODES) |
|
|
|
{ |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
opcode_info = &(_jit_intrinsics[opcode]); |
|
|
|
value = apply_opcode(func, opcode_info, dest_type, value1, value2); |
|
|
|
opcode_info = &_jit_intrinsics[opcode]; |
|
|
|
jit_value_t value = apply_opcode(func, opcode_info, type, |
|
|
|
value1, value2); |
|
|
|
if(value) |
|
|
|
{ |
|
|
|
/*
|
|
|
|
* We have to apply a logical not to the constant |
|
|
|
* jit_int result value. |
|
|
|
*/ |
|
|
|
value->address = !(value->address); |
|
|
|
return value; |
|
|
|
value->address = !value->address; |
|
|
|
} |
|
|
|
return value; |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
return apply_opcode(func, opcode_info, type, value1, value2); |
|
|
|
} |
|
|
|
|
|
|
|
jit_value_t |
|
|
|
_jit_opcode_apply_unary(jit_function_t func, jit_uint opcode, jit_type_t type, |
|
|
|
jit_value_t value) |
|
|
|
{ |
|
|
|
if(opcode >= JIT_OP_NUM_OPCODES) |
|
|
|
{ |
|
|
|
return 0; |
|
|
|
} |
|
|
|
if(!value->is_constant) |
|
|
|
{ |
|
|
|
return 0; |
|
|
|
} |
|
|
|
return _jit_opcode_apply_helper(func, opcode, type, value, value); |
|
|
|
} |
|
|
|
|
|
|
|
jit_value_t |
|
|
|
_jit_opcode_apply(jit_function_t func, jit_uint opcode, jit_type_t type, |
|
|
|
jit_value_t value1, jit_value_t value2) |
|
|
|
{ |
|
|
|
if(opcode >= JIT_OP_NUM_OPCODES) |
|
|
|
{ |
|
|
|
return 0; |
|
|
|
} |
|
|
|
if(!value1->is_constant || !value2->is_constant) |
|
|
|
{ |
|
|
|
return 0; |
|
|
|
} |
|
|
|
return _jit_opcode_apply_helper(func, opcode, type, value1, value2); |
|
|
|
} |
|
|
|