mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-03-12 00:45:28 +00:00
Fix missing float cmp for XIP (#1699)
This commit is contained in:
parent
cef4e74fee
commit
4b0660cf24
|
@ -72,6 +72,8 @@ static const aot_intrinsic g_intrinsic_mapping[] = {
|
|||
{ "i64.div_u", "aot_intrinsic_i64_div_u", AOT_INTRINSIC_FLAG_I64_DIV_U},
|
||||
{ "i64.rem_s", "aot_intrinsic_i64_rem_s", AOT_INTRINSIC_FLAG_I64_REM_S},
|
||||
{ "i64.rem_u", "aot_intrinsic_i64_rem_u", AOT_INTRINSIC_FLAG_I64_REM_U},
|
||||
{ "i64.or", "aot_intrinsic_i64_bit_or", AOT_INTRINSIC_FLAG_I64_BIT_OR},
|
||||
{ "i64.and", "aot_intrinsic_i64_bit_and", AOT_INTRINSIC_FLAG_I64_BIT_AND},
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
|
@ -524,6 +526,18 @@ aot_intrinsic_i64_rem_u(uint64 l, uint64 r)
|
|||
return l % r;
|
||||
}
|
||||
|
||||
uint64
|
||||
aot_intrinsic_i64_bit_or(uint64 l, uint64 r)
|
||||
{
|
||||
return l | r;
|
||||
}
|
||||
|
||||
uint64
|
||||
aot_intrinsic_i64_bit_and(uint64 l, uint64 r)
|
||||
{
|
||||
return l & r;
|
||||
}
|
||||
|
||||
const char *
|
||||
aot_intrinsic_get_symbol(const char *llvm_intrinsic)
|
||||
{
|
||||
|
@ -558,6 +572,8 @@ add_i64_common_intrinsics(AOTCompContext *comp_ctx)
|
|||
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I64_DIV_U);
|
||||
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I64_REM_S);
|
||||
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I64_REM_U);
|
||||
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I64_BIT_OR);
|
||||
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I64_BIT_AND);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -93,6 +93,8 @@ extern "C" {
|
|||
#define AOT_INTRINSIC_FLAG_I64_DIV_U AOT_INTRINSIC_FLAG(1, 29)
|
||||
#define AOT_INTRINSIC_FLAG_I64_REM_S AOT_INTRINSIC_FLAG(1, 30)
|
||||
#define AOT_INTRINSIC_FLAG_I64_REM_U AOT_INTRINSIC_FLAG(1, 31)
|
||||
#define AOT_INTRINSIC_FLAG_I64_BIT_OR AOT_INTRINSIC_FLAG(1, 32)
|
||||
#define AOT_INTRINSIC_FLAG_I64_BIT_AND AOT_INTRINSIC_FLAG(1, 33)
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
|
@ -267,6 +269,12 @@ aot_intrinsic_i64_rem_s(int64 l, int64 r);
|
|||
uint64
|
||||
aot_intrinsic_i64_rem_u(uint64 l, uint64 r);
|
||||
|
||||
uint64
|
||||
aot_intrinsic_i64_bit_or(uint64 l, uint64 r);
|
||||
|
||||
uint64
|
||||
aot_intrinsic_i64_bit_and(uint64 l, uint64 r);
|
||||
|
||||
const char *
|
||||
aot_intrinsic_get_symbol(const char *llvm_intrinsic);
|
||||
|
||||
|
|
|
@ -112,6 +112,8 @@ typedef struct {
|
|||
REG_SYM(aot_intrinsic_i64_div_u), \
|
||||
REG_SYM(aot_intrinsic_i64_rem_s), \
|
||||
REG_SYM(aot_intrinsic_i64_rem_u), \
|
||||
REG_SYM(aot_intrinsic_i64_bit_or), \
|
||||
REG_SYM(aot_intrinsic_i64_bit_and), \
|
||||
REG_SYM(aot_intrinsic_i32_div_u), \
|
||||
|
||||
#define REG_COMMON_SYMBOLS \
|
||||
|
|
|
@ -234,15 +234,49 @@ compile_op_float_min_max(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
nan = LLVMConstRealOfString(ret_type, "NaN");
|
||||
char *intrinsic = is_min ? (is_f32 ? "llvm.minnum.f32" : "llvm.minnum.f64")
|
||||
: (is_f32 ? "llvm.maxnum.f32" : "llvm.maxnum.f64");
|
||||
bool is_i32 = is_f32;
|
||||
|
||||
CHECK_LLVM_CONST(nan);
|
||||
|
||||
param_types[0] = param_types[1] = ret_type;
|
||||
|
||||
if (!(is_nan = LLVMBuildFCmp(comp_ctx->builder, LLVMRealUNO, left, right,
|
||||
"is_nan"))
|
||||
|| !(is_eq = LLVMBuildFCmp(comp_ctx->builder, LLVMRealOEQ, left, right,
|
||||
"is_eq"))) {
|
||||
if (comp_ctx->disable_llvm_intrinsics
|
||||
&& aot_intrinsic_check_capability(comp_ctx,
|
||||
is_f32 ? "f32_cmp" : "f64_cmp")) {
|
||||
LLVMTypeRef param_types[3];
|
||||
LLVMValueRef opcond = LLVMConstInt(I32_TYPE, FLOAT_UNO, true);
|
||||
param_types[0] = I32_TYPE;
|
||||
param_types[1] = is_f32 ? F32_TYPE : F64_TYPE;
|
||||
param_types[2] = param_types[1];
|
||||
is_nan = aot_call_llvm_intrinsic(
|
||||
comp_ctx, func_ctx, is_f32 ? "f32_cmp" : "f64_cmp", I32_TYPE,
|
||||
param_types, 3, opcond, left, right);
|
||||
|
||||
opcond = LLVMConstInt(I32_TYPE, FLOAT_EQ, true);
|
||||
is_eq = aot_call_llvm_intrinsic(
|
||||
comp_ctx, func_ctx, is_f32 ? "f32_cmp" : "f64_cmp", I32_TYPE,
|
||||
param_types, 3, opcond, left, right);
|
||||
|
||||
if (!is_nan || !is_eq) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(is_nan = LLVMBuildIntCast(comp_ctx->builder, is_nan, INT1_TYPE,
|
||||
"bit_cast_is_nan"))) {
|
||||
aot_set_last_error("llvm build is_nan bit cast fail.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(is_eq = LLVMBuildIntCast(comp_ctx->builder, is_eq, INT1_TYPE,
|
||||
"bit_cast_is_eq"))) {
|
||||
aot_set_last_error("llvm build is_eq bit cast fail.");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if (!(is_nan = LLVMBuildFCmp(comp_ctx->builder, LLVMRealUNO, left,
|
||||
right, "is_nan"))
|
||||
|| !(is_eq = LLVMBuildFCmp(comp_ctx->builder, LLVMRealOEQ, left,
|
||||
right, "is_eq"))) {
|
||||
aot_set_last_error("llvm build fcmp fail.");
|
||||
return NULL;
|
||||
}
|
||||
|
@ -258,9 +292,11 @@ compile_op_float_min_max(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
|
||||
if (is_min)
|
||||
LLVM_BUILD_OP(Or, left_int, right_int, tmp, "tmp_int", NULL);
|
||||
LLVM_BUILD_OP_OR_INTRINSIC(Or, left_int, right_int, tmp, "i64.or",
|
||||
"tmp_int", false);
|
||||
else
|
||||
LLVM_BUILD_OP(And, left_int, right_int, tmp, "tmp_int", NULL);
|
||||
LLVM_BUILD_OP_OR_INTRINSIC(And, left_int, right_int, tmp, "i64.and",
|
||||
"tmp_int", false);
|
||||
|
||||
if (!(tmp = LLVMBuildBitCast(comp_ctx->builder, tmp, ret_type, "tmp"))) {
|
||||
aot_set_last_error("llvm build bitcast fail.");
|
||||
|
|
Loading…
Reference in New Issue
Block a user