Implement i64.div and i64.rem intrinsics (#1375)

This commit is contained in:
Huang Qi
2022-08-12 11:09:06 +08:00
committed by GitHub
parent 88cf1e36c1
commit 2178787664
4 changed files with 108 additions and 4 deletions

View File

@ -388,6 +388,9 @@ compile_int_div(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
{
LLVMValueRef left, right, cmp_div_zero, overflow, res;
LLVMBasicBlockRef check_div_zero_succ, check_overflow_succ;
LLVMTypeRef param_types[2];
param_types[1] = param_types[0] = is_i32 ? I32_TYPE : I64_TYPE;
bh_assert(arith_op == INT_DIV_S || arith_op == INT_DIV_U
|| arith_op == INT_REM_S || arith_op == INT_REM_U);
@ -459,16 +462,56 @@ compile_int_div(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Build div */
switch (arith_op) {
case INT_DIV_S:
LLVM_BUILD_OP(SDiv, left, right, res, "div_s", false);
if (comp_ctx->disable_llvm_intrinsics && !is_i32
&& aot_intrinsic_check_capability(comp_ctx,
"i64.div_s")) {
res = aot_call_llvm_intrinsic(
comp_ctx, func_ctx, "i64.div_s", param_types[0],
param_types, 2, left, right);
}
else {
LLVM_BUILD_OP(SDiv, left, right, res, "div_s",
false);
}
break;
case INT_DIV_U:
LLVM_BUILD_OP(UDiv, left, right, res, "div_u", false);
if (comp_ctx->disable_llvm_intrinsics && !is_i32
&& aot_intrinsic_check_capability(comp_ctx,
"i64.div_u")) {
res = aot_call_llvm_intrinsic(
comp_ctx, func_ctx, "i64.div_u", param_types[0],
param_types, 2, left, right);
}
else {
LLVM_BUILD_OP(UDiv, left, right, res, "div_u",
false);
}
break;
case INT_REM_S:
LLVM_BUILD_OP(SRem, left, right, res, "rem_s", false);
if (comp_ctx->disable_llvm_intrinsics && !is_i32
&& aot_intrinsic_check_capability(comp_ctx,
"i64.rem_s")) {
res = aot_call_llvm_intrinsic(
comp_ctx, func_ctx, "i64.rem_s", param_types[0],
param_types, 2, left, right);
}
else {
LLVM_BUILD_OP(SRem, left, right, res, "rem_s",
false);
}
break;
case INT_REM_U:
LLVM_BUILD_OP(URem, left, right, res, "rem_u", false);
if (comp_ctx->disable_llvm_intrinsics && !is_i32
&& aot_intrinsic_check_capability(comp_ctx,
"i64.rem_u")) {
res = aot_call_llvm_intrinsic(
comp_ctx, func_ctx, "i64.rem_u", param_types[0],
param_types, 2, left, right);
}
else {
LLVM_BUILD_OP(URem, left, right, res, "rem_u",
false);
}
break;
default:
bh_assert(0);