From 9694ad78906dfa7103023dfed173cb8a791f8e63 Mon Sep 17 00:00:00 2001 From: "liang.he" Date: Wed, 1 Jun 2022 11:18:22 +0800 Subject: [PATCH] Implement inn.extend8_s, inn.extend16_s, i64.extend32_s (#1199) --- .../fast-jit/cg/x86-64/jit_codegen_x86_64.cpp | 224 +++++++++++++++++- core/iwasm/fast-jit/fe/jit_emit_conversion.c | 70 +++++- core/iwasm/fast-jit/jit_ir.def | 6 + 3 files changed, 293 insertions(+), 7 deletions(-) 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 0abdcef00..3db6a0918 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 @@ -1207,6 +1207,126 @@ mov_r_to_r_f64(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) /* Let compiler do the conversation job as much as possible */ +/** + * Encoding convert int8 immediate data to int32 register + * + * @param a the assembler to emit the code + * @param reg_no the dst register, need to be converted to int32 + * @param data the src int8 immediate data + * + * @return true if success, false otherwise + */ +static bool +convert_imm_i8_to_r_i32(x86::Assembler &a, int32 reg_no, int8 data) +{ + return mov_imm_to_r_i32(a, reg_no, (int32)data); +} + +/** + * encoding convert int8 register to int32 register + * + * @param a the assembler to emit the code + * @param reg_no_dst the dst register + * @param reg_no_src the src register + * + * @return true if success, false otherwise + */ +static bool +convert_r_i8_to_r_i32(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) +{ + return extend_r8_to_r32(a, reg_no_dst, reg_no_src, true); +} + +/** + * encoding convert int8 immediate data to int64 register + * + * @param a the assembler to emit the code + * @param reg_no the dst register, need to be converted to int64 + * @param data the src int8 immediate data + * + * @return true if success, false otherwise + */ +static bool +convert_imm_i8_to_r_i64(x86::Assembler &a, int32 reg_no, int8 data) +{ + return mov_imm_to_r_i64(a, reg_no, (int64)data); +} + +/** + * encoding convert int8 register to int64 register + * + * @param a the assembler to emit the code + * @param reg_no_dst the dst register + * @param reg_no_src the src register + * + * @return true if success, false otherwise + */ +static bool +convert_r_i8_to_r_i64(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) +{ + return extend_r8_to_r64(a, reg_no_dst, reg_no_src, true); +} + +/** + * Encoding convert int16 immediate data to int32 register + * + * @param a the assembler to emit the code + * @param reg_no the dst register, need to be converted to int32 + * @param data the src int16 immediate data + * + * @return true if success, false otherwise + */ +static bool +convert_imm_i16_to_r_i32(x86::Assembler &a, int32 reg_no, int16 data) +{ + return mov_imm_to_r_i32(a, reg_no, (int32)data); +} + +/** + * encoding convert int16 register to int32 register + * + * @param a the assembler to emit the code + * @param reg_no_dst the dst register + * @param reg_no_src the src register + * + * @return true if success, false otherwise + */ +static bool +convert_r_i16_to_r_i32(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) +{ + return extend_r16_to_r32(a, reg_no_dst, reg_no_src, true); +} + +/** + * encoding convert int16 immediate data to int64 register + * + * @param a the assembler to emit the code + * @param reg_no the dst register, need to be converted to int64 + * @param data the src int16 immediate data + * + * @return true if success, false otherwise + */ +static bool +convert_imm_i16_to_r_i64(x86::Assembler &a, int32 reg_no, int16 data) +{ + return mov_imm_to_r_i64(a, reg_no, (int64)data); +} + +/** + * encoding convert int16 register to int64 register + * + * @param a the assembler to emit the code + * @param reg_no_dst the dst register + * @param reg_no_src the src register + * + * @return true if success, false otherwise + */ +static bool +convert_r_i16_to_r_i64(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) +{ + return extend_r16_to_r64(a, reg_no_dst, reg_no_src, true); +} + /** * Encoding convert int32 immediate data to int8 register * @@ -1441,7 +1561,7 @@ convert_imm_i32_to_r_f64(x86::Assembler &a, int32 reg_no, int32 data) static bool convert_imm_i64_to_r_i32(x86::Assembler &a, int32 reg_no, int64 data) { - return mov_imm_to_r_i32(a, reg_no, (int32)data); + return mov_imm_to_r_i64(a, reg_no, (int32)data); } /** @@ -1461,6 +1581,70 @@ convert_r_i64_to_r_i32(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) return true; } +/** + * Encode converting int64 immediate data to int8 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_i8(x86::Assembler &a, int32 reg_no, int64 data) +{ + return mov_imm_to_r_i64(a, reg_no, (int8)data); +} + +/** + * Encode converting int64 register data to int8 register data + * + * @param a the assembler to emit the code + * @param reg_no_dst the no of dst int8 register + * @param reg_no_src the no of src int64 register + * + * @return true if success, false otherwise + */ +static bool +convert_r_i64_to_r_i8(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) +{ + mov_r_to_r_i64(a, reg_no_dst, reg_no_src); + a.and_(regs_i64[reg_no_dst], 0x00000000000000FFLL); + return true; +} + +/** + * Encode converting int64 immediate data to int16 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_i16(x86::Assembler &a, int32 reg_no, int64 data) +{ + return mov_imm_to_r_i64(a, reg_no, (int16)data); +} + +/** + * Encode converting int64 register data to int16 register data + * + * @param a the assembler to emit the code + * @param reg_no_dst the no of dst int16 register + * @param reg_no_src the no of src int64 register + * + * @return true if success, false otherwise + */ +static bool +convert_r_i64_to_r_i16(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) +{ + mov_r_to_r_i64(a, reg_no_dst, reg_no_src); + a.and_(regs_i64[reg_no_dst], 0x000000000000FFFFLL); + return true; +} + /** * Encode converting uint32 immediate data to int64 register data * @@ -5623,6 +5807,26 @@ jit_codegen_gen_native(JitCompContext *cc) GOTO_FAIL; break; + case JIT_OP_I8TOI32: + LOAD_2ARGS(); + CONVERT_R_R(I32, I32, i32, i8, int8); + break; + + case JIT_OP_I8TOI64: + LOAD_2ARGS(); + CONVERT_R_R(I64, I64, i64, i8, int8); + break; + + case JIT_OP_I16TOI32: + LOAD_2ARGS(); + CONVERT_R_R(I32, I32, i32, i16, int16); + break; + + case JIT_OP_I16TOI64: + LOAD_2ARGS(); + CONVERT_R_R(I64, I64, i64, i16, int16); + break; + case JIT_OP_I32TOI8: LOAD_2ARGS(); CONVERT_R_R(I32, I32, i8, i32, int32); @@ -5670,7 +5874,17 @@ jit_codegen_gen_native(JitCompContext *cc) case JIT_OP_U32TOF64: LOAD_2ARGS(); - CONVERT_R_R(F64, I32, f64, u32, int32); + CONVERT_R_R(F64, I32, f64, u32, uint32); + break; + + case JIT_OP_I64TOI8: + LOAD_2ARGS(); + CONVERT_R_R(I64, I64, i8, i64, int64); + break; + + case JIT_OP_I64TOI16: + LOAD_2ARGS(); + CONVERT_R_R(I64, I64, i16, i64, int64); break; case JIT_OP_I64TOI32: @@ -5690,12 +5904,12 @@ jit_codegen_gen_native(JitCompContext *cc) case JIT_OP_F32TOI32: LOAD_2ARGS(); - CONVERT_R_R(I32, F32, i32, f32, int32); + CONVERT_R_R(I32, F32, i32, f32, float32); break; case JIT_OP_F32TOI64: LOAD_2ARGS(); - CONVERT_R_R(I64, F32, i64, f32, int32); + CONVERT_R_R(I64, F32, i64, f32, float32); break; case JIT_OP_F32TOF64: @@ -5705,7 +5919,7 @@ jit_codegen_gen_native(JitCompContext *cc) case JIT_OP_F32TOU32: LOAD_2ARGS(); - CONVERT_R_R(I32, F32, u32, f32, int32); + CONVERT_R_R(I32, F32, u32, f32, float32); break; case JIT_OP_F64TOI32: diff --git a/core/iwasm/fast-jit/fe/jit_emit_conversion.c b/core/iwasm/fast-jit/fe/jit_emit_conversion.c index ad4eb81ab..310af334f 100644 --- a/core/iwasm/fast-jit/fe/jit_emit_conversion.c +++ b/core/iwasm/fast-jit/fe/jit_emit_conversion.c @@ -206,14 +206,80 @@ fail: bool jit_compile_op_i64_extend_i64(JitCompContext *cc, int8 bitwidth) { - bh_assert(0); + JitReg value, tmp, res; + + POP_I64(value); + + tmp = jit_cc_new_reg_I64(cc); + res = jit_cc_new_reg_I64(cc); + + switch (bitwidth) { + case 8: + { + GEN_INSN(I64TOI8, tmp, value); + GEN_INSN(I8TOI64, res, tmp); + break; + } + case 16: + { + GEN_INSN(I64TOI16, tmp, value); + GEN_INSN(I16TOI64, res, tmp); + break; + } + case 32: + { + GEN_INSN(I64TOI32, tmp, value); + GEN_INSN(I32TOI64, res, tmp); + break; + } + default: + { + bh_assert(0); + goto fail; + } + } + + PUSH_I64(res); + + return true; +fail: return false; } bool jit_compile_op_i32_extend_i32(JitCompContext *cc, int8 bitwidth) { - bh_assert(0); + JitReg value, tmp, res; + + POP_I32(value); + + tmp = jit_cc_new_reg_I32(cc); + res = jit_cc_new_reg_I32(cc); + + switch (bitwidth) { + case 8: + { + GEN_INSN(I32TOI8, tmp, value); + GEN_INSN(I8TOI32, res, tmp); + break; + } + case 16: + { + GEN_INSN(I32TOI16, tmp, value); + GEN_INSN(I16TOI32, res, tmp); + break; + } + default: + { + bh_assert(0); + goto fail; + } + } + + PUSH_I32(res); + + return true; +fail: return false; } diff --git a/core/iwasm/fast-jit/jit_ir.def b/core/iwasm/fast-jit/jit_ir.def index 4bde69fc2..dbe297588 100644 --- a/core/iwasm/fast-jit/jit_ir.def +++ b/core/iwasm/fast-jit/jit_ir.def @@ -78,6 +78,10 @@ INSN(MOV, Reg, 2, 1) INSN(PHI, VReg, 1, 1) /* conversion. will extend or truncate */ +INSN(I8TOI32, Reg, 2, 1) +INSN(I8TOI64, Reg, 2, 1) +INSN(I16TOI32, Reg, 2, 1) +INSN(I16TOI64, Reg, 2, 1) INSN(I32TOI8, Reg, 2, 1) INSN(I32TOU8, Reg, 2, 1) INSN(I32TOI16, Reg, 2, 1) @@ -88,6 +92,8 @@ INSN(I32TOF64, Reg, 2, 1) INSN(U32TOI64, Reg, 2, 1) INSN(U32TOF32, Reg, 2, 1) INSN(U32TOF64, Reg, 2, 1) +INSN(I64TOI8, Reg, 2, 1) +INSN(I64TOI16, Reg, 2, 1) INSN(I64TOI32, Reg, 2, 1) INSN(I64TOF32, Reg, 2, 1) INSN(I64TOF64, Reg, 2, 1)