aboutsummaryrefslogtreecommitdiff
path: root/tcg
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2022-11-11 11:01:13 +1000
committerRichard Henderson <richard.henderson@linaro.org>2023-02-04 06:19:42 -1000
commit466d37596010845eb61fbb8b5cd7daa407286342 (patch)
tree67148befe22a519e176f89cb7c7ebeeb68978741 /tcg
parentecbea3ec1ce5f4499ef6acbc696ec5d6a1c69165 (diff)
downloadqemu-466d37596010845eb61fbb8b5cd7daa407286342.zip
qemu-466d37596010845eb61fbb8b5cd7daa407286342.tar.gz
qemu-466d37596010845eb61fbb8b5cd7daa407286342.tar.bz2
tcg: Handle dh_typecode_i128 with TCG_CALL_{RET,ARG}_NORMAL
Many hosts pass and return 128-bit quantities like sequential 64-bit quantities. Treat this just like we currently break down 64-bit quantities for a 32-bit host. Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tcg')
-rw-r--r--tcg/tcg.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/tcg/tcg.c b/tcg/tcg.c
index bc60fd0..bc7198e 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -707,11 +707,22 @@ static void init_call_layout(TCGHelperInfo *info)
case dh_typecode_s64:
info->nr_out = 64 / TCG_TARGET_REG_BITS;
info->out_kind = TCG_CALL_RET_NORMAL;
+ assert(info->nr_out <= ARRAY_SIZE(tcg_target_call_oarg_regs));
+ break;
+ case dh_typecode_i128:
+ info->nr_out = 128 / TCG_TARGET_REG_BITS;
+ info->out_kind = TCG_CALL_RET_NORMAL; /* TODO */
+ switch (/* TODO */ TCG_CALL_RET_NORMAL) {
+ case TCG_CALL_RET_NORMAL:
+ assert(info->nr_out <= ARRAY_SIZE(tcg_target_call_oarg_regs));
+ break;
+ default:
+ qemu_build_not_reached();
+ }
break;
default:
g_assert_not_reached();
}
- assert(info->nr_out <= ARRAY_SIZE(tcg_target_call_oarg_regs));
/*
* Parse and place function arguments.
@@ -733,6 +744,9 @@ static void init_call_layout(TCGHelperInfo *info)
case dh_typecode_ptr:
type = TCG_TYPE_PTR;
break;
+ case dh_typecode_i128:
+ type = TCG_TYPE_I128;
+ break;
default:
g_assert_not_reached();
}
@@ -772,6 +786,19 @@ static void init_call_layout(TCGHelperInfo *info)
}
break;
+ case TCG_TYPE_I128:
+ switch (/* TODO */ TCG_CALL_ARG_NORMAL) {
+ case TCG_CALL_ARG_EVEN:
+ layout_arg_even(&cum);
+ /* fall through */
+ case TCG_CALL_ARG_NORMAL:
+ layout_arg_normal_n(&cum, info, 128 / TCG_TARGET_REG_BITS);
+ break;
+ default:
+ qemu_build_not_reached();
+ }
+ break;
+
default:
g_assert_not_reached();
}
@@ -1692,11 +1719,13 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
op->args[pi++] = temp_arg(ret);
break;
case 2:
+ case 4:
tcg_debug_assert(ret != NULL);
- tcg_debug_assert(ret->base_type == ret->type + 1);
+ tcg_debug_assert(ret->base_type == ret->type + ctz32(n));
tcg_debug_assert(ret->temp_subindex == 0);
- op->args[pi++] = temp_arg(ret);
- op->args[pi++] = temp_arg(ret + 1);
+ for (i = 0; i < n; ++i) {
+ op->args[pi++] = temp_arg(ret + i);
+ }
break;
default:
g_assert_not_reached();