mirror of
				https://github.com/bytecodealliance/wasm-micro-runtime.git
				synced 2025-10-31 13:17:31 +00:00 
			
		
		
		
	Implement i32.rem_s and i32.rem_u intrinsic (#1789)
This commit is contained in:
		
							parent
							
								
									ead6478285
								
							
						
					
					
						commit
						bfd57558a7
					
				|  | @ -69,6 +69,8 @@ static const aot_intrinsic g_intrinsic_mapping[] = { | |||
|     { "f64.const", NULL, AOT_INTRINSIC_FLAG_F64_CONST }, | ||||
|     { "i64.div_s", "aot_intrinsic_i64_div_s", AOT_INTRINSIC_FLAG_I64_DIV_S}, | ||||
|     { "i32.div_u", "aot_intrinsic_i32_div_u", AOT_INTRINSIC_FLAG_I32_DIV_U}, | ||||
|     { "i32.rem_s", "aot_intrinsic_i32_rem_s", AOT_INTRINSIC_FLAG_I32_REM_S}, | ||||
|     { "i32.rem_u", "aot_intrinsic_i32_rem_u", AOT_INTRINSIC_FLAG_I32_REM_U}, | ||||
|     { "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}, | ||||
|  | @ -508,6 +510,18 @@ aot_intrinsic_i32_div_u(uint32 l, uint32 r) | |||
|     return l / r; | ||||
| } | ||||
| 
 | ||||
| int32 | ||||
| aot_intrinsic_i32_rem_s(int32 l, int32 r) | ||||
| { | ||||
|     return l % r; | ||||
| } | ||||
| 
 | ||||
| uint32 | ||||
| aot_intrinsic_i32_rem_u(uint32 l, uint32 r) | ||||
| { | ||||
|     return l % r; | ||||
| } | ||||
| 
 | ||||
| uint64 | ||||
| aot_intrinsic_i64_div_u(uint64 l, uint64 r) | ||||
| { | ||||
|  | @ -580,6 +594,8 @@ static void | |||
| add_i32_common_intrinsics(AOTCompContext *comp_ctx) | ||||
| { | ||||
|     add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I32_DIV_U); | ||||
|     add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I32_REM_S); | ||||
|     add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I32_REM_U); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
|  | @ -675,6 +691,7 @@ aot_intrinsic_fill_capability_flags(AOTCompContext *comp_ctx) | |||
|         return; | ||||
| 
 | ||||
|     if (!strncmp(comp_ctx->target_arch, "thumb", 5)) { | ||||
|         add_i32_common_intrinsics(comp_ctx); | ||||
|         if (!strcmp(comp_ctx->target_cpu, "cortex-m7")) { | ||||
|         } | ||||
|         else if (!strcmp(comp_ctx->target_cpu, "cortex-m4")) { | ||||
|  |  | |||
|  | @ -60,6 +60,8 @@ extern "C" { | |||
| #define AOT_INTRINSIC_FLAG_F32_CONST    AOT_INTRINSIC_FLAG(0, 26) | ||||
| #define AOT_INTRINSIC_FLAG_I32_CONST    AOT_INTRINSIC_FLAG(0, 27) | ||||
| #define AOT_INTRINSIC_FLAG_I32_DIV_U    AOT_INTRINSIC_FLAG(0, 28) | ||||
| #define AOT_INTRINSIC_FLAG_I32_REM_S    AOT_INTRINSIC_FLAG(0, 29) | ||||
| #define AOT_INTRINSIC_FLAG_I32_REM_U    AOT_INTRINSIC_FLAG(0, 30) | ||||
| 
 | ||||
| #define AOT_INTRINSIC_FLAG_F64_FADD     AOT_INTRINSIC_FLAG(1, 0) | ||||
| #define AOT_INTRINSIC_FLAG_F64_FSUB     AOT_INTRINSIC_FLAG(1, 1) | ||||
|  | @ -260,6 +262,12 @@ aot_intrinsic_i64_div_s(int64 l, int64 r); | |||
| uint32 | ||||
| aot_intrinsic_i32_div_u(uint32 l, uint32 r); | ||||
| 
 | ||||
| int32 | ||||
| aot_intrinsic_i32_rem_s(int32 l, int32 r); | ||||
| 
 | ||||
| uint32 | ||||
| aot_intrinsic_i32_rem_u(uint32 l, uint32 r); | ||||
| 
 | ||||
| uint64 | ||||
| aot_intrinsic_i64_div_u(uint64 l, uint64 r); | ||||
| 
 | ||||
|  |  | |||
|  | @ -115,6 +115,8 @@ typedef struct { | |||
|     REG_SYM(aot_intrinsic_i64_bit_or),    \ | ||||
|     REG_SYM(aot_intrinsic_i64_bit_and),   \ | ||||
|     REG_SYM(aot_intrinsic_i32_div_u),     \ | ||||
|     REG_SYM(aot_intrinsic_i32_rem_s),     \ | ||||
|     REG_SYM(aot_intrinsic_i32_rem_u),     \ | ||||
| 
 | ||||
| #define REG_COMMON_SYMBOLS                \ | ||||
|     REG_SYM(aot_set_exception_with_id),   \ | ||||
|  |  | |||
|  | @ -31,7 +31,7 @@ | |||
| #define LLVM_BUILD_OP_OR_INTRINSIC(Op, left, right, res, intrinsic, name, \ | ||||
|                                    err_ret)                               \ | ||||
|     do {                                                                  \ | ||||
|         if (comp_ctx->disable_llvm_intrinsics && !is_i32                  \ | ||||
|         if (comp_ctx->disable_llvm_intrinsics                             \ | ||||
|             && aot_intrinsic_check_capability(comp_ctx, intrinsic)) {     \ | ||||
|             res = aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic,  \ | ||||
|                                           param_types[0], param_types, 2, \ | ||||
|  | @ -234,8 +234,6 @@ 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; | ||||
|  | @ -292,11 +290,13 @@ compile_op_float_min_max(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, | |||
|     } | ||||
| 
 | ||||
|     if (is_min) | ||||
|         LLVM_BUILD_OP_OR_INTRINSIC(Or, left_int, right_int, tmp, "i64.or", | ||||
|                                    "tmp_int", false); | ||||
|         LLVM_BUILD_OP_OR_INTRINSIC(Or, left_int, right_int, tmp, | ||||
|                                    is_f32 ? "i32.or" : "i64.or", "tmp_int", | ||||
|                                    false); | ||||
|     else | ||||
|         LLVM_BUILD_OP_OR_INTRINSIC(And, left_int, right_int, tmp, "i64.and", | ||||
|                                    "tmp_int", false); | ||||
|         LLVM_BUILD_OP_OR_INTRINSIC(And, left_int, right_int, tmp, | ||||
|                                    is_f32 ? "i32.and" : "i64.and", "tmp_int", | ||||
|                                    false); | ||||
| 
 | ||||
|     if (!(tmp = LLVMBuildBitCast(comp_ctx->builder, tmp, ret_type, "tmp"))) { | ||||
|         aot_set_last_error("llvm build bitcast fail."); | ||||
|  | @ -402,7 +402,8 @@ compile_rems(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, | |||
|     LLVMPositionBuilderAtEnd(comp_ctx->builder, no_overflow_block); | ||||
| 
 | ||||
|     LLVM_BUILD_OP_OR_INTRINSIC(SRem, left, right, no_overflow_value, | ||||
|                                "i64.rem_s", "rem_s", false); | ||||
|                                is_i32 ? "i32.rem_s" : "i64.rem_s", "rem_s", | ||||
|                                false); | ||||
| 
 | ||||
|     /* Jump to rems_end block */ | ||||
|     if (!LLVMBuildBr(comp_ctx->builder, rems_end_block)) { | ||||
|  | @ -516,20 +517,24 @@ compile_int_div(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, | |||
|                 /* Build div */ | ||||
|                 switch (arith_op) { | ||||
|                     case INT_DIV_S: | ||||
|                         LLVM_BUILD_OP_OR_INTRINSIC(SDiv, left, right, res, | ||||
|                                                    "i64.div_s", "div_s", false); | ||||
|                         LLVM_BUILD_OP_OR_INTRINSIC( | ||||
|                             SDiv, left, right, res, | ||||
|                             is_i32 ? "i32.div_s" : "i64.div_s", "div_s", false); | ||||
|                         break; | ||||
|                     case INT_DIV_U: | ||||
|                         LLVM_BUILD_OP_OR_INTRINSIC(UDiv, left, right, res, | ||||
|                                                    "i64.div_u", "div_u", false); | ||||
|                         LLVM_BUILD_OP_OR_INTRINSIC( | ||||
|                             UDiv, left, right, res, | ||||
|                             is_i32 ? "i32.div_u" : "i64.div_u", "div_u", false); | ||||
|                         break; | ||||
|                     case INT_REM_S: | ||||
|                         LLVM_BUILD_OP_OR_INTRINSIC(SRem, left, right, res, | ||||
|                                                    "i64.rem_s", "rem_s", false); | ||||
|                         LLVM_BUILD_OP_OR_INTRINSIC( | ||||
|                             SRem, left, right, res, | ||||
|                             is_i32 ? "i32.rem_s" : "i64.rem_s", "rem_s", false); | ||||
|                         break; | ||||
|                     case INT_REM_U: | ||||
|                         LLVM_BUILD_OP_OR_INTRINSIC(URem, left, right, res, | ||||
|                                                    "i64.rem_u", "rem_u", false); | ||||
|                         LLVM_BUILD_OP_OR_INTRINSIC( | ||||
|                             URem, left, right, res, | ||||
|                             is_i32 ? "i32.rem_u" : "i64.rem_u", "rem_u", false); | ||||
|                         break; | ||||
|                     default: | ||||
|                         bh_assert(0); | ||||
|  | @ -568,7 +573,8 @@ compile_int_div(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, | |||
|                                          check_overflow_succ))) | ||||
|                     goto fail; | ||||
| 
 | ||||
|                 LLVM_BUILD_OP_OR_INTRINSIC(SDiv, left, right, res, "i64.div_s", | ||||
|                 LLVM_BUILD_OP_OR_INTRINSIC(SDiv, left, right, res, | ||||
|                                            is_i32 ? "i32.div_s" : "i64.div_s", | ||||
|                                            "div_s", false); | ||||
|                 PUSH_INT(res); | ||||
|                 return true; | ||||
|  | @ -594,7 +600,8 @@ compile_int_div(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, | |||
|                 return compile_rems(comp_ctx, func_ctx, left, right, overflow, | ||||
|                                     is_i32); | ||||
|             case INT_REM_U: | ||||
|                 LLVM_BUILD_OP_OR_INTRINSIC(URem, left, right, res, "i64.rem_u", | ||||
|                 LLVM_BUILD_OP_OR_INTRINSIC(URem, left, right, res, | ||||
|                                            is_i32 ? "i32.rem_u" : "i64.rem_u", | ||||
|                                            "rem_u", false); | ||||
|                 PUSH_INT(res); | ||||
|                 return true; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Huang Qi
						Huang Qi