This commit adds qemu_ld and qemu_st by calling the helper functions
corresponding to MemOp.
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
---
tcg/wasm/tcg-target.c.inc | 95 +++++++++++++++++++++++++++++++++++++++
1 file changed, 95 insertions(+)
diff --git a/tcg/wasm/tcg-target.c.inc b/tcg/wasm/tcg-target.c.inc
index d7d4fd4e58..db92463941 100644
--- a/tcg/wasm/tcg-target.c.inc
+++ b/tcg/wasm/tcg-target.c.inc
@@ -1155,6 +1155,99 @@ static void tcg_wasm_out_call(TCGContext *s, intptr_t func,
gen_call(s, info, func_idx);
}
+static void *qemu_ld_helper_ptr(uint32_t oi)
+{
+ MemOp mop = get_memop(oi);
+ switch (mop & MO_SSIZE) {
+ case MO_UB:
+ return helper_ldub_mmu;
+ case MO_SB:
+ return helper_ldsb_mmu;
+ case MO_UW:
+ return helper_lduw_mmu;
+ case MO_SW:
+ return helper_ldsw_mmu;
+ case MO_UL:
+ return helper_ldul_mmu;
+ case MO_SL:
+ return helper_ldsl_mmu;
+ case MO_UQ:
+ return helper_ldq_mmu;
+ default:
+ g_assert_not_reached();
+ }
+}
+
+static void tcg_wasm_out_qemu_ld(TCGContext *s, TCGReg data_reg,
+ TCGReg addr_reg, MemOpIdx oi)
+{
+ intptr_t helper_idx;
+ int64_t func_idx;
+
+ helper_idx = (intptr_t)qemu_ld_helper_ptr(oi);
+ func_idx = get_helper_idx(s, helper_idx);
+ if (func_idx < 0) {
+ func_idx = register_helper(s, helper_idx);
+ }
+
+ /* call the target helper */
+ tcg_wasm_out_op_idx(s, OPC_GLOBAL_GET, REG_IDX(TCG_AREG0));
+ tcg_wasm_out_op_idx(s, OPC_GLOBAL_GET, REG_IDX(addr_reg));
+ tcg_wasm_out_op_const(s, OPC_I32_CONST, oi);
+ tcg_wasm_out_op_const(s, OPC_I64_CONST, (intptr_t)s->code_ptr);
+
+ tcg_wasm_out_op_idx(s, OPC_CALL, func_idx);
+ tcg_wasm_out_op_idx(s, OPC_GLOBAL_SET, REG_IDX(data_reg));
+}
+
+static void *qemu_st_helper_ptr(uint32_t oi)
+{
+ MemOp mop = get_memop(oi);
+ switch (mop & MO_SIZE) {
+ case MO_8:
+ return helper_stb_mmu;
+ case MO_16:
+ return helper_stw_mmu;
+ case MO_32:
+ return helper_stl_mmu;
+ case MO_64:
+ return helper_stq_mmu;
+ default:
+ g_assert_not_reached();
+ }
+}
+
+static void tcg_wasm_out_qemu_st(TCGContext *s, TCGReg data_reg,
+ TCGReg addr_reg, MemOpIdx oi)
+{
+ intptr_t helper_idx;
+ int64_t func_idx;
+ MemOp mop = get_memop(oi);
+
+ helper_idx = (intptr_t)qemu_st_helper_ptr(oi);
+ func_idx = get_helper_idx(s, helper_idx);
+ if (func_idx < 0) {
+ func_idx = register_helper(s, helper_idx);
+ }
+
+ /* call the target helper */
+ tcg_wasm_out_op_idx(s, OPC_GLOBAL_GET, REG_IDX(TCG_AREG0));
+ tcg_wasm_out_op_idx(s, OPC_GLOBAL_GET, REG_IDX(addr_reg));
+ switch (mop & MO_SSIZE) {
+ case MO_UQ:
+ tcg_wasm_out_op_idx(s, OPC_GLOBAL_GET, REG_IDX(data_reg));
+ break;
+ default:
+ tcg_wasm_out_op_idx(s, OPC_GLOBAL_GET, REG_IDX(data_reg));
+ tcg_wasm_out_op(s, OPC_I32_WRAP_I64);
+ break;
+ }
+ tcg_wasm_out_op_const(s, OPC_I32_CONST, oi);
+ tcg_wasm_out_op_const(s, OPC_I64_CONST, (intptr_t)s->code_ptr);
+
+ tcg_wasm_out_op_idx(s, OPC_CALL, func_idx);
+}
+
static bool patch_reloc(tcg_insn_unit *code_ptr_i, int type,
intptr_t value, intptr_t addend)
{
@@ -2319,6 +2412,7 @@ static void tgen_qemu_ld(TCGContext *s, TCGType type, TCGReg data,
TCGReg addr, MemOpIdx oi)
{
tcg_out_op_rrm(s, INDEX_op_qemu_ld, data, addr, oi);
+ tcg_wasm_out_qemu_ld(s, data, addr, oi);
}
static const TCGOutOpQemuLdSt outop_qemu_ld = {
@@ -2334,6 +2428,7 @@ static void tgen_qemu_st(TCGContext *s, TCGType type, TCGReg data,
TCGReg addr, MemOpIdx oi)
{
tcg_out_op_rrm(s, INDEX_op_qemu_st, data, addr, oi);
+ tcg_wasm_out_qemu_st(s, data, addr, oi);
}
static const TCGOutOpQemuLdSt outop_qemu_st = {
--
2.43.0