diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2022-10-21 10:47:54 +1000 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2023-02-04 06:19:42 -1000 |
commit | e9709e17ac88f16c60004c4160c9a131d36ed564 (patch) | |
tree | 05ef76aa676a95fd3c8325090e5ba0035eead71c /tcg/tcg.c | |
parent | 896c76e6ba5d9a3444fb8528fdc407747ecc82f2 (diff) | |
download | qemu-e9709e17ac88f16c60004c4160c9a131d36ed564.zip qemu-e9709e17ac88f16c60004c4160c9a131d36ed564.tar.gz qemu-e9709e17ac88f16c60004c4160c9a131d36ed564.tar.bz2 |
tcg/tci: Add TCG_TARGET_CALL_{RET,ARG}_I128
Fill in the parameters for libffi for Int128.
Adjust the interpreter to allow for 16-byte return values.
Adjust tcg_out_call to record the return value length.
Call parameters are no longer all the same size, so we
cannot reuse the same call_slots array for every function.
Compute it each time now, but only fill in slots required
for the call we're about to make.
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tcg/tcg.c')
-rw-r--r-- | tcg/tcg.c | 19 |
1 files changed, 19 insertions, 0 deletions
@@ -570,6 +570,22 @@ static GHashTable *helper_table; #ifdef CONFIG_TCG_INTERPRETER static ffi_type *typecode_to_ffi(int argmask) { + /* + * libffi does not support __int128_t, so we have forced Int128 + * to use the structure definition instead of the builtin type. + */ + static ffi_type *ffi_type_i128_elements[3] = { + &ffi_type_uint64, + &ffi_type_uint64, + NULL + }; + static ffi_type ffi_type_i128 = { + .size = 16, + .alignment = __alignof__(Int128), + .type = FFI_TYPE_STRUCT, + .elements = ffi_type_i128_elements, + }; + switch (argmask) { case dh_typecode_void: return &ffi_type_void; @@ -583,6 +599,8 @@ static ffi_type *typecode_to_ffi(int argmask) return &ffi_type_sint64; case dh_typecode_ptr: return &ffi_type_pointer; + case dh_typecode_i128: + return &ffi_type_i128; } g_assert_not_reached(); } @@ -613,6 +631,7 @@ static void init_ffi_layouts(void) /* Ignoring the return type, find the last non-zero field. */ nargs = 32 - clz32(typemask >> 3); nargs = DIV_ROUND_UP(nargs, 3); + assert(nargs <= MAX_CALL_IARGS); ca = g_malloc0(sizeof(*ca) + nargs * sizeof(ffi_type *)); ca->cif.rtype = typecode_to_ffi(typemask & 7); |