|
|
@@ -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);
|