diff --git a/core/iwasm/fast-jit/cg/x86-64/jit_codegen_x86_64.cpp b/core/iwasm/fast-jit/cg/x86-64/jit_codegen_x86_64.cpp index 2ced20052..21cf19e75 100644 --- a/core/iwasm/fast-jit/cg/x86-64/jit_codegen_x86_64.cpp +++ b/core/iwasm/fast-jit/cg/x86-64/jit_codegen_x86_64.cpp @@ -426,7 +426,13 @@ static bool extend_r8_to_r32(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src, bool is_signed) { - return false; + if (is_signed) { + a.movsx(regs_i32[reg_no_dst], regs_i8[reg_no_src]); + } + else { + a.movzx(regs_i32[reg_no_dst], regs_i8[reg_no_src]); + } + return true; } /** * Encode extending register of word to register of dword @@ -441,7 +447,13 @@ static bool extend_r16_to_r32(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src, bool is_signed) { - return false; + if (is_signed) { + a.movsx(regs_i32[reg_no_dst], regs_i16[reg_no_src]); + } + else { + a.movzx(regs_i32[reg_no_dst], regs_i16[reg_no_src]); + } + return true; } /** @@ -457,7 +469,13 @@ static bool extend_r8_to_r64(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src, bool is_signed) { - return false; + if (is_signed) { + a.movsx(regs_i64[reg_no_dst], regs_i8[reg_no_src]); + } + else { + a.movzx(regs_i64[reg_no_dst], regs_i8[reg_no_src]); + } + return true; } /** @@ -473,7 +491,13 @@ static bool extend_r16_to_r64(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src, bool is_signed) { - return false; + if (is_signed) { + a.movsx(regs_i64[reg_no_dst], regs_i16[reg_no_src]); + } + else { + a.movzx(regs_i64[reg_no_dst], regs_i16[reg_no_src]); + } + return true; } /** @@ -489,29 +513,40 @@ static bool extend_r32_to_r64(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src, bool is_signed) { - return false; + if (is_signed) { + a.movsxd(regs_i64[reg_no_dst], regs_i32[reg_no_src]); + } + else { + a.xor_(regs_i64[reg_no_dst], regs_i64[reg_no_dst]); + a.mov(regs_i32[reg_no_dst], regs_i32[reg_no_src]); + } + return true; } +static bool +mov_r_to_r_i32(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src); + +static bool +mov_r_to_r_i64(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src); + static void mov_r_to_r(x86::Assembler &a, uint32 kind_dst, int32 reg_no_dst, int32 reg_no_src) { - if (reg_no_dst != reg_no_src) { - if (kind_dst == JIT_REG_KIND_I32) - a.mov(regs_i32[reg_no_dst], regs_i32[reg_no_src]); - else if (kind_dst == JIT_REG_KIND_I64) - a.mov(regs_i64[reg_no_dst], regs_i64[reg_no_src]); - else if (kind_dst == JIT_REG_KIND_F32) { - /* TODO */ - bh_assert(0); - } - else if (kind_dst == JIT_REG_KIND_F64) { - /* TODO */ - bh_assert(0); - } - else { - bh_assert(0); - } + if (kind_dst == JIT_REG_KIND_I32) + mov_r_to_r_i32(a, reg_no_dst, reg_no_src); + else if (kind_dst == JIT_REG_KIND_I64) + mov_r_to_r_i64(a, reg_no_dst, reg_no_src); + else if (kind_dst == JIT_REG_KIND_F32) { + /* TODO */ + bh_assert(0); + } + else if (kind_dst == JIT_REG_KIND_F64) { + /* TODO */ + bh_assert(0); + } + else { + bh_assert(0); } } @@ -1109,7 +1144,9 @@ mov_r_to_r_f64(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) static bool convert_imm_i32_to_r_i8(x86::Assembler &a, int32 reg_no, int32 data) { - return false; + Imm imm((int8)data); + a.mov(regs_i32[reg_no], imm); + return true; } /** @@ -1124,6 +1161,8 @@ convert_imm_i32_to_r_i8(x86::Assembler &a, int32 reg_no, int32 data) static bool convert_r_i32_to_r_i8(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) { + /* TODO */ + bh_assert(0); return false; } @@ -1139,7 +1178,9 @@ convert_r_i32_to_r_i8(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) static bool convert_imm_i32_to_r_u8(x86::Assembler &a, int32 reg_no, int32 data) { - return false; + Imm imm((uint8)data); + a.mov(regs_i32[reg_no], imm); + return true; } /** @@ -1154,6 +1195,8 @@ convert_imm_i32_to_r_u8(x86::Assembler &a, int32 reg_no, int32 data) static bool convert_r_i32_to_r_u8(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) { + /* TODO */ + bh_assert(0); return false; } @@ -1169,7 +1212,9 @@ convert_r_i32_to_r_u8(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) static bool convert_imm_i32_to_r_i16(x86::Assembler &a, int32 reg_no, int32 data) { - return false; + Imm imm((int16)data); + a.mov(regs_i32[reg_no], imm); + return true; } /** @@ -1184,6 +1229,8 @@ convert_imm_i32_to_r_i16(x86::Assembler &a, int32 reg_no, int32 data) static bool convert_r_i32_to_r_i16(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) { + /* TODO */ + bh_assert(0); return false; } @@ -1199,7 +1246,9 @@ convert_r_i32_to_r_i16(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) static bool convert_imm_i32_to_r_u16(x86::Assembler &a, int32 reg_no, int32 data) { - return false; + Imm imm((uint16)data); + a.mov(regs_i32[reg_no], imm); + return true; } /** @@ -1214,11 +1263,13 @@ convert_imm_i32_to_r_u16(x86::Assembler &a, int32 reg_no, int32 data) static bool convert_r_i32_to_r_u16(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) { + /* TODO */ + bh_assert(0); return false; } /** - * Encoding convert int32 immediate data to uint64 register + * Encoding convert int32 immediate data to int64 register * * @param a the assembler to emit the code * @param reg_no the dst register, need to be converted to uint64 @@ -1227,13 +1278,16 @@ convert_r_i32_to_r_u16(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) * @return true if success, false otherwise */ static bool -convert_imm_i32_to_r_u64(x86::Assembler &a, int32 reg_no, int32 data) +convert_imm_i32_to_r_i64(x86::Assembler &a, int32 reg_no, int32 data) { - return false; + /* let compiler do sign-extending */ + Imm imm((int64)data); + a.mov(regs_i64[reg_no], imm); + return true; } /** - * Encoding convert int32 immediate data to uint64 register + * Encoding convert int32 register data to int64 register with signed extension * * @param a the assembler to emit the code * @param reg_no_dst the dst register, need to be converted to uint64 @@ -1242,9 +1296,9 @@ convert_imm_i32_to_r_u64(x86::Assembler &a, int32 reg_no, int32 data) * @return true if success, false otherwise */ static bool -convert_r_i32_to_r_u64(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) +convert_r_i32_to_r_i64(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) { - return false; + return extend_r32_to_r64(a, reg_no_dst, reg_no_src, true); } /** @@ -1307,6 +1361,132 @@ convert_r_i32_to_r_f64(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) return false; } +/** + * Encode converting uint32 immediate data to int64 register data + * + * @param a the assembler to emit the code + * @param reg_no the no of dst int64 register + * @param data the src immediate uint32 data + * + * @return true if success, false otherwise + */ +static bool +convert_imm_u32_to_r_i64(x86::Assembler &a, int32 reg_no, uint32 data) +{ + Imm imm((uint64)data); + a.mov(regs_i64[reg_no], imm); + return true; +} + +/** + * Encode converting uint32 register data to int64 register data + * + * @param a the assembler to emit the code + * @param reg_no_dst the no of dst uint32 register + * @param reg_no_src the no of src int64 register + * + * @return true if success, false otherwise + */ +static bool +convert_r_u32_to_r_i64(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) +{ + return extend_r32_to_r64(a, reg_no_dst, reg_no_src, false); +} + +/** + * Encode converting int64 immediate data to int32 register data + * + * @param a the assembler to emit the code + * @param reg_no the no of dst int32 register + * @param data the src immediate int64 data + * + * @return true if success, false otherwise + */ +static bool +convert_imm_i64_to_r_i32(x86::Assembler &a, int32 reg_no, int64 data) +{ + Imm imm((int32)data); + a.mov(regs_i32[reg_no], imm); + return true; +} + +/** + * Encode converting int64 register data to int32 register data + * + * @param a the assembler to emit the code + * @param reg_no_dst the no of dst int32 register + * @param reg_no_src the no of src int64 register + * + * @return true if success, false otherwise + */ +static bool +convert_r_i64_to_r_i32(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) +{ + /* TODO */ + bh_assert(0); + return false; +} + +/** + * Encode converting int64 immediate data to float register data + * + * @param a the assembler to emit the code + * @param reg_no the no of dst float register + * @param data the src immediate int64 data + * + * @return true if success, false otherwise + */ +static bool +convert_imm_i64_to_r_f32(x86::Assembler &a, int32 reg_no_dst, int64 data) +{ + return false; +} + +/** + * Encode converting int64 register data to float register data + * + * @param a the assembler to emit the code + * @param reg_no_dst the no of dst float register + * @param reg_no_src the no of src int64 register + * + * @return true if success, false otherwise + */ +static bool +convert_r_i64_to_r_f32(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) +{ + return false; +} + +/** + * Encode converting int64 immediate data to double register data + * + * @param a the assembler to emit the code + * @param reg_no the no of dst double register + * @param data the src immediate int64 data + * + * @return true if success, false otherwise + */ +static bool +convert_imm_i64_to_r_f64(x86::Assembler &a, int32 reg_no_dst, int64 data) +{ + return false; +} + +/** + * Encode converting int64 register data to double register data + * + * @param a the assembler to emit the code + * @param reg_no_dst the no of dst double register + * @param reg_no_src the no of src int64 register + * + * @return true if success, false otherwise + */ +static bool +convert_r_i64_to_r_f64(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) +{ + return false; +} + /** * Encode converting float immediate data to int32 register data * @@ -1397,6 +1577,36 @@ convert_r_f64_to_r_i32(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) return false; } +/** + * Encode converting double immediate data to int64 register data + * + * @param a the assembler to emit the code + * @param reg_no the no of dst int64 register + * @param data the src immediate double data + * + * @return true if success, false otherwise + */ +static bool +convert_imm_f64_to_r_i64(x86::Assembler &a, int32 reg_no, double data) +{ + return false; +} + +/** + * Encode converting double register data to int64 register data + * + * @param a the assembler to emit the code + * @param reg_no_dst the no of dst int64 register + * @param reg_no_src the no of src double register + * + * @return true if success, false otherwise + */ +static bool +convert_r_f64_to_r_i64(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) +{ + return false; +} + /** * Encode converting double immediate data to float register data * @@ -3370,10 +3580,12 @@ fail: /** * Encode insn convert: I32TOI8 r0, r1, or I32TOI16, I32TOF32, F32TOF64, etc. - * @param kind0 the dst data kind, such as I32, I64, F32 and F64 - * @param kind1 the src data kind, such as I32, I64, F32 and F64 - * @param type0 the dst data type, such as int32, float and double - * @param type1 the src data type, such as int32, float and double + * @param kind0 the dst JIT_REG_KIND, such as I32, I64, F32 and F64 + * @param kind1 the src JIT_REG_KIND, such as I32, I64, F32 and F64 + * @param type0 the dst data type, such as i8, u8, i16, u16, i32, f32, i64, f32, + * f64 + * @param type1 the src data type, such as i8, u8, i16, u16, i32, f32, i64, f32, + * f64 */ #define CONVERT_R_R(kind0, kind1, type0, type1, Type1) \ do { \ @@ -3670,8 +3882,9 @@ fail: * @param cc the compiler context * @param a the assembler to emit the code * @param r0 dst jit register that contains the dst operand info - * @param r1 src jit register that contains the first src operand info - * @param r2 src jit register that contains the second src operand info + * @param r1 condition jit register + * @param r2 src jit register that contains the first src operand info + * @param r3 src jit register that contains the second src operand info * * @return true if success, false if failed */ @@ -4373,6 +4586,16 @@ jit_codegen_gen_native(JitCompContext *cc) CONVERT_R_R(I32, I32, u16, i32, int32); break; + case JIT_OP_I32TOI64: + LOAD_2ARGS(); + CONVERT_R_R(I64, I32, i64, i32, int32); + break; + + case JIT_OP_U32TOI64: + LOAD_2ARGS(); + CONVERT_R_R(I64, I32, i64, u32, int32); + break; + case JIT_OP_I32TOF32: case JIT_OP_U32TOF32: LOAD_2ARGS(); @@ -4385,6 +4608,21 @@ jit_codegen_gen_native(JitCompContext *cc) CONVERT_R_R(F64, I32, f64, i32, int32); break; + case JIT_OP_I64TOI32: + LOAD_2ARGS(); + CONVERT_R_R(I32, I64, i32, i64, int64); + break; + + case JIT_OP_I64TOF32: + LOAD_2ARGS(); + CONVERT_R_R(F32, I64, f32, i64, int64); + break; + + case JIT_OP_I64TOF64: + LOAD_2ARGS(); + CONVERT_R_R(F64, I64, f64, i64, int64); + break; + case JIT_OP_F32TOI32: LOAD_2ARGS(); CONVERT_R_R(I32, F32, i32, f32, int32); @@ -4400,6 +4638,11 @@ jit_codegen_gen_native(JitCompContext *cc) CONVERT_R_R(I32, F64, i32, f64, float64); break; + case JIT_OP_F64TOI64: + LOAD_2ARGS(); + CONVERT_R_R(I64, F64, i64, f64, float64); + break; + case JIT_OP_F64TOF32: LOAD_2ARGS(); CONVERT_R_R(F32, F64, f32, f64, float64); diff --git a/core/iwasm/fast-jit/fe/jit_emit_memory.c b/core/iwasm/fast-jit/fe/jit_emit_memory.c index 34ce25cc5..a15caa9bb 100644 --- a/core/iwasm/fast-jit/fe/jit_emit_memory.c +++ b/core/iwasm/fast-jit/fe/jit_emit_memory.c @@ -5,11 +5,219 @@ #include "jit_emit_memory.h" #include "../jit_frontend.h" +#include "fe/jit_emit_exception.h" + +static JitReg +get_memory_boundary(JitCompContext *cc, uint32 mem_idx, uint32 bytes) +{ + JitReg memory_boundary; + + switch (bytes) { + case 1: + { + memory_boundary = + get_mem_bound_check_1byte_reg(cc->jit_frame, mem_idx); + break; + } + case 2: + { + memory_boundary = + get_mem_bound_check_2bytes_reg(cc->jit_frame, mem_idx); + break; + } + case 4: + { + memory_boundary = + get_mem_bound_check_4bytes_reg(cc->jit_frame, mem_idx); + break; + } + case 8: + { + memory_boundary = + get_mem_bound_check_8bytes_reg(cc->jit_frame, mem_idx); + break; + } + case 16: + { + memory_boundary = + get_mem_bound_check_16bytes_reg(cc->jit_frame, mem_idx); + break; + } + default: + { + bh_assert(0); + goto fail; + } + } + + return memory_boundary; +fail: + return 0; +} + +#if UINTPTR_MAX == UINT64_MAX +static JitReg +check_and_seek_on_64bit_platform(JitCompContext *cc, JitReg addr, JitReg offset, + JitReg memory_boundary) +{ + JitReg long_addr, offset1; + + /* long_addr = (int64_t)addr */ + long_addr = jit_cc_new_reg_I64(cc); + GEN_INSN(U32TOI64, long_addr, addr); + + /* offset1 = offset + long_addr */ + offset1 = jit_cc_new_reg_I64(cc); + GEN_INSN(ADD, offset1, offset, long_addr); + + /* if (offset1 > memory_boundary) goto EXCEPTION */ + GEN_INSN(CMP, cc->cmp_reg, offset1, memory_boundary); + if (!jit_emit_exception(cc, EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, JIT_OP_BGTU, + cc->cmp_reg, NULL)) { + goto fail; + } + + return offset1; +fail: + return 0; +} +#else +static JitReg +check_and_seek_on_32bit_platform(JitCompContext *cc, JitReg addr, JitReg offset, + JitReg memory_boundary) +{ + JitReg offset1; + + /* offset1 = offset + addr */ + offset1 = jit_cc_new_reg_I32(cc); + GEN_INSN(ADD, offset1, offset, addr); + + /* if (offset1 < addr) goto EXCEPTION */ + GEN_INSN(CMP, cc->cmp_reg, offset1, addr); + if (!jit_emit_exception(cc, EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, JIT_OP_BLTU, + cc->cmp_reg, NULL)) { + goto fail; + } + + /* if (offset1 > memory_boundary) goto EXCEPTION */ + GEN_INSN(CMP, cc->cmp_reg, offset1, memory_boundary); + if (!jit_emit_exception(cc, EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, JIT_OP_BGTU, + cc->cmp_reg, NULL)) { + goto fail; + } + + return offset1; +fail: + return 0; +} +#endif + +static JitReg +check_and_seek(JitCompContext *cc, JitReg addr, uint32 offset, uint32 bytes) +{ + JitReg memory_boundary, offset1, memory_data, maddr; + /* the default memory */ + uint32 mem_idx = 0; + + /* ---------- check ---------- */ + /* 1. shortcut if the memory size is 0*/ + if (0 == cc->cur_wasm_module->memories[mem_idx].init_page_count) { + JitReg memory_inst, cur_mem_page_count; + + /* if (cur_mem_page_count == 0) goto EXCEPTION */ + memory_inst = get_memory_inst_reg(cc->jit_frame, mem_idx); + cur_mem_page_count = jit_cc_new_reg_I32(cc); + GEN_INSN(LDI32, cur_mem_page_count, memory_inst, + NEW_CONST(I32, offsetof(WASMMemoryInstance, cur_page_count))); + GEN_INSN(CMP, cc->cmp_reg, cur_mem_page_count, NEW_CONST(I32, 0)); + if (!jit_emit_exception(cc, EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, + JIT_OP_BEQ, cc->cmp_reg, NULL)) { + goto fail; + } + } + + /* 2. a complete boundary check */ + memory_boundary = get_memory_boundary(cc, mem_idx, bytes); + if (!memory_boundary) + goto fail; + +#if UINTPTR_MAX == UINT64_MAX + offset1 = check_and_seek_on_64bit_platform(cc, addr, NEW_CONST(I64, offset), + memory_boundary); + if (!offset1) + goto fail; +#else + offset1 = check_and_seek_on_32bit_platform(cc, addr, NEW_CONST(I32, offset), + memory_boundary); + if (!offset1) + goto fail; +#endif + + /* ---------- seek ---------- */ + memory_data = get_memory_data_reg(cc->jit_frame, mem_idx); + maddr = jit_cc_new_reg_ptr(cc); + GEN_INSN(ADD, maddr, memory_data, offset1); + + return maddr; +fail: + return 0; +} bool jit_compile_op_i32_load(JitCompContext *cc, uint32 align, uint32 offset, uint32 bytes, bool sign, bool atomic) { + JitReg addr, maddr, value; + + POP_I32(addr); + + maddr = check_and_seek(cc, addr, offset, bytes); + if (!maddr) { + goto fail; + } + + value = jit_cc_new_reg_I32(cc); + switch (bytes) { + case 1: + { + if (sign) { + GEN_INSN(LDI8, value, maddr, NEW_CONST(I32, 0)); + } + else { + GEN_INSN(LDU8, value, maddr, NEW_CONST(I32, 0)); + } + break; + } + case 2: + { + if (sign) { + GEN_INSN(LDI16, value, maddr, NEW_CONST(I32, 0)); + } + else { + GEN_INSN(LDU16, value, maddr, NEW_CONST(I32, 0)); + } + break; + } + case 4: + { + if (sign) { + GEN_INSN(LDI32, value, maddr, NEW_CONST(I32, 0)); + } + else { + GEN_INSN(LDU32, value, maddr, NEW_CONST(I32, 0)); + } + break; + } + default: + { + bh_assert(0); + goto fail; + } + } + + PUSH_I32(value); + return true; +fail: return false; } @@ -17,6 +225,67 @@ bool jit_compile_op_i64_load(JitCompContext *cc, uint32 align, uint32 offset, uint32 bytes, bool sign, bool atomic) { + JitReg addr, maddr, value; + + POP_I32(addr); + + maddr = check_and_seek(cc, addr, offset, bytes); + if (!maddr) { + goto fail; + } + + value = jit_cc_new_reg_I64(cc); + switch (bytes) { + case 1: + { + if (sign) { + GEN_INSN(LDI8, value, maddr, NEW_CONST(I32, 0)); + } + else { + GEN_INSN(LDU8, value, maddr, NEW_CONST(I32, 0)); + } + break; + } + case 2: + { + if (sign) { + GEN_INSN(LDI16, value, maddr, NEW_CONST(I32, 0)); + } + else { + GEN_INSN(LDU16, value, maddr, NEW_CONST(I32, 0)); + } + break; + } + case 4: + { + if (sign) { + GEN_INSN(LDI16, value, maddr, NEW_CONST(I32, 0)); + } + else { + GEN_INSN(LDU16, value, maddr, NEW_CONST(I32, 0)); + } + break; + } + case 8: + { + if (sign) { + GEN_INSN(LDI64, value, maddr, NEW_CONST(I32, 0)); + } + else { + GEN_INSN(LDU64, value, maddr, NEW_CONST(I32, 0)); + } + break; + } + default: + { + bh_assert(0); + goto fail; + } + } + + PUSH_I64(value); + return true; +fail: return false; } @@ -36,6 +305,41 @@ bool jit_compile_op_i32_store(JitCompContext *cc, uint32 align, uint32 offset, uint32 bytes, bool atomic) { + JitReg value, addr, maddr; + + POP_I32(value); + POP_I32(addr); + + maddr = check_and_seek(cc, addr, offset, bytes); + if (!maddr) { + goto fail; + } + + switch (bytes) { + case 1: + { + GEN_INSN(STI8, value, maddr, NEW_CONST(I32, 0)); + break; + } + case 2: + { + GEN_INSN(STI16, value, maddr, NEW_CONST(I32, 0)); + break; + } + case 4: + { + GEN_INSN(STI32, value, maddr, NEW_CONST(I32, 0)); + break; + } + default: + { + bh_assert(0); + goto fail; + } + } + + return true; +fail: return false; } @@ -43,6 +347,46 @@ bool jit_compile_op_i64_store(JitCompContext *cc, uint32 align, uint32 offset, uint32 bytes, bool atomic) { + JitReg value, addr, maddr; + + POP_I64(value); + POP_I32(addr); + + maddr = check_and_seek(cc, addr, offset, bytes); + if (!maddr) { + goto fail; + } + + switch (bytes) { + case 1: + { + GEN_INSN(STI8, value, maddr, NEW_CONST(I32, 0)); + break; + } + case 2: + { + GEN_INSN(STI16, value, maddr, NEW_CONST(I32, 0)); + break; + } + case 4: + { + GEN_INSN(STI32, value, maddr, NEW_CONST(I32, 0)); + break; + } + case 8: + { + GEN_INSN(STI64, value, maddr, NEW_CONST(I32, 0)); + break; + } + default: + { + bh_assert(0); + goto fail; + } + } + + return true; +fail: return false; }