The sextract operation is genereted only when the corresponding Wasm instructions are available, as specified by TCG_TARGET_sextract_valid.
Signed-off-by: Kohei Tokunaga <ktokunaga.m...@gmail.com> --- tcg/wasm/tcg-target-has.h | 5 +++++ tcg/wasm/tcg-target.c.inc | 42 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) V2: - This commit generates both Wasm and TCI instrucitons. - Removed the extract and deposit oprations to use default expansion. - Updated the sextract to emit only when the corresponding Wasm instruction is available diff --git a/tcg/wasm/tcg-target-has.h b/tcg/wasm/tcg-target-has.h index 7e3caf8790..cfb85388de 100644 --- a/tcg/wasm/tcg-target-has.h +++ b/tcg/wasm/tcg-target-has.h @@ -4,4 +4,9 @@ #define TCG_TARGET_HAS_tst 0 +#define TCG_TARGET_extract_valid(type, ofs, len) 0 +#define TCG_TARGET_sextract_valid(type, ofs, len) \ + ((ofs == 0) && ((len == 8) || (len == 16) || (len == 32))) +#define TCG_TARGET_deposit_valid(type, ofs, len) 0 + #endif diff --git a/tcg/wasm/tcg-target.c.inc b/tcg/wasm/tcg-target.c.inc index 70de3bbf83..dd75deecd3 100644 --- a/tcg/wasm/tcg-target.c.inc +++ b/tcg/wasm/tcg-target.c.inc @@ -182,7 +182,10 @@ typedef enum { OPC_I64_SHR_U = 0x88, OPC_I32_WRAP_I64 = 0xa7, + OPC_I64_EXTEND_I32_S = 0xac, OPC_I64_EXTEND_I32_U = 0xad, + OPC_I64_EXTEND8_S = 0xc2, + OPC_I64_EXTEND16_S = 0xc3, } WasmInsn; typedef enum { @@ -391,6 +394,33 @@ static void tcg_wasm_out_movcond(TCGContext *s, TCGType type, TCGReg ret, tcg_wasm_out_op_idx(s, OPC_GLOBAL_SET, REG_IDX(ret)); } +static void tcg_wasm_out_sextract(TCGContext *s, TCGReg dest, TCGReg arg1, + int pos, int len) +{ + tcg_wasm_out_op_idx(s, OPC_GLOBAL_GET, REG_IDX(arg1)); + + if (pos == 0) { + switch (len) { + case 8: + tcg_wasm_out_op(s, OPC_I64_EXTEND8_S); + break; + case 16: + tcg_wasm_out_op(s, OPC_I64_EXTEND16_S); + break; + case 32: + tcg_wasm_out_op(s, OPC_I32_WRAP_I64); + tcg_wasm_out_op(s, OPC_I64_EXTEND_I32_S); + break; + default: + g_assert_not_reached(); + } + } else { + g_assert_not_reached(); + } + + tcg_wasm_out_op_idx(s, OPC_GLOBAL_SET, REG_IDX(dest)); +} + static void tcg_out_op_rr(TCGContext *s, TCGOpcode op, TCGReg r0, TCGReg r1) { tcg_insn_unit_tci insn = 0; @@ -529,6 +559,18 @@ static const TCGOutOpBinary outop_mul = { .out_rrr = tgen_mul, }; +static void tcg_out_sextract(TCGContext *s, TCGType type, TCGReg rd, + TCGReg rs, unsigned pos, unsigned len) +{ + tcg_out_op_rrbb(s, INDEX_op_sextract, rd, rs, pos, len); + tcg_wasm_out_sextract(s, rd, rs, pos, len); +} + +static const TCGOutOpExtract outop_sextract = { + .base.static_constraint = C_O1_I1(r, r), + .out_rr = tcg_out_sextract, +}; + static void tgen_shl(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1, TCGReg a2) { -- 2.43.0