Skip to content

Commit 8245aef

Browse files
authored
aot: add new u64 intrinsics (#4168)
1 parent 8f2fed4 commit 8245aef

File tree

4 files changed

+96
-20
lines changed

4 files changed

+96
-20
lines changed

core/iwasm/aot/aot_intrinsic.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,30 @@ aot_intrinsic_i64_bit_and(uint64 l, uint64 r)
485485
return l & r;
486486
}
487487

488+
uint64
489+
aot_intrinsic_i64_mul(uint64 l, uint64 r)
490+
{
491+
return l * r;
492+
}
493+
494+
uint64
495+
aot_intrinsic_i64_shl(uint64 l, uint64 r)
496+
{
497+
return l << r;
498+
}
499+
500+
uint64
501+
aot_intrinsic_i64_shr_s(uint64 l, uint64 r)
502+
{
503+
return (int64)l >> r;
504+
}
505+
506+
uint64
507+
aot_intrinsic_i64_shr_u(uint64 l, uint64 r)
508+
{
509+
return l >> r;
510+
}
511+
488512
#if WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0
489513

490514
typedef struct {
@@ -561,6 +585,10 @@ static const aot_intrinsic g_intrinsic_mapping[] = {
561585
{ "i64.rem_u", "aot_intrinsic_i64_rem_u", AOT_INTRINSIC_FLAG_I64_REM_U},
562586
{ "i64.or", "aot_intrinsic_i64_bit_or", AOT_INTRINSIC_FLAG_I64_BIT_OR},
563587
{ "i64.and", "aot_intrinsic_i64_bit_and", AOT_INTRINSIC_FLAG_I64_BIT_AND},
588+
{ "i64.mul", "aot_intrinsic_i64_mul", AOT_INTRINSIC_FLAG_I64_MUL},
589+
{ "i64.shl", "aot_intrinsic_i64_shl", AOT_INTRINSIC_FLAG_I64_SHL},
590+
{ "i64.shr_s", "aot_intrinsic_i64_shr_s", AOT_INTRINSIC_FLAG_I64_SHR_S},
591+
{ "i64.shr_u", "aot_intrinsic_i64_shr_u", AOT_INTRINSIC_FLAG_I64_SHR_U},
564592
};
565593
/* clang-format on */
566594

@@ -601,6 +629,10 @@ add_i64_common_intrinsics(AOTCompContext *comp_ctx)
601629
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I64_REM_U);
602630
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I64_BIT_OR);
603631
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I64_BIT_AND);
632+
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I64_MUL);
633+
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I64_SHL);
634+
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I64_SHR_S);
635+
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I64_SHR_U);
604636
}
605637

606638
static void

core/iwasm/aot/aot_intrinsic.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ extern "C" {
9898
#define AOT_INTRINSIC_FLAG_I64_REM_U AOT_INTRINSIC_FLAG(1, 31)
9999
#define AOT_INTRINSIC_FLAG_I64_BIT_OR AOT_INTRINSIC_FLAG(1, 32)
100100
#define AOT_INTRINSIC_FLAG_I64_BIT_AND AOT_INTRINSIC_FLAG(1, 33)
101+
#define AOT_INTRINSIC_FLAG_I64_MUL AOT_INTRINSIC_FLAG(1, 34)
102+
#define AOT_INTRINSIC_FLAG_I64_SHL AOT_INTRINSIC_FLAG(1, 35)
103+
#define AOT_INTRINSIC_FLAG_I64_SHR_S AOT_INTRINSIC_FLAG(1, 36)
104+
#define AOT_INTRINSIC_FLAG_I64_SHR_U AOT_INTRINSIC_FLAG(1, 37)
101105

102106
/* clang-format on */
103107

@@ -287,6 +291,18 @@ aot_intrinsic_i64_bit_or(uint64 l, uint64 r);
287291
uint64
288292
aot_intrinsic_i64_bit_and(uint64 l, uint64 r);
289293

294+
uint64
295+
aot_intrinsic_i64_mul(uint64 l, uint64 r);
296+
297+
uint64
298+
aot_intrinsic_i64_shl(uint64 l, uint64 r);
299+
300+
uint64
301+
aot_intrinsic_i64_shr_s(uint64 l, uint64 r);
302+
303+
uint64
304+
aot_intrinsic_i64_shr_u(uint64 l, uint64 r);
305+
290306
#if WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0
291307
const char *
292308
aot_intrinsic_get_symbol(const char *llvm_intrinsic);

core/iwasm/aot/aot_reloc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ typedef struct {
122122
REG_SYM(aot_intrinsic_i64_rem_u), \
123123
REG_SYM(aot_intrinsic_i64_bit_or), \
124124
REG_SYM(aot_intrinsic_i64_bit_and), \
125+
REG_SYM(aot_intrinsic_i64_mul), \
126+
REG_SYM(aot_intrinsic_i64_shl), \
127+
REG_SYM(aot_intrinsic_i64_shr_s), \
128+
REG_SYM(aot_intrinsic_i64_shr_u), \
125129
REG_SYM(aot_intrinsic_i32_div_s), \
126130
REG_SYM(aot_intrinsic_i32_div_u), \
127131
REG_SYM(aot_intrinsic_i32_rem_s), \

core/iwasm/compilation/aot_emit_numberic.c

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -653,15 +653,22 @@ compile_int_sub(AOTCompContext *comp_ctx, LLVMValueRef left, LLVMValueRef right,
653653
}
654654

655655
static LLVMValueRef
656-
compile_int_mul(AOTCompContext *comp_ctx, LLVMValueRef left, LLVMValueRef right,
657-
bool is_i32)
656+
compile_int_mul(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
657+
LLVMValueRef left, LLVMValueRef right, bool is_i32)
658658
{
659659
/* If one of the operands is 0, just return constant 0 */
660660
if (IS_CONST_ZERO(left) || IS_CONST_ZERO(right))
661661
return is_i32 ? I32_ZERO : I64_ZERO;
662662

663663
/* Build mul */
664-
return LLVMBuildMul(comp_ctx->builder, left, right, "mul");
664+
LLVMTypeRef param_types[2];
665+
param_types[1] = param_types[0] = is_i32 ? I32_TYPE : I64_TYPE;
666+
667+
LLVMValueRef res;
668+
LLVM_BUILD_OP_OR_INTRINSIC(Mul, left, right, res,
669+
is_i32 ? "i32.mul" : "i64.mul", "mul", false);
670+
671+
return res;
665672
}
666673

667674
static bool
@@ -679,8 +686,9 @@ compile_op_int_arithmetic(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
679686
"compile int sub fail.");
680687
return true;
681688
case INT_MUL:
682-
DEF_INT_BINARY_OP(compile_int_mul(comp_ctx, left, right, is_i32),
683-
"compile int mul fail.");
689+
DEF_INT_BINARY_OP(
690+
compile_int_mul(comp_ctx, func_ctx, left, right, is_i32),
691+
"compile int mul fail.");
684692
return true;
685693
case INT_DIV_S:
686694
case INT_DIV_U:
@@ -726,43 +734,57 @@ compile_op_int_bitwise(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
726734
}
727735

728736
static LLVMValueRef
729-
compile_int_shl(AOTCompContext *comp_ctx, LLVMValueRef left, LLVMValueRef right,
730-
bool is_i32)
737+
compile_int_shl(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
738+
LLVMValueRef left, LLVMValueRef right, bool is_i32)
731739
{
732740
LLVMValueRef res;
733741

734742
SHIFT_COUNT_MASK;
735743

736744
/* Build shl */
737-
LLVM_BUILD_OP(Shl, left, right, res, "shl", NULL);
745+
LLVMTypeRef param_types[2];
746+
param_types[1] = param_types[0] = is_i32 ? I32_TYPE : I64_TYPE;
747+
748+
LLVM_BUILD_OP_OR_INTRINSIC(Shl, left, right, res,
749+
is_i32 ? "i32.shl" : "i64.shl", "shl", false);
738750

739751
return res;
740752
}
741753

742754
static LLVMValueRef
743-
compile_int_shr_s(AOTCompContext *comp_ctx, LLVMValueRef left,
744-
LLVMValueRef right, bool is_i32)
755+
compile_int_shr_s(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
756+
LLVMValueRef left, LLVMValueRef right, bool is_i32)
745757
{
746758
LLVMValueRef res;
747759

748760
SHIFT_COUNT_MASK;
749761

750762
/* Build shl */
751-
LLVM_BUILD_OP(AShr, left, right, res, "shr_s", NULL);
763+
LLVMTypeRef param_types[2];
764+
param_types[1] = param_types[0] = is_i32 ? I32_TYPE : I64_TYPE;
765+
766+
LLVM_BUILD_OP_OR_INTRINSIC(AShr, left, right, res,
767+
is_i32 ? "i32.shr_s" : "i64.shr_s", "shr_s",
768+
false);
752769

753770
return res;
754771
}
755772

756773
static LLVMValueRef
757-
compile_int_shr_u(AOTCompContext *comp_ctx, LLVMValueRef left,
758-
LLVMValueRef right, bool is_i32)
774+
compile_int_shr_u(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
775+
LLVMValueRef left, LLVMValueRef right, bool is_i32)
759776
{
760777
LLVMValueRef res;
761778

762779
SHIFT_COUNT_MASK;
763780

764781
/* Build shl */
765-
LLVM_BUILD_OP(LShr, left, right, res, "shr_u", NULL);
782+
LLVMTypeRef param_types[2];
783+
param_types[1] = param_types[0] = is_i32 ? I32_TYPE : I64_TYPE;
784+
785+
LLVM_BUILD_OP_OR_INTRINSIC(LShr, left, right, res,
786+
is_i32 ? "i32.shr_u" : "i64.shr_u", "shr_u",
787+
false);
766788

767789
return res;
768790
}
@@ -814,16 +836,18 @@ compile_op_int_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
814836
{
815837
switch (shift_op) {
816838
case INT_SHL:
817-
DEF_INT_BINARY_OP(compile_int_shl(comp_ctx, left, right, is_i32),
818-
NULL);
839+
DEF_INT_BINARY_OP(
840+
compile_int_shl(comp_ctx, func_ctx, left, right, is_i32), NULL);
819841
return true;
820842
case INT_SHR_S:
821-
DEF_INT_BINARY_OP(compile_int_shr_s(comp_ctx, left, right, is_i32),
822-
NULL);
843+
DEF_INT_BINARY_OP(
844+
compile_int_shr_s(comp_ctx, func_ctx, left, right, is_i32),
845+
NULL);
823846
return true;
824847
case INT_SHR_U:
825-
DEF_INT_BINARY_OP(compile_int_shr_u(comp_ctx, left, right, is_i32),
826-
NULL);
848+
DEF_INT_BINARY_OP(
849+
compile_int_shr_u(comp_ctx, func_ctx, left, right, is_i32),
850+
NULL);
827851
return true;
828852
case INT_ROTL:
829853
DEF_INT_BINARY_OP(

0 commit comments

Comments
 (0)