This commit implements mov/movi instructions. The tcg_out_mov[i] functions
are used by several other functions and are intended to emit TCI code. So
they have been renamed to tcg_tci_out_mov[i].
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
---
tcg/wasm32/tcg-target.c.inc | 85 ++++++++++++++++++++++++++-----------
1 file changed, 60 insertions(+), 25 deletions(-)
diff --git a/tcg/wasm32/tcg-target.c.inc b/tcg/wasm32/tcg-target.c.inc
index 9b024b03b9..90a5705442 100644
--- a/tcg/wasm32/tcg-target.c.inc
+++ b/tcg/wasm32/tcg-target.c.inc
@@ -779,6 +779,28 @@ static void tcg_wasm_out_st16(TCGContext *s, TCGReg val,
tcg_wasm_out_op_i64_store16(s, 0, offset);
}
+static void tcg_wasm_out_mov(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+ tcg_wasm_out_op_global_get_r(s, arg);
+ tcg_wasm_out_op_global_set_r(s, ret);
+}
+
+static void tcg_wasm_out_movi(TCGContext *s, TCGType type,
+ TCGReg ret, tcg_target_long arg)
+{
+ switch (type) {
+ case TCG_TYPE_I32:
+ tcg_wasm_out_op_i64_const(s, (int32_t)arg);
+ break;
+ case TCG_TYPE_I64:
+ tcg_wasm_out_op_i64_const(s, arg);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ tcg_wasm_out_op_global_set_r(s, ret);
+}
+
static bool patch_reloc(tcg_insn_unit *code_ptr_i, int type,
intptr_t value, intptr_t addend)
{
@@ -990,6 +1012,33 @@ static void tcg_out_op_rrrrrc(TCGContext *s, TCGOpcode op,
tcg_out32(s, insn);
}
+static void tcg_tci_out_movi(TCGContext *s, TCGType type,
+ TCGReg ret, tcg_target_long arg)
+{
+ switch (type) {
+ case TCG_TYPE_I32:
+#if TCG_TARGET_REG_BITS == 64
+ arg = (int32_t)arg;
+ /* fall through */
+ case TCG_TYPE_I64:
+#endif
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ if (arg == sextract32(arg, 0, 20)) {
+ tcg_out_op_ri(s, INDEX_op_tci_movi, ret, arg);
+ } else {
+ tcg_insn_unit_tci insn = 0;
+
+ new_pool_label(s, arg, 20, s->code_ptr, 0);
+ insn = deposit32(insn, 0, 8, INDEX_op_tci_movl);
+ insn = deposit32(insn, 8, 4, ret);
+ tcg_out32(s, insn);
+ }
+}
+
static void tcg_tci_out_extract(TCGContext *s, TCGType type, TCGReg rd,
TCGReg rs, unsigned pos, unsigned len)
{
@@ -1001,7 +1050,7 @@ static void tcg_out_ldst(TCGContext *s, TCGOpcode op, TCGReg val,
{
stack_bounds_check(base, offset);
if (offset != sextract32(offset, 0, 16)) {
- tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP, offset);
+ tcg_tci_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP, offset);
tcg_out_op_rrr(s, INDEX_op_add, TCG_REG_TMP, TCG_REG_TMP, base);
base = TCG_REG_TMP;
offset = 0;
@@ -1021,37 +1070,23 @@ static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg val, TCGReg base,
tcg_wasm_out_ld(s, type, val, base, offset);
}
-static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
+static void tcg_tci_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
{
tcg_out_op_rr(s, INDEX_op_mov, ret, arg);
+}
+
+static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
+{
+ tcg_tci_out_mov(s, type, ret, arg);
+ tcg_wasm_out_mov(s, ret, arg);
return true;
}
static void tcg_out_movi(TCGContext *s, TCGType type,
TCGReg ret, tcg_target_long arg)
{
- switch (type) {
- case TCG_TYPE_I32:
-#if TCG_TARGET_REG_BITS == 64
- arg = (int32_t)arg;
- /* fall through */
- case TCG_TYPE_I64:
-#endif
- break;
- default:
- g_assert_not_reached();
- }
-
- if (arg == sextract32(arg, 0, 20)) {
- tcg_out_op_ri(s, INDEX_op_tci_movi, ret, arg);
- } else {
- tcg_insn_unit insn = 0;
-
- new_pool_label(s, arg, 20, s->code_ptr, 0);
- insn = deposit32(insn, 0, 8, INDEX_op_tci_movl);
- insn = deposit32(insn, 8, 4, ret);
- tcg_out32(s, insn);
- }
+ tcg_tci_out_movi(s, type, ret, arg);
+ tcg_wasm_out_movi(s, type, ret, arg);
}
static void tcg_out_extract(TCGContext *s, TCGType type, TCGReg rd,
@@ -1133,7 +1168,7 @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rs)
{
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
- tcg_out_mov(s, TCG_TYPE_I32, rd, rs);
+ tcg_tci_out_mov(s, TCG_TYPE_I32, rd, rs);
}
static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2)
--
2.43.0