* [PATCH v6 00/26] TCI fixes and cleanups
@ 2021-05-02 23:57 Richard Henderson
2021-05-02 23:57 ` [PATCH v6 01/26] tcg: Combine dh_is_64bit and dh_is_signed to dh_typecode Richard Henderson
` (27 more replies)
0 siblings, 28 replies; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
Changes since v5:
* More patches now upstream.
* Re-work how ffi is used, to avoid breaking plugins.
Changes since v4:
* 19 more patches now upstream.
Changes since v3:
* First patch fixes g2h() breakage. This shows a hole in our CI,
in that we only build softmmu with TCI, not linux-user.
* Tidy-up for the magic qemu_ld/st macros.
* Fix libffi return value case with ffi_arg.
Changes since v2:
* 20-something patches are now upstream.
* Increase testing timeout for tci.
* Gitlab testing for tci w/ 32-bit host.
r~
Richard Henderson (26):
tcg: Combine dh_is_64bit and dh_is_signed to dh_typecode
tcg: Add tcg_call_flags
accel/tcg/plugin-gen: Drop inline markers
plugins: Drop tcg_flags from struct qemu_plugin_dyn_cb
accel/tcg: Add tcg call flags to plugins helpers
tcg: Store the TCGHelperInfo in the TCGOp for call
tcg: Add tcg_call_func
tcg: Build ffi data structures for helpers
tcg/tci: Improve tcg_target_call_clobber_regs
tcg/tci: Move call-return regs to end of tcg_target_reg_alloc_order
tcg/tci: Use ffi for calls
tcg/tci: Reserve r13 for a temporary
tcg/tci: Emit setcond before brcond
tcg/tci: Remove tci_write_reg
tcg/tci: Change encoding to uint32_t units
tcg/tci: Implement goto_ptr
tcg/tci: Implement movcond
tcg/tci: Implement andc, orc, eqv, nand, nor
tcg/tci: Implement extract, sextract
tcg/tci: Implement clz, ctz, ctpop
tcg/tci: Implement mulu2, muls2
tcg/tci: Implement add2, sub2
tcg/tci: Split out tci_qemu_ld, tci_qemu_st
tests/tcg: Increase timeout for TCI
gitlab: Rename ACCEL_CONFIGURE_OPTS to EXTRA_CONFIGURE_OPTS
gitlab: Enable cross-i386 builds of TCI
configure | 3 +
meson.build | 9 +-
accel/tcg/plugin-helpers.h | 5 +-
include/exec/helper-head.h | 37 +-
include/exec/helper-tcg.h | 34 +-
include/qemu/plugin.h | 1 -
include/tcg/tcg-opc.h | 4 +-
include/tcg/tcg.h | 1 +
target/hppa/helper.h | 3 -
target/i386/ops_sse_header.h | 3 -
target/m68k/helper.h | 1 -
target/ppc/helper.h | 3 -
tcg/internal.h | 50 +
tcg/tci/tcg-target-con-set.h | 1 +
tcg/tci/tcg-target.h | 68 +-
accel/tcg/plugin-gen.c | 20 +-
plugins/core.c | 30 +-
tcg/optimize.c | 3 +-
tcg/tcg.c | 250 ++--
tcg/tci.c | 1120 ++++++++---------
tcg/tci/tcg-target.c.inc | 550 ++++----
.gitlab-ci.d/crossbuilds.yml | 21 +-
tcg/tci/README | 20 +-
tests/docker/dockerfiles/alpine.docker | 1 +
tests/docker/dockerfiles/centos7.docker | 1 +
tests/docker/dockerfiles/centos8.docker | 1 +
tests/docker/dockerfiles/debian10.docker | 1 +
.../dockerfiles/fedora-i386-cross.docker | 1 +
.../dockerfiles/fedora-win32-cross.docker | 1 +
.../dockerfiles/fedora-win64-cross.docker | 1 +
tests/docker/dockerfiles/fedora.docker | 1 +
tests/docker/dockerfiles/ubuntu.docker | 1 +
tests/docker/dockerfiles/ubuntu1804.docker | 1 +
tests/docker/dockerfiles/ubuntu2004.docker | 1 +
tests/tcg/Makefile.target | 6 +-
35 files changed, 1179 insertions(+), 1075 deletions(-)
create mode 100644 tcg/internal.h
--
2.25.1
^ permalink raw reply [flat|nested] 53+ messages in thread
* [PATCH v6 01/26] tcg: Combine dh_is_64bit and dh_is_signed to dh_typecode
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-15 9:10 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 02/26] tcg: Add tcg_call_flags Richard Henderson
` (26 subsequent siblings)
27 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
We will shortly be interested in distinguishing pointers
from integers in the helper's declaration, as well as a
true void return. We currently have two parallel 1 bit
fields; merge them and expand to a 3 bit field.
Our current maximum is 7 helper arguments, plus the return
makes 8 * 3 = 24 bits used within the uint32_t typemask.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/exec/helper-head.h | 37 +++++--------------
include/exec/helper-tcg.h | 34 ++++++++---------
target/hppa/helper.h | 3 --
| 3 --
target/m68k/helper.h | 1 -
target/ppc/helper.h | 3 --
tcg/tcg.c | 71 +++++++++++++++++++++---------------
7 files changed, 67 insertions(+), 85 deletions(-)
diff --git a/include/exec/helper-head.h b/include/exec/helper-head.h
index 3094c7946d..b974eb394a 100644
--- a/include/exec/helper-head.h
+++ b/include/exec/helper-head.h
@@ -85,32 +85,14 @@
#define dh_retvar_ptr tcgv_ptr_temp(retval)
#define dh_retvar(t) glue(dh_retvar_, dh_alias(t))
-#define dh_is_64bit_void 0
-#define dh_is_64bit_noreturn 0
-#define dh_is_64bit_i32 0
-#define dh_is_64bit_i64 1
-#define dh_is_64bit_ptr (sizeof(void *) == 8)
-#define dh_is_64bit_cptr dh_is_64bit_ptr
-#define dh_is_64bit(t) glue(dh_is_64bit_, dh_alias(t))
-
-#define dh_is_signed_void 0
-#define dh_is_signed_noreturn 0
-#define dh_is_signed_i32 0
-#define dh_is_signed_s32 1
-#define dh_is_signed_i64 0
-#define dh_is_signed_s64 1
-#define dh_is_signed_f16 0
-#define dh_is_signed_f32 0
-#define dh_is_signed_f64 0
-#define dh_is_signed_tl 0
-#define dh_is_signed_int 1
-/* ??? This is highly specific to the host cpu. There are even special
- extension instructions that may be required, e.g. ia64's addp4. But
- for now we don't support any 64-bit targets with 32-bit pointers. */
-#define dh_is_signed_ptr 0
-#define dh_is_signed_cptr dh_is_signed_ptr
-#define dh_is_signed_env dh_is_signed_ptr
-#define dh_is_signed(t) dh_is_signed_##t
+#define dh_typecode_void 0
+#define dh_typecode_noreturn 0
+#define dh_typecode_i32 2
+#define dh_typecode_s32 3
+#define dh_typecode_i64 4
+#define dh_typecode_s64 5
+#define dh_typecode_ptr 6
+#define dh_typecode(t) glue(dh_typecode_, dh_alias(t))
#define dh_callflag_i32 0
#define dh_callflag_s32 0
@@ -126,8 +108,7 @@
#define dh_callflag_noreturn TCG_CALL_NO_RETURN
#define dh_callflag(t) glue(dh_callflag_, dh_alias(t))
-#define dh_sizemask(t, n) \
- ((dh_is_64bit(t) << (n*2)) | (dh_is_signed(t) << (n*2+1)))
+#define dh_typemask(t, n) (dh_typecode(t) << (n * 3))
#define dh_arg(t, n) \
glue(glue(tcgv_, dh_alias(t)), _temp)(glue(arg, n))
diff --git a/include/exec/helper-tcg.h b/include/exec/helper-tcg.h
index 27870509a2..32dfe94903 100644
--- a/include/exec/helper-tcg.h
+++ b/include/exec/helper-tcg.h
@@ -13,50 +13,50 @@
#define DEF_HELPER_FLAGS_0(NAME, FLAGS, ret) \
{ .func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(ret), \
- .sizemask = dh_sizemask(ret, 0) },
+ .typemask = dh_typemask(ret, 0) },
#define DEF_HELPER_FLAGS_1(NAME, FLAGS, ret, t1) \
{ .func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(ret), \
- .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) },
+ .typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) },
#define DEF_HELPER_FLAGS_2(NAME, FLAGS, ret, t1, t2) \
{ .func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(ret), \
- .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
- | dh_sizemask(t2, 2) },
+ .typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
+ | dh_typemask(t2, 2) },
#define DEF_HELPER_FLAGS_3(NAME, FLAGS, ret, t1, t2, t3) \
{ .func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(ret), \
- .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
- | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) },
+ .typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
+ | dh_typemask(t2, 2) | dh_typemask(t3, 3) },
#define DEF_HELPER_FLAGS_4(NAME, FLAGS, ret, t1, t2, t3, t4) \
{ .func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(ret), \
- .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
- | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) },
+ .typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
+ | dh_typemask(t2, 2) | dh_typemask(t3, 3) | dh_typemask(t4, 4) },
#define DEF_HELPER_FLAGS_5(NAME, FLAGS, ret, t1, t2, t3, t4, t5) \
{ .func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(ret), \
- .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
- | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) \
- | dh_sizemask(t5, 5) },
+ .typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
+ | dh_typemask(t2, 2) | dh_typemask(t3, 3) | dh_typemask(t4, 4) \
+ | dh_typemask(t5, 5) },
#define DEF_HELPER_FLAGS_6(NAME, FLAGS, ret, t1, t2, t3, t4, t5, t6) \
{ .func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(ret), \
- .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
- | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) \
- | dh_sizemask(t5, 5) | dh_sizemask(t6, 6) },
+ .typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
+ | dh_typemask(t2, 2) | dh_typemask(t3, 3) | dh_typemask(t4, 4) \
+ | dh_typemask(t5, 5) | dh_typemask(t6, 6) },
#define DEF_HELPER_FLAGS_7(NAME, FLAGS, ret, t1, t2, t3, t4, t5, t6, t7) \
{ .func = HELPER(NAME), .name = str(NAME), .flags = FLAGS, \
- .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
- | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) \
- | dh_sizemask(t5, 5) | dh_sizemask(t6, 6) | dh_sizemask(t7, 7) },
+ .typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
+ | dh_typemask(t2, 2) | dh_typemask(t3, 3) | dh_typemask(t4, 4) \
+ | dh_typemask(t5, 5) | dh_typemask(t6, 6) | dh_typemask(t7, 7) },
#include "helper.h"
#include "trace/generated-helpers.h"
diff --git a/target/hppa/helper.h b/target/hppa/helper.h
index 2d483aab58..0a629ffa7c 100644
--- a/target/hppa/helper.h
+++ b/target/hppa/helper.h
@@ -1,12 +1,9 @@
#if TARGET_REGISTER_BITS == 64
# define dh_alias_tr i64
-# define dh_is_64bit_tr 1
#else
# define dh_alias_tr i32
-# define dh_is_64bit_tr 0
#endif
#define dh_ctype_tr target_ureg
-#define dh_is_signed_tr 0
DEF_HELPER_2(excp, noreturn, env, int)
DEF_HELPER_FLAGS_2(tsv, TCG_CALL_NO_WG, void, env, tr)
--git a/target/i386/ops_sse_header.h b/target/i386/ops_sse_header.h
index 6c0c849347..e68af5c403 100644
--- a/target/i386/ops_sse_header.h
+++ b/target/i386/ops_sse_header.h
@@ -30,9 +30,6 @@
#define dh_ctype_Reg Reg *
#define dh_ctype_ZMMReg ZMMReg *
#define dh_ctype_MMXReg MMXReg *
-#define dh_is_signed_Reg dh_is_signed_ptr
-#define dh_is_signed_ZMMReg dh_is_signed_ptr
-#define dh_is_signed_MMXReg dh_is_signed_ptr
DEF_HELPER_3(glue(psrlw, SUFFIX), void, env, Reg, Reg)
DEF_HELPER_3(glue(psraw, SUFFIX), void, env, Reg, Reg)
diff --git a/target/m68k/helper.h b/target/m68k/helper.h
index 77808497a9..9842eeaa95 100644
--- a/target/m68k/helper.h
+++ b/target/m68k/helper.h
@@ -17,7 +17,6 @@ DEF_HELPER_4(cas2l_parallel, void, env, i32, i32, i32)
#define dh_alias_fp ptr
#define dh_ctype_fp FPReg *
-#define dh_is_signed_fp dh_is_signed_ptr
DEF_HELPER_3(exts32, void, env, fp, s32)
DEF_HELPER_3(extf32, void, env, fp, f32)
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 6a4dccf70c..9d45b62f40 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -107,11 +107,9 @@ DEF_HELPER_FLAGS_1(ftsqrt, TCG_CALL_NO_RWG_SE, i32, i64)
#define dh_alias_avr ptr
#define dh_ctype_avr ppc_avr_t *
-#define dh_is_signed_avr dh_is_signed_ptr
#define dh_alias_vsr ptr
#define dh_ctype_vsr ppc_vsr_t *
-#define dh_is_signed_vsr dh_is_signed_ptr
DEF_HELPER_3(vavgub, void, avr, avr, avr)
DEF_HELPER_3(vavguh, void, avr, avr, avr)
@@ -695,7 +693,6 @@ DEF_HELPER_3(store_601_batu, void, env, i32, tl)
#define dh_alias_fprp ptr
#define dh_ctype_fprp ppc_fprp_t *
-#define dh_is_signed_fprp dh_is_signed_ptr
DEF_HELPER_4(dadd, void, env, fprp, fprp, fprp)
DEF_HELPER_4(daddq, void, env, fprp, fprp, fprp)
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 1fbe0b686d..3c7c9a5517 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1089,7 +1089,7 @@ typedef struct TCGHelperInfo {
void *func;
const char *name;
unsigned flags;
- unsigned sizemask;
+ unsigned typemask;
} TCGHelperInfo;
#include "exec/helper-proto.h"
@@ -1964,13 +1964,13 @@ bool tcg_op_supported(TCGOpcode op)
void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
{
int i, real_args, nb_rets, pi;
- unsigned sizemask, flags;
+ unsigned typemask, flags;
TCGHelperInfo *info;
TCGOp *op;
info = g_hash_table_lookup(helper_table, (gpointer)func);
flags = info->flags;
- sizemask = info->sizemask;
+ typemask = info->typemask;
#ifdef CONFIG_PLUGIN
/* detect non-plugin helpers */
@@ -1983,36 +1983,41 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
&& !defined(CONFIG_TCG_INTERPRETER)
/* We have 64-bit values in one register, but need to pass as two
separate parameters. Split them. */
- int orig_sizemask = sizemask;
+ int orig_typemask = typemask;
int orig_nargs = nargs;
TCGv_i64 retl, reth;
TCGTemp *split_args[MAX_OPC_PARAM];
retl = NULL;
reth = NULL;
- if (sizemask != 0) {
- for (i = real_args = 0; i < nargs; ++i) {
- int is_64bit = sizemask & (1 << (i+1)*2);
- if (is_64bit) {
- TCGv_i64 orig = temp_tcgv_i64(args[i]);
- TCGv_i32 h = tcg_temp_new_i32();
- TCGv_i32 l = tcg_temp_new_i32();
- tcg_gen_extr_i64_i32(l, h, orig);
- split_args[real_args++] = tcgv_i32_temp(h);
- split_args[real_args++] = tcgv_i32_temp(l);
- } else {
- split_args[real_args++] = args[i];
- }
+ typemask = 0;
+ for (i = real_args = 0; i < nargs; ++i) {
+ int argtype = extract32(orig_typemask, (i + 1) * 3, 3);
+ bool is_64bit = (argtype & ~1) == dh_typecode_i64;
+
+ if (is_64bit) {
+ TCGv_i64 orig = temp_tcgv_i64(args[i]);
+ TCGv_i32 h = tcg_temp_new_i32();
+ TCGv_i32 l = tcg_temp_new_i32();
+ tcg_gen_extr_i64_i32(l, h, orig);
+ split_args[real_args++] = tcgv_i32_temp(h);
+ typemask |= dh_typecode_i32 << (real_args * 3);
+ split_args[real_args++] = tcgv_i32_temp(l);
+ typemask |= dh_typecode_i32 << (real_args * 3);
+ } else {
+ split_args[real_args++] = args[i];
+ typemask |= argtype << (real_args * 3);
}
- nargs = real_args;
- args = split_args;
- sizemask = 0;
}
+ nargs = real_args;
+ args = split_args;
#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
for (i = 0; i < nargs; ++i) {
- int is_64bit = sizemask & (1 << (i+1)*2);
- int is_signed = sizemask & (2 << (i+1)*2);
- if (!is_64bit) {
+ int argtype = extract32(typemask, (i + 1) * 3, 3);
+ bool is_32bit = (argtype & ~1) == dh_typecode_i32;
+ bool is_signed = argtype & 1;
+
+ if (is_32bit) {
TCGv_i64 temp = tcg_temp_new_i64();
TCGv_i64 orig = temp_tcgv_i64(args[i]);
if (is_signed) {
@@ -2031,7 +2036,7 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
if (ret != NULL) {
#if defined(__sparc__) && !defined(__arch64__) \
&& !defined(CONFIG_TCG_INTERPRETER)
- if (orig_sizemask & 1) {
+ if ((typemask & 6) == dh_typecode_i64) {
/* The 32-bit ABI is going to return the 64-bit value in
the %o0/%o1 register pair. Prepare for this by using
two return temporaries, and reassemble below. */
@@ -2045,7 +2050,7 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
nb_rets = 1;
}
#else
- if (TCG_TARGET_REG_BITS < 64 && (sizemask & 1)) {
+ if (TCG_TARGET_REG_BITS < 64 && (typemask & 6) == dh_typecode_i64) {
#ifdef HOST_WORDS_BIGENDIAN
op->args[pi++] = temp_arg(ret + 1);
op->args[pi++] = temp_arg(ret);
@@ -2066,7 +2071,9 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
real_args = 0;
for (i = 0; i < nargs; i++) {
- int is_64bit = sizemask & (1 << (i+1)*2);
+ int argtype = extract32(typemask, (i + 1) * 3, 3);
+ bool is_64bit = (argtype & ~1) == dh_typecode_i64;
+
if (TCG_TARGET_REG_BITS < 64 && is_64bit) {
#ifdef TCG_TARGET_CALL_ALIGN_ARGS
/* some targets want aligned 64 bit args */
@@ -2111,7 +2118,9 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
&& !defined(CONFIG_TCG_INTERPRETER)
/* Free all of the parts we allocated above. */
for (i = real_args = 0; i < orig_nargs; ++i) {
- int is_64bit = orig_sizemask & (1 << (i+1)*2);
+ int argtype = extract32(orig_typemask, (i + 1) * 3, 3);
+ bool is_64bit = (argtype & ~1) == dh_typecode_i64;
+
if (is_64bit) {
tcg_temp_free_internal(args[real_args++]);
tcg_temp_free_internal(args[real_args++]);
@@ -2119,7 +2128,7 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
real_args++;
}
}
- if (orig_sizemask & 1) {
+ if ((orig_typemask & 6) == dh_typecode_i64) {
/* The 32-bit ABI returned two 32-bit pieces. Re-assemble them.
Note that describing these as TCGv_i64 eliminates an unnecessary
zero-extension that tcg_gen_concat_i32_i64 would create. */
@@ -2129,8 +2138,10 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
}
#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
for (i = 0; i < nargs; ++i) {
- int is_64bit = sizemask & (1 << (i+1)*2);
- if (!is_64bit) {
+ int argtype = extract32(typemask, (i + 1) * 3, 3);
+ bool is_32bit = (argtype & ~1) == dh_typecode_i32;
+
+ if (is_32bit) {
tcg_temp_free_internal(args[i]);
}
}
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 02/26] tcg: Add tcg_call_flags
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
2021-05-02 23:57 ` [PATCH v6 01/26] tcg: Combine dh_is_64bit and dh_is_signed to dh_typecode Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-03 21:39 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 03/26] accel/tcg/plugin-gen: Drop inline markers Richard Henderson
` (25 subsequent siblings)
27 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
We're going to change how to look up the call flags from a TCGop,
so extract it as a helper.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/internal.h | 33 +++++++++++++++++++++++++++++++++
tcg/optimize.c | 3 ++-
tcg/tcg.c | 15 +++++++--------
3 files changed, 42 insertions(+), 9 deletions(-)
create mode 100644 tcg/internal.h
diff --git a/tcg/internal.h b/tcg/internal.h
new file mode 100644
index 0000000000..35a8a0d9fa
--- /dev/null
+++ b/tcg/internal.h
@@ -0,0 +1,33 @@
+/*
+ * Internal declarations for Tiny Code Generator for QEMU
+ *
+ * Copyright (c) 2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef TCG_INTERNAL_H
+#define TCG_INTERNAL_H 1
+
+static inline unsigned tcg_call_flags(TCGOp *op)
+{
+ return op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op) + 1];
+}
+
+#endif /* TCG_INTERNAL_H */
diff --git a/tcg/optimize.c b/tcg/optimize.c
index 37c902283e..081b62798e 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -25,6 +25,7 @@
#include "qemu/osdep.h"
#include "tcg/tcg-op.h"
+#include "internal.h"
#define CASE_OP_32_64(x) \
glue(glue(case INDEX_op_, x), _i32): \
@@ -1481,7 +1482,7 @@ void tcg_optimize(TCGContext *s)
break;
case INDEX_op_call:
- if (!(op->args[nb_oargs + nb_iargs + 1]
+ if (!(tcg_call_flags(op)
& (TCG_CALL_NO_READ_GLOBALS | TCG_CALL_NO_WRITE_GLOBALS))) {
for (i = 0; i < nb_globals; i++) {
if (test_bit(i, temps_used.l)) {
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 3c7c9a5517..b590f8d0de 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -65,6 +65,7 @@
#include "elf.h"
#include "exec/log.h"
#include "sysemu/sysemu.h"
+#include "internal.h"
/* Forward declarations for functions declared in tcg-target.c.inc and
used here. */
@@ -2335,9 +2336,9 @@ static void tcg_dump_ops(TCGContext *s, bool have_prefs)
nb_cargs = def->nb_cargs;
/* function name, flags, out args */
- col += qemu_log(" %s %s,$0x%" TCG_PRIlx ",$%d", def->name,
+ col += qemu_log(" %s %s,$0x%x,$%d", def->name,
tcg_find_helper(s, op->args[nb_oargs + nb_iargs]),
- op->args[nb_oargs + nb_iargs + 1], nb_oargs);
+ tcg_call_flags(op), nb_oargs);
for (i = 0; i < nb_oargs; i++) {
col += qemu_log(",%s", tcg_get_arg_str(s, buf, sizeof(buf),
op->args[i]));
@@ -2711,7 +2712,6 @@ static void reachable_code_pass(TCGContext *s)
QTAILQ_FOREACH_SAFE(op, &s->ops, link, op_next) {
bool remove = dead;
TCGLabel *label;
- int call_flags;
switch (op->opc) {
case INDEX_op_set_label:
@@ -2756,8 +2756,7 @@ static void reachable_code_pass(TCGContext *s)
case INDEX_op_call:
/* Notice noreturn helper calls, raising exceptions. */
- call_flags = op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op) + 1];
- if (call_flags & TCG_CALL_NO_RETURN) {
+ if (tcg_call_flags(op) & TCG_CALL_NO_RETURN) {
dead = true;
}
break;
@@ -2958,7 +2957,7 @@ static void liveness_pass_1(TCGContext *s)
nb_oargs = TCGOP_CALLO(op);
nb_iargs = TCGOP_CALLI(op);
- call_flags = op->args[nb_oargs + nb_iargs + 1];
+ call_flags = tcg_call_flags(op);
/* pure functions can be removed if their result is unused */
if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) {
@@ -3273,7 +3272,7 @@ static bool liveness_pass_2(TCGContext *s)
if (opc == INDEX_op_call) {
nb_oargs = TCGOP_CALLO(op);
nb_iargs = TCGOP_CALLI(op);
- call_flags = op->args[nb_oargs + nb_iargs + 1];
+ call_flags = tcg_call_flags(op);
} else {
nb_iargs = def->nb_iargs;
nb_oargs = def->nb_oargs;
@@ -4355,7 +4354,7 @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
TCGRegSet allocated_regs;
func_addr = (tcg_insn_unit *)(intptr_t)op->args[nb_oargs + nb_iargs];
- flags = op->args[nb_oargs + nb_iargs + 1];
+ flags = tcg_call_flags(op);
nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
if (nb_regs > nb_iargs) {
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 03/26] accel/tcg/plugin-gen: Drop inline markers
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
2021-05-02 23:57 ` [PATCH v6 01/26] tcg: Combine dh_is_64bit and dh_is_signed to dh_typecode Richard Henderson
2021-05-02 23:57 ` [PATCH v6 02/26] tcg: Add tcg_call_flags Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-03 21:40 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 04/26] plugins: Drop tcg_flags from struct qemu_plugin_dyn_cb Richard Henderson
` (24 subsequent siblings)
27 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
Let the compiler decide on inlining.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
accel/tcg/plugin-gen.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index c3dc3effe7..eb99be52d0 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -161,9 +161,8 @@ static void gen_empty_mem_helper(void)
tcg_temp_free_ptr(ptr);
}
-static inline
-void gen_plugin_cb_start(enum plugin_gen_from from,
- enum plugin_gen_cb type, unsigned wr)
+static void gen_plugin_cb_start(enum plugin_gen_from from,
+ enum plugin_gen_cb type, unsigned wr)
{
TCGOp *op;
@@ -180,7 +179,7 @@ static void gen_wrapped(enum plugin_gen_from from,
tcg_gen_plugin_cb_end();
}
-static inline void plugin_gen_empty_callback(enum plugin_gen_from from)
+static void plugin_gen_empty_callback(enum plugin_gen_from from)
{
switch (from) {
case PLUGIN_GEN_AFTER_INSN:
@@ -514,9 +513,8 @@ static bool op_rw(const TCGOp *op, const struct qemu_plugin_dyn_cb *cb)
return !!(cb->rw & (w + 1));
}
-static inline
-void inject_cb_type(const GArray *cbs, TCGOp *begin_op, inject_fn inject,
- op_ok_fn ok)
+static void inject_cb_type(const GArray *cbs, TCGOp *begin_op,
+ inject_fn inject, op_ok_fn ok)
{
TCGOp *end_op;
TCGOp *op;
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 04/26] plugins: Drop tcg_flags from struct qemu_plugin_dyn_cb
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (2 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 03/26] accel/tcg/plugin-gen: Drop inline markers Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-16 12:53 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 05/26] accel/tcg: Add tcg call flags to plugins helpers Richard Henderson
` (23 subsequent siblings)
27 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
As noted by qemu-plugins.h, enum qemu_plugin_cb_flags is
currently unused -- plugins can neither read nor write
guest registers.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
accel/tcg/plugin-helpers.h | 1 -
include/qemu/plugin.h | 1 -
accel/tcg/plugin-gen.c | 8 ++++----
plugins/core.c | 30 ++++++------------------------
4 files changed, 10 insertions(+), 30 deletions(-)
diff --git a/accel/tcg/plugin-helpers.h b/accel/tcg/plugin-helpers.h
index 1916ee7920..853bd21677 100644
--- a/accel/tcg/plugin-helpers.h
+++ b/accel/tcg/plugin-helpers.h
@@ -1,5 +1,4 @@
#ifdef CONFIG_PLUGIN
-/* Note: no TCG flags because those are overwritten later */
DEF_HELPER_2(plugin_vcpu_udata_cb, void, i32, ptr)
DEF_HELPER_4(plugin_vcpu_mem_cb, void, i32, i32, i64, ptr)
#endif
diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
index c5a79a89f0..0fefbc6084 100644
--- a/include/qemu/plugin.h
+++ b/include/qemu/plugin.h
@@ -79,7 +79,6 @@ enum plugin_dyn_cb_subtype {
struct qemu_plugin_dyn_cb {
union qemu_plugin_cb_sig f;
void *userp;
- unsigned tcg_flags;
enum plugin_dyn_cb_subtype type;
/* @rw applies to mem callbacks only (both regular and inline) */
enum qemu_plugin_mem_rw rw;
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index eb99be52d0..1e7f201cd2 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -385,7 +385,7 @@ static TCGOp *copy_st_ptr(TCGOp **begin_op, TCGOp *op)
}
static TCGOp *copy_call(TCGOp **begin_op, TCGOp *op, void *empty_func,
- void *func, unsigned tcg_flags, int *cb_idx)
+ void *func, int *cb_idx)
{
/* copy all ops until the call */
do {
@@ -412,7 +412,7 @@ static TCGOp *copy_call(TCGOp **begin_op, TCGOp *op, void *empty_func,
tcg_debug_assert(i < MAX_OPC_PARAM_ARGS);
}
op->args[*cb_idx] = (uintptr_t)func;
- op->args[*cb_idx + 1] = tcg_flags;
+ op->args[*cb_idx + 1] = (*begin_op)->args[*cb_idx + 1];
return op;
}
@@ -439,7 +439,7 @@ static TCGOp *append_udata_cb(const struct qemu_plugin_dyn_cb *cb,
/* call */
op = copy_call(&begin_op, op, HELPER(plugin_vcpu_udata_cb),
- cb->f.vcpu_udata, cb->tcg_flags, cb_idx);
+ cb->f.vcpu_udata, cb_idx);
return op;
}
@@ -490,7 +490,7 @@ static TCGOp *append_mem_cb(const struct qemu_plugin_dyn_cb *cb,
if (type == PLUGIN_GEN_CB_MEM) {
/* call */
op = copy_call(&begin_op, op, HELPER(plugin_vcpu_mem_cb),
- cb->f.vcpu_udata, cb->tcg_flags, cb_idx);
+ cb->f.vcpu_udata, cb_idx);
}
return op;
diff --git a/plugins/core.c b/plugins/core.c
index 87b823bbc4..03e0a4c806 100644
--- a/plugins/core.c
+++ b/plugins/core.c
@@ -297,33 +297,15 @@ void plugin_register_inline_op(GArray **arr,
dyn_cb->inline_insn.imm = imm;
}
-static inline uint32_t cb_to_tcg_flags(enum qemu_plugin_cb_flags flags)
-{
- uint32_t ret;
-
- switch (flags) {
- case QEMU_PLUGIN_CB_RW_REGS:
- ret = 0;
- break;
- case QEMU_PLUGIN_CB_R_REGS:
- ret = TCG_CALL_NO_WG;
- break;
- case QEMU_PLUGIN_CB_NO_REGS:
- default:
- ret = TCG_CALL_NO_RWG;
- }
- return ret;
-}
-
-inline void
-plugin_register_dyn_cb__udata(GArray **arr,
- qemu_plugin_vcpu_udata_cb_t cb,
- enum qemu_plugin_cb_flags flags, void *udata)
+void plugin_register_dyn_cb__udata(GArray **arr,
+ qemu_plugin_vcpu_udata_cb_t cb,
+ enum qemu_plugin_cb_flags flags,
+ void *udata)
{
struct qemu_plugin_dyn_cb *dyn_cb = plugin_get_dyn_cb(arr);
dyn_cb->userp = udata;
- dyn_cb->tcg_flags = cb_to_tcg_flags(flags);
+ /* Note flags are discarded as unused. */
dyn_cb->f.vcpu_udata = cb;
dyn_cb->type = PLUGIN_CB_REGULAR;
}
@@ -338,7 +320,7 @@ void plugin_register_vcpu_mem_cb(GArray **arr,
dyn_cb = plugin_get_dyn_cb(arr);
dyn_cb->userp = udata;
- dyn_cb->tcg_flags = cb_to_tcg_flags(flags);
+ /* Note flags are discarded as unused. */
dyn_cb->type = PLUGIN_CB_REGULAR;
dyn_cb->rw = rw;
dyn_cb->f.generic = cb;
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 05/26] accel/tcg: Add tcg call flags to plugins helpers
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (3 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 04/26] plugins: Drop tcg_flags from struct qemu_plugin_dyn_cb Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-15 9:02 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 06/26] tcg: Store the TCGHelperInfo in the TCGOp for call Richard Henderson
` (22 subsequent siblings)
27 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
As noted by qemu-plugins.h, plugins can neither read nor write
guest registers.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
accel/tcg/plugin-helpers.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/accel/tcg/plugin-helpers.h b/accel/tcg/plugin-helpers.h
index 853bd21677..9829abe4a9 100644
--- a/accel/tcg/plugin-helpers.h
+++ b/accel/tcg/plugin-helpers.h
@@ -1,4 +1,4 @@
#ifdef CONFIG_PLUGIN
-DEF_HELPER_2(plugin_vcpu_udata_cb, void, i32, ptr)
-DEF_HELPER_4(plugin_vcpu_mem_cb, void, i32, i32, i64, ptr)
+DEF_HELPER_FLAGS_2(plugin_vcpu_udata_cb, TCG_CALL_NO_RWG, void, i32, ptr)
+DEF_HELPER_FLAGS_4(plugin_vcpu_mem_cb, TCG_CALL_NO_RWG, void, i32, i32, i64, ptr)
#endif
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 06/26] tcg: Store the TCGHelperInfo in the TCGOp for call
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (4 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 05/26] accel/tcg: Add tcg call flags to plugins helpers Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-15 9:00 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 07/26] tcg: Add tcg_call_func Richard Henderson
` (21 subsequent siblings)
27 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
This will give us both flags and typemask for use later.
We also fix a dumping bug, wherein calls generated for plugins
fail tcg_find_helper and print (null) instead of either a name
or the raw function pointer.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/internal.h | 14 +++++++++++++-
tcg/tcg.c | 49 +++++++++++++++++++++----------------------------
2 files changed, 34 insertions(+), 29 deletions(-)
diff --git a/tcg/internal.h b/tcg/internal.h
index 35a8a0d9fa..c2d5e9c42f 100644
--- a/tcg/internal.h
+++ b/tcg/internal.h
@@ -25,9 +25,21 @@
#ifndef TCG_INTERNAL_H
#define TCG_INTERNAL_H 1
+typedef struct TCGHelperInfo {
+ void *func;
+ const char *name;
+ unsigned flags;
+ unsigned typemask;
+} TCGHelperInfo;
+
+static inline const TCGHelperInfo *tcg_call_info(TCGOp *op)
+{
+ return (void *)(uintptr_t)op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op) + 1];
+}
+
static inline unsigned tcg_call_flags(TCGOp *op)
{
- return op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op) + 1];
+ return tcg_call_info(op)->flags;
}
#endif /* TCG_INTERNAL_H */
diff --git a/tcg/tcg.c b/tcg/tcg.c
index b590f8d0de..d42fa6c956 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1086,13 +1086,6 @@ void tcg_pool_reset(TCGContext *s)
s->pool_current = NULL;
}
-typedef struct TCGHelperInfo {
- void *func;
- const char *name;
- unsigned flags;
- unsigned typemask;
-} TCGHelperInfo;
-
#include "exec/helper-proto.h"
static const TCGHelperInfo all_helpers[] = {
@@ -1965,12 +1958,11 @@ bool tcg_op_supported(TCGOpcode op)
void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
{
int i, real_args, nb_rets, pi;
- unsigned typemask, flags;
- TCGHelperInfo *info;
+ unsigned typemask;
+ const TCGHelperInfo *info;
TCGOp *op;
info = g_hash_table_lookup(helper_table, (gpointer)func);
- flags = info->flags;
typemask = info->typemask;
#ifdef CONFIG_PLUGIN
@@ -2108,7 +2100,7 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
real_args++;
}
op->args[pi++] = (uintptr_t)func;
- op->args[pi++] = flags;
+ op->args[pi++] = (uintptr_t)info;
TCGOP_CALLI(op) = real_args;
/* Make sure the fields didn't overflow. */
@@ -2227,19 +2219,6 @@ static char *tcg_get_arg_str(TCGContext *s, char *buf,
return tcg_get_arg_str_ptr(s, buf, buf_size, arg_temp(arg));
}
-/* Find helper name. */
-static inline const char *tcg_find_helper(TCGContext *s, uintptr_t val)
-{
- const char *ret = NULL;
- if (helper_table) {
- TCGHelperInfo *info = g_hash_table_lookup(helper_table, (gpointer)val);
- if (info) {
- ret = info->name;
- }
- }
- return ret;
-}
-
static const char * const cond_name[] =
{
[TCG_COND_NEVER] = "never",
@@ -2330,15 +2309,29 @@ static void tcg_dump_ops(TCGContext *s, bool have_prefs)
col += qemu_log(" " TARGET_FMT_lx, a);
}
} else if (c == INDEX_op_call) {
+ const TCGHelperInfo *info = tcg_call_info(op);
+ void *func;
+
/* variable number of arguments */
nb_oargs = TCGOP_CALLO(op);
nb_iargs = TCGOP_CALLI(op);
nb_cargs = def->nb_cargs;
- /* function name, flags, out args */
- col += qemu_log(" %s %s,$0x%x,$%d", def->name,
- tcg_find_helper(s, op->args[nb_oargs + nb_iargs]),
- tcg_call_flags(op), nb_oargs);
+ col += qemu_log(" %s ", def->name);
+
+ /*
+ * Print the function name from TCGHelperInfo, if available.
+ * Note that plugins have a template function for the info,
+ * but the actual function pointer comes from the plugin.
+ */
+ func = (void *)(uintptr_t)op->args[nb_oargs + nb_iargs];
+ if (func == info->func) {
+ col += qemu_log("%s", info->name);
+ } else {
+ col += qemu_log("plugin(%p)", func);
+ }
+
+ col += qemu_log("$0x%x,$%d", info->flags, nb_oargs);
for (i = 0; i < nb_oargs; i++) {
col += qemu_log(",%s", tcg_get_arg_str(s, buf, sizeof(buf),
op->args[i]));
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 07/26] tcg: Add tcg_call_func
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (5 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 06/26] tcg: Store the TCGHelperInfo in the TCGOp for call Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-03 21:50 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 08/26] tcg: Build ffi data structures for helpers Richard Henderson
` (20 subsequent siblings)
27 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/internal.h | 5 +++++
tcg/tcg.c | 5 ++---
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/tcg/internal.h b/tcg/internal.h
index c2d5e9c42f..cd128e2a83 100644
--- a/tcg/internal.h
+++ b/tcg/internal.h
@@ -32,6 +32,11 @@ typedef struct TCGHelperInfo {
unsigned typemask;
} TCGHelperInfo;
+static inline void *tcg_call_func(TCGOp *op)
+{
+ return (void *)(uintptr_t)op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op)];
+}
+
static inline const TCGHelperInfo *tcg_call_info(TCGOp *op)
{
return (void *)(uintptr_t)op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op) + 1];
diff --git a/tcg/tcg.c b/tcg/tcg.c
index d42fa6c956..1e5e165bff 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2310,7 +2310,7 @@ static void tcg_dump_ops(TCGContext *s, bool have_prefs)
}
} else if (c == INDEX_op_call) {
const TCGHelperInfo *info = tcg_call_info(op);
- void *func;
+ void *func = tcg_call_func(op);
/* variable number of arguments */
nb_oargs = TCGOP_CALLO(op);
@@ -2324,7 +2324,6 @@ static void tcg_dump_ops(TCGContext *s, bool have_prefs)
* Note that plugins have a template function for the info,
* but the actual function pointer comes from the plugin.
*/
- func = (void *)(uintptr_t)op->args[nb_oargs + nb_iargs];
if (func == info->func) {
col += qemu_log("%s", info->name);
} else {
@@ -4346,7 +4345,7 @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
int allocate_args;
TCGRegSet allocated_regs;
- func_addr = (tcg_insn_unit *)(intptr_t)op->args[nb_oargs + nb_iargs];
+ func_addr = tcg_call_func(op);
flags = tcg_call_flags(op);
nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 08/26] tcg: Build ffi data structures for helpers
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (6 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 07/26] tcg: Add tcg_call_func Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-31 18:55 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 09/26] tcg/tci: Improve tcg_target_call_clobber_regs Richard Henderson
` (19 subsequent siblings)
27 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
Add libffi as a build requirement for TCI.
Add libffi to the dockerfiles to satisfy that requirement.
Construct an ffi_cif structure for each unique typemask.
Record the result in a separate hash table for later lookup;
this allows helper_table to stay const.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
meson.build | 9 ++-
tcg/tcg.c | 58 +++++++++++++++++++
tests/docker/dockerfiles/alpine.docker | 1 +
tests/docker/dockerfiles/centos7.docker | 1 +
tests/docker/dockerfiles/centos8.docker | 1 +
tests/docker/dockerfiles/debian10.docker | 1 +
.../dockerfiles/fedora-i386-cross.docker | 1 +
.../dockerfiles/fedora-win32-cross.docker | 1 +
.../dockerfiles/fedora-win64-cross.docker | 1 +
tests/docker/dockerfiles/fedora.docker | 1 +
tests/docker/dockerfiles/ubuntu.docker | 1 +
tests/docker/dockerfiles/ubuntu1804.docker | 1 +
tests/docker/dockerfiles/ubuntu2004.docker | 1 +
13 files changed, 77 insertions(+), 1 deletion(-)
diff --git a/meson.build b/meson.build
index c6f4b0cf5e..0bb0b7b28d 100644
--- a/meson.build
+++ b/meson.build
@@ -1942,7 +1942,14 @@ specific_ss.add(when: 'CONFIG_TCG', if_true: files(
'tcg/tcg-op.c',
'tcg/tcg.c',
))
-specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('tcg/tci.c'))
+
+if get_option('tcg_interpreter')
+ libffi = dependency('libffi', version: '>=3.0',
+ static: enable_static, method: 'pkg-config',
+ required: true)
+ specific_ss.add(libffi)
+ specific_ss.add(files('tcg/tci.c'))
+endif
# Work around a gcc bug/misfeature wherein constant propagation looks
# through an alias:
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 1e5e165bff..8bb65ff1c6 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -67,6 +67,10 @@
#include "sysemu/sysemu.h"
#include "internal.h"
+#ifdef CONFIG_TCG_INTERPRETER
+#include <ffi.h>
+#endif
+
/* Forward declarations for functions declared in tcg-target.c.inc and
used here. */
static void tcg_target_init(TCGContext *s);
@@ -1093,6 +1097,19 @@ static const TCGHelperInfo all_helpers[] = {
};
static GHashTable *helper_table;
+#ifdef CONFIG_TCG_INTERPRETER
+static GHashTable *ffi_table;
+
+static ffi_type * const typecode_to_ffi[8] = {
+ [dh_typecode_void] = &ffi_type_void,
+ [dh_typecode_i32] = &ffi_type_uint32,
+ [dh_typecode_s32] = &ffi_type_sint32,
+ [dh_typecode_i64] = &ffi_type_uint64,
+ [dh_typecode_s64] = &ffi_type_sint64,
+ [dh_typecode_ptr] = &ffi_type_pointer,
+};
+#endif
+
static int indirect_reg_alloc_order[ARRAY_SIZE(tcg_target_reg_alloc_order)];
static void process_op_defs(TCGContext *s);
static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type,
@@ -1135,6 +1152,47 @@ void tcg_context_init(TCGContext *s)
(gpointer)&all_helpers[i]);
}
+#ifdef CONFIG_TCG_INTERPRETER
+ /* g_direct_hash/equal for direct comparisons on uint32_t. */
+ ffi_table = g_hash_table_new(NULL, NULL);
+ for (i = 0; i < ARRAY_SIZE(all_helpers); ++i) {
+ struct {
+ ffi_cif cif;
+ ffi_type *args[];
+ } *ca;
+ uint32_t typemask = all_helpers[i].typemask;
+ gpointer hash = (gpointer)(uintptr_t)typemask;
+ ffi_status status;
+ int nargs;
+
+ if (g_hash_table_lookup(ffi_table, hash)) {
+ continue;
+ }
+
+ /* Ignoring the return type, find the last non-zero field. */
+ nargs = 32 - clz32(typemask >> 3);
+ nargs = DIV_ROUND_UP(nargs, 3);
+
+ ca = g_malloc0(sizeof(*ca) + nargs * sizeof(ffi_type *));
+ ca->cif.rtype = typecode_to_ffi[typemask & 7];
+ ca->cif.nargs = nargs;
+
+ if (nargs != 0) {
+ ca->cif.arg_types = ca->args;
+ for (i = 0; i < nargs; ++i) {
+ int typecode = extract32(typemask, (i + 1) * 3, 3);
+ ca->args[i] = typecode_to_ffi[typecode];
+ }
+ }
+
+ status = ffi_prep_cif(&ca->cif, FFI_DEFAULT_ABI, nargs,
+ ca->cif.rtype, ca->cif.arg_types);
+ assert(status == FFI_OK);
+
+ g_hash_table_insert(ffi_table, hash, (gpointer)&ca->cif);
+ }
+#endif
+
tcg_target_init(s);
process_op_defs(s);
diff --git a/tests/docker/dockerfiles/alpine.docker b/tests/docker/dockerfiles/alpine.docker
index d63a269aef..017cbbceac 100644
--- a/tests/docker/dockerfiles/alpine.docker
+++ b/tests/docker/dockerfiles/alpine.docker
@@ -20,6 +20,7 @@ ENV PACKAGES \
gtk+3.0-dev \
libaio-dev \
libcap-ng-dev \
+ libffi-dev \
libjpeg-turbo-dev \
libnfs-dev \
libpng-dev \
diff --git a/tests/docker/dockerfiles/centos7.docker b/tests/docker/dockerfiles/centos7.docker
index 75fdb53c7c..fff7c5a424 100644
--- a/tests/docker/dockerfiles/centos7.docker
+++ b/tests/docker/dockerfiles/centos7.docker
@@ -20,6 +20,7 @@ ENV PACKAGES \
libaio-devel \
libepoxy-devel \
libfdt-devel \
+ libffi-devel \
libgcrypt-devel \
librdmacm-devel \
libzstd-devel \
diff --git a/tests/docker/dockerfiles/centos8.docker b/tests/docker/dockerfiles/centos8.docker
index a8c6c528b0..fcab3bc8e4 100644
--- a/tests/docker/dockerfiles/centos8.docker
+++ b/tests/docker/dockerfiles/centos8.docker
@@ -16,6 +16,7 @@ ENV PACKAGES \
libaio-devel \
libepoxy-devel \
libfdt-devel \
+ libffi-devel \
libgcrypt-devel \
lzo-devel \
make \
diff --git a/tests/docker/dockerfiles/debian10.docker b/tests/docker/dockerfiles/debian10.docker
index d034acbd25..1f8bea97b3 100644
--- a/tests/docker/dockerfiles/debian10.docker
+++ b/tests/docker/dockerfiles/debian10.docker
@@ -26,6 +26,7 @@ RUN apt update && \
gdb-multiarch \
gettext \
git \
+ libffi-dev \
libncurses5-dev \
ninja-build \
pkg-config \
diff --git a/tests/docker/dockerfiles/fedora-i386-cross.docker b/tests/docker/dockerfiles/fedora-i386-cross.docker
index 966072c08e..b620d7664d 100644
--- a/tests/docker/dockerfiles/fedora-i386-cross.docker
+++ b/tests/docker/dockerfiles/fedora-i386-cross.docker
@@ -5,6 +5,7 @@ ENV PACKAGES \
findutils \
gcc \
git \
+ libffi-devel.i686 \
libtasn1-devel.i686 \
libzstd-devel.i686 \
make \
diff --git a/tests/docker/dockerfiles/fedora-win32-cross.docker b/tests/docker/dockerfiles/fedora-win32-cross.docker
index 81b5659e9c..5072c9c2a6 100644
--- a/tests/docker/dockerfiles/fedora-win32-cross.docker
+++ b/tests/docker/dockerfiles/fedora-win32-cross.docker
@@ -18,6 +18,7 @@ ENV PACKAGES \
mingw32-gmp \
mingw32-gnutls \
mingw32-gtk3 \
+ mingw32-libffi \
mingw32-libjpeg-turbo \
mingw32-libpng \
mingw32-libtasn1 \
diff --git a/tests/docker/dockerfiles/fedora-win64-cross.docker b/tests/docker/dockerfiles/fedora-win64-cross.docker
index bcb428e724..5cdca965c2 100644
--- a/tests/docker/dockerfiles/fedora-win64-cross.docker
+++ b/tests/docker/dockerfiles/fedora-win64-cross.docker
@@ -17,6 +17,7 @@ ENV PACKAGES \
mingw64-glib2 \
mingw64-gmp \
mingw64-gtk3 \
+ mingw64-libffi \
mingw64-libjpeg-turbo \
mingw64-libpng \
mingw64-libtasn1 \
diff --git a/tests/docker/dockerfiles/fedora.docker b/tests/docker/dockerfiles/fedora.docker
index 915fdc1845..8140fe67b2 100644
--- a/tests/docker/dockerfiles/fedora.docker
+++ b/tests/docker/dockerfiles/fedora.docker
@@ -32,6 +32,7 @@ ENV PACKAGES \
libcurl-devel \
libepoxy-devel \
libfdt-devel \
+ libffi-devel \
libiscsi-devel \
libjpeg-devel \
libpmem-devel \
diff --git a/tests/docker/dockerfiles/ubuntu.docker b/tests/docker/dockerfiles/ubuntu.docker
index b5ef7a8198..204a7c10a5 100644
--- a/tests/docker/dockerfiles/ubuntu.docker
+++ b/tests/docker/dockerfiles/ubuntu.docker
@@ -28,6 +28,7 @@ ENV PACKAGES \
libdrm-dev \
libepoxy-dev \
libfdt-dev \
+ libffi-dev \
libgbm-dev \
libgnutls28-dev \
libgtk-3-dev \
diff --git a/tests/docker/dockerfiles/ubuntu1804.docker b/tests/docker/dockerfiles/ubuntu1804.docker
index 9b0a19ba5e..4d567a46fe 100644
--- a/tests/docker/dockerfiles/ubuntu1804.docker
+++ b/tests/docker/dockerfiles/ubuntu1804.docker
@@ -16,6 +16,7 @@ ENV PACKAGES \
libdrm-dev \
libepoxy-dev \
libfdt-dev \
+ libffi-dev \
libgbm-dev \
libgtk-3-dev \
libibverbs-dev \
diff --git a/tests/docker/dockerfiles/ubuntu2004.docker b/tests/docker/dockerfiles/ubuntu2004.docker
index 9750016e51..f73631ba84 100644
--- a/tests/docker/dockerfiles/ubuntu2004.docker
+++ b/tests/docker/dockerfiles/ubuntu2004.docker
@@ -19,6 +19,7 @@ ENV PACKAGES flex bison \
libdrm-dev \
libepoxy-dev \
libfdt-dev \
+ libffi-dev \
libgbm-dev \
libgtk-3-dev \
libibverbs-dev \
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 09/26] tcg/tci: Improve tcg_target_call_clobber_regs
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (7 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 08/26] tcg: Build ffi data structures for helpers Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-02 23:57 ` [PATCH v6 10/26] tcg/tci: Move call-return regs to end of tcg_target_reg_alloc_order Richard Henderson
` (18 subsequent siblings)
27 siblings, 0 replies; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
The current setting is much too pessimistic. Indicating only
the one or two registers that are actually assigned after a
call should avoid unnecessary movement between the register
array and the stack array.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/tci/tcg-target.c.inc | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
index ee6cdfec71..fb7c927fdf 100644
--- a/tcg/tci/tcg-target.c.inc
+++ b/tcg/tci/tcg-target.c.inc
@@ -812,8 +812,14 @@ static void tcg_target_init(TCGContext *s)
tcg_target_available_regs[TCG_TYPE_I32] = BIT(TCG_TARGET_NB_REGS) - 1;
/* Registers available for 64 bit operations. */
tcg_target_available_regs[TCG_TYPE_I64] = BIT(TCG_TARGET_NB_REGS) - 1;
- /* TODO: Which registers should be set here? */
- tcg_target_call_clobber_regs = BIT(TCG_TARGET_NB_REGS) - 1;
+ /*
+ * The interpreter "registers" are in the local stack frame and
+ * cannot be clobbered by the called helper functions. However,
+ * the interpreter assumes a 64-bit return value and assigns to
+ * the return value registers.
+ */
+ tcg_target_call_clobber_regs =
+ MAKE_64BIT_MASK(TCG_REG_R0, 64 / TCG_TARGET_REG_BITS);
s->reserved_regs = 0;
tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 10/26] tcg/tci: Move call-return regs to end of tcg_target_reg_alloc_order
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (8 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 09/26] tcg/tci: Improve tcg_target_call_clobber_regs Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-15 9:01 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 11/26] tcg/tci: Use ffi for calls Richard Henderson
` (17 subsequent siblings)
27 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
As the only call-clobbered regs for TCI, these should
receive the least priority.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/tci/tcg-target.c.inc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
index fb7c927fdf..288e945465 100644
--- a/tcg/tci/tcg-target.c.inc
+++ b/tcg/tci/tcg-target.c.inc
@@ -170,8 +170,6 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
}
static const int tcg_target_reg_alloc_order[] = {
- TCG_REG_R0,
- TCG_REG_R1,
TCG_REG_R2,
TCG_REG_R3,
TCG_REG_R4,
@@ -186,6 +184,8 @@ static const int tcg_target_reg_alloc_order[] = {
TCG_REG_R13,
TCG_REG_R14,
TCG_REG_R15,
+ TCG_REG_R1,
+ TCG_REG_R0,
};
#if MAX_OPC_PARAM_IARGS != 6
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 11/26] tcg/tci: Use ffi for calls
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (9 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 10/26] tcg/tci: Move call-return regs to end of tcg_target_reg_alloc_order Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-06-01 5:18 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 12/26] tcg/tci: Reserve r13 for a temporary Richard Henderson
` (16 subsequent siblings)
27 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
This requires adjusting where arguments are stored.
Place them on the stack at left-aligned positions.
Adjust the stack frame to be at entirely positive offsets.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/tcg/tcg.h | 1 +
tcg/tci/tcg-target.h | 2 +-
tcg/tcg.c | 64 +++++++++++++------
tcg/tci.c | 135 ++++++++++++++++++++++-----------------
tcg/tci/tcg-target.c.inc | 50 +++++++--------
5 files changed, 148 insertions(+), 104 deletions(-)
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 0f0695e90d..e5573a9877 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -53,6 +53,7 @@
#define MAX_OPC_PARAM (4 + (MAX_OPC_PARAM_PER_ARG * MAX_OPC_PARAM_ARGS))
#define CPU_TEMP_BUF_NLONGS 128
+#define TCG_STATIC_FRAME_SIZE (CPU_TEMP_BUF_NLONGS * sizeof(long))
/* Default target word size to pointer size. */
#ifndef TCG_TARGET_REG_BITS
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index 52af6d8bc5..4df10e2e83 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -161,7 +161,7 @@ typedef enum {
/* Used for function call generation. */
#define TCG_TARGET_CALL_STACK_OFFSET 0
-#define TCG_TARGET_STACK_ALIGN 16
+#define TCG_TARGET_STACK_ALIGN 8
#define HAVE_TCG_QEMU_TB_EXEC
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 8bb65ff1c6..7b9e31d15e 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -154,7 +154,12 @@ static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
intptr_t arg2);
static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
TCGReg base, intptr_t ofs);
+#ifdef CONFIG_TCG_INTERPRETER
+static void tcg_out_call(TCGContext *s, const tcg_insn_unit *target,
+ ffi_cif *cif);
+#else
static void tcg_out_call(TCGContext *s, const tcg_insn_unit *target);
+#endif
static int tcg_target_const_match(tcg_target_long val, TCGType type,
const TCGArgConstraint *arg_ct);
#ifdef TCG_TARGET_NEED_LDST_LABELS
@@ -2124,25 +2129,37 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
for (i = 0; i < nargs; i++) {
int argtype = extract32(typemask, (i + 1) * 3, 3);
bool is_64bit = (argtype & ~1) == dh_typecode_i64;
+ bool want_align = false;
+
+#if defined(CONFIG_TCG_INTERPRETER)
+ /*
+ * Align all arguments, so that they land in predictable places
+ * for passing off to ffi_call.
+ */
+ want_align = true;
+#elif defined(TCG_TARGET_CALL_ALIGN_ARGS)
+ /* Some targets want aligned 64 bit args */
+ want_align = is_64bit;
+#endif
+
+ if (TCG_TARGET_REG_BITS < 64 && want_align && (real_args & 1)) {
+ op->args[pi++] = TCG_CALL_DUMMY_ARG;
+ real_args++;
+ }
if (TCG_TARGET_REG_BITS < 64 && is_64bit) {
-#ifdef TCG_TARGET_CALL_ALIGN_ARGS
- /* some targets want aligned 64 bit args */
- if (real_args & 1) {
- op->args[pi++] = TCG_CALL_DUMMY_ARG;
- real_args++;
- }
-#endif
- /* If stack grows up, then we will be placing successive
- arguments at lower addresses, which means we need to
- reverse the order compared to how we would normally
- treat either big or little-endian. For those arguments
- that will wind up in registers, this still works for
- HPPA (the only current STACK_GROWSUP target) since the
- argument registers are *also* allocated in decreasing
- order. If another such target is added, this logic may
- have to get more complicated to differentiate between
- stack arguments and register arguments. */
+ /*
+ * If stack grows up, then we will be placing successive
+ * arguments at lower addresses, which means we need to
+ * reverse the order compared to how we would normally
+ * treat either big or little-endian. For those arguments
+ * that will wind up in registers, this still works for
+ * HPPA (the only current STACK_GROWSUP target) since the
+ * argument registers are *also* allocated in decreasing
+ * order. If another such target is added, this logic may
+ * have to get more complicated to differentiate between
+ * stack arguments and register arguments.
+ */
#if defined(HOST_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
op->args[pi++] = temp_arg(args[i] + 1);
op->args[pi++] = temp_arg(args[i]);
@@ -4393,6 +4410,7 @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
const int nb_oargs = TCGOP_CALLO(op);
const int nb_iargs = TCGOP_CALLI(op);
const TCGLifeData arg_life = op->life;
+ const TCGHelperInfo *info;
int flags, nb_regs, i;
TCGReg reg;
TCGArg arg;
@@ -4404,7 +4422,8 @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
TCGRegSet allocated_regs;
func_addr = tcg_call_func(op);
- flags = tcg_call_flags(op);
+ info = tcg_call_info(op);
+ flags = info->flags;
nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
if (nb_regs > nb_iargs) {
@@ -4496,7 +4515,16 @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
save_globals(s, allocated_regs);
}
+#ifdef CONFIG_TCG_INTERPRETER
+ {
+ gpointer hash = (gpointer)(uintptr_t)info->typemask;
+ ffi_cif *cif = g_hash_table_lookup(ffi_table, hash);
+ assert(cif != NULL);
+ tcg_out_call(s, func_addr, cif);
+ }
+#else
tcg_out_call(s, func_addr);
+#endif
/* assign output registers and emit moves if needed */
for(i = 0; i < nb_oargs; i++) {
diff --git a/tcg/tci.c b/tcg/tci.c
index d68c5a4e55..743c12af67 100644
--- a/tcg/tci.c
+++ b/tcg/tci.c
@@ -18,6 +18,13 @@
*/
#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "tcg/tcg.h" /* MAX_OPC_PARAM_IARGS */
+#include "exec/cpu_ldst.h"
+#include "tcg/tcg-op.h"
+#include "qemu/compiler.h"
+#include <ffi.h>
+
/* Enable TCI assertions only when debugging TCG (and without NDEBUG defined).
* Without assertions, the interpreter runs much faster. */
@@ -27,36 +34,8 @@
# define tci_assert(cond) ((void)(cond))
#endif
-#include "qemu-common.h"
-#include "tcg/tcg.h" /* MAX_OPC_PARAM_IARGS */
-#include "exec/cpu_ldst.h"
-#include "tcg/tcg-op.h"
-#include "qemu/compiler.h"
-
-#if MAX_OPC_PARAM_IARGS != 6
-# error Fix needed, number of supported input arguments changed!
-#endif
-#if TCG_TARGET_REG_BITS == 32
-typedef uint64_t (*helper_function)(tcg_target_ulong, tcg_target_ulong,
- tcg_target_ulong, tcg_target_ulong,
- tcg_target_ulong, tcg_target_ulong,
- tcg_target_ulong, tcg_target_ulong,
- tcg_target_ulong, tcg_target_ulong,
- tcg_target_ulong, tcg_target_ulong);
-#else
-typedef uint64_t (*helper_function)(tcg_target_ulong, tcg_target_ulong,
- tcg_target_ulong, tcg_target_ulong,
- tcg_target_ulong, tcg_target_ulong);
-#endif
-
__thread uintptr_t tci_tb_ptr;
-static tcg_target_ulong tci_read_reg(const tcg_target_ulong *regs, TCGReg index)
-{
- tci_assert(index < TCG_TARGET_NB_REGS);
- return regs[index];
-}
-
static void
tci_write_reg(tcg_target_ulong *regs, TCGReg index, tcg_target_ulong value)
{
@@ -133,6 +112,7 @@ static tcg_target_ulong tci_read_label(const uint8_t **tb_ptr)
* I = immediate (tcg_target_ulong)
* l = label or pointer
* m = immediate (TCGMemOpIdx)
+ * n = immediate (call return length)
* r = register
* s = signed ldst offset
*/
@@ -153,6 +133,18 @@ static void tci_args_l(const uint8_t **tb_ptr, void **l0)
check_size(start, tb_ptr);
}
+static void tci_args_nll(const uint8_t **tb_ptr, uint8_t *n0,
+ void **l1, void **l2)
+{
+ const uint8_t *start = *tb_ptr;
+
+ *n0 = tci_read_b(tb_ptr);
+ *l1 = (void *)tci_read_label(tb_ptr);
+ *l2 = (void *)tci_read_label(tb_ptr);
+
+ check_size(start, tb_ptr);
+}
+
static void tci_args_rr(const uint8_t **tb_ptr,
TCGReg *r0, TCGReg *r1)
{
@@ -487,11 +479,13 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
{
const uint8_t *tb_ptr = v_tb_ptr;
tcg_target_ulong regs[TCG_TARGET_NB_REGS];
- long tcg_temps[CPU_TEMP_BUF_NLONGS];
- uintptr_t sp_value = (uintptr_t)(tcg_temps + CPU_TEMP_BUF_NLONGS);
+ uint64_t stack[(TCG_STATIC_CALL_ARGS_SIZE + TCG_STATIC_FRAME_SIZE)
+ / sizeof(uint64_t)];
+ void *call_slots[TCG_STATIC_CALL_ARGS_SIZE / sizeof(uint64_t)];
regs[TCG_AREG0] = (tcg_target_ulong)env;
- regs[TCG_REG_CALL_STACK] = sp_value;
+ regs[TCG_REG_CALL_STACK] = (uintptr_t)stack;
+ call_slots[0] = NULL;
tci_assert(tb_ptr);
for (;;) {
@@ -509,40 +503,58 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
#endif
TCGMemOpIdx oi;
int32_t ofs;
- void *ptr;
+ void *ptr, *cif;
/* Skip opcode and size entry. */
tb_ptr += 2;
switch (opc) {
case INDEX_op_call:
- tci_args_l(&tb_ptr, &ptr);
+ /*
+ * Set up the ffi_avalue array once, delayed until now
+ * because many TB's do not make any calls. In tcg_gen_callN,
+ * we arranged for every real argument to be "left-aligned"
+ * in each 64-bit slot.
+ */
+ if (unlikely(call_slots[0] == NULL)) {
+ for (int i = 0; i < ARRAY_SIZE(call_slots); ++i) {
+ call_slots[i] = &stack[i];
+ }
+ }
+
+ tci_args_nll(&tb_ptr, &len, &ptr, &cif);
+
+ /* Helper functions may need to access the "return address" */
tci_tb_ptr = (uintptr_t)tb_ptr;
-#if TCG_TARGET_REG_BITS == 32
- tmp64 = ((helper_function)ptr)(tci_read_reg(regs, TCG_REG_R0),
- tci_read_reg(regs, TCG_REG_R1),
- tci_read_reg(regs, TCG_REG_R2),
- tci_read_reg(regs, TCG_REG_R3),
- tci_read_reg(regs, TCG_REG_R4),
- tci_read_reg(regs, TCG_REG_R5),
- tci_read_reg(regs, TCG_REG_R6),
- tci_read_reg(regs, TCG_REG_R7),
- tci_read_reg(regs, TCG_REG_R8),
- tci_read_reg(regs, TCG_REG_R9),
- tci_read_reg(regs, TCG_REG_R10),
- tci_read_reg(regs, TCG_REG_R11));
- tci_write_reg(regs, TCG_REG_R0, tmp64);
- tci_write_reg(regs, TCG_REG_R1, tmp64 >> 32);
-#else
- tmp64 = ((helper_function)ptr)(tci_read_reg(regs, TCG_REG_R0),
- tci_read_reg(regs, TCG_REG_R1),
- tci_read_reg(regs, TCG_REG_R2),
- tci_read_reg(regs, TCG_REG_R3),
- tci_read_reg(regs, TCG_REG_R4),
- tci_read_reg(regs, TCG_REG_R5));
- tci_write_reg(regs, TCG_REG_R0, tmp64);
-#endif
+
+ ffi_call(cif, ptr, stack, call_slots);
+
+ /* Any result winds up "left-aligned" in the stack[0] slot. */
+ switch (len) {
+ case 0: /* void */
+ break;
+ case 1: /* uint32_t */
+ /*
+ * Note that libffi has an odd special case in that it will
+ * always widen an integral result to ffi_arg.
+ */
+ if (sizeof(ffi_arg) == 4) {
+ regs[TCG_REG_R0] = *(uint32_t *)stack;
+ break;
+ }
+ /* fall through */
+ case 2: /* uint64_t */
+ if (TCG_TARGET_REG_BITS == 32) {
+ tci_write_reg64(regs, TCG_REG_R1, TCG_REG_R0, stack[0]);
+ } else {
+ regs[TCG_REG_R0] = stack[0];
+ }
+ break;
+ default:
+ g_assert_not_reached();
+ }
break;
+
case INDEX_op_br:
tci_args_l(&tb_ptr, &ptr);
tb_ptr = ptr;
@@ -1119,7 +1131,7 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
TCGCond c;
TCGMemOpIdx oi;
uint8_t pos, len;
- void *ptr;
+ void *ptr, *cif;
const uint8_t *tb_ptr;
status = info->read_memory_func(addr, buf, 2, info);
@@ -1147,13 +1159,18 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
switch (op) {
case INDEX_op_br:
- case INDEX_op_call:
case INDEX_op_exit_tb:
case INDEX_op_goto_tb:
tci_args_l(&tb_ptr, &ptr);
info->fprintf_func(info->stream, "%-12s %p", op_name, ptr);
break;
+ case INDEX_op_call:
+ tci_args_nll(&tb_ptr, &len, &ptr, &cif);
+ info->fprintf_func(info->stream, "%-12s %d, %p, %p",
+ op_name, len, ptr, cif);
+ break;
+
case INDEX_op_brcond_i32:
case INDEX_op_brcond_i64:
tci_args_rrcl(&tb_ptr, &r0, &r1, &c, &ptr);
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
index 288e945465..9ab7916300 100644
--- a/tcg/tci/tcg-target.c.inc
+++ b/tcg/tci/tcg-target.c.inc
@@ -192,23 +192,8 @@ static const int tcg_target_reg_alloc_order[] = {
# error Fix needed, number of supported input arguments changed!
#endif
-static const int tcg_target_call_iarg_regs[] = {
- TCG_REG_R0,
- TCG_REG_R1,
- TCG_REG_R2,
- TCG_REG_R3,
- TCG_REG_R4,
- TCG_REG_R5,
-#if TCG_TARGET_REG_BITS == 32
- /* 32 bit hosts need 2 * MAX_OPC_PARAM_IARGS registers. */
- TCG_REG_R6,
- TCG_REG_R7,
- TCG_REG_R8,
- TCG_REG_R9,
- TCG_REG_R10,
- TCG_REG_R11,
-#endif
-};
+/* No call arguments via registers. All will be stored on the "stack". */
+static const int tcg_target_call_iarg_regs[] = { };
static const int tcg_target_call_oarg_regs[] = {
TCG_REG_R0,
@@ -292,8 +277,9 @@ static void tci_out_label(TCGContext *s, TCGLabel *label)
static void stack_bounds_check(TCGReg base, target_long offset)
{
if (base == TCG_REG_CALL_STACK) {
- tcg_debug_assert(offset < 0);
- tcg_debug_assert(offset >= -(CPU_TEMP_BUF_NLONGS * sizeof(long)));
+ tcg_debug_assert(offset >= 0);
+ tcg_debug_assert(offset < (TCG_STATIC_CALL_ARGS_SIZE +
+ TCG_STATIC_FRAME_SIZE));
}
}
@@ -593,11 +579,25 @@ static void tcg_out_movi(TCGContext *s, TCGType type,
}
}
-static inline void tcg_out_call(TCGContext *s, const tcg_insn_unit *arg)
+static void tcg_out_call(TCGContext *s, const tcg_insn_unit *func,
+ ffi_cif *cif)
{
uint8_t *old_code_ptr = s->code_ptr;
+ uint8_t which;
+
+ if (cif->rtype == &ffi_type_void) {
+ which = 0;
+ } else if (cif->rtype->size == 4) {
+ which = 1;
+ } else {
+ tcg_debug_assert(cif->rtype->size == 8);
+ which = 2;
+ }
tcg_out_op_t(s, INDEX_op_call);
- tcg_out_i(s, (uintptr_t)arg);
+ tcg_out8(s, which);
+ tcg_out_i(s, (uintptr_t)func);
+ tcg_out_i(s, (uintptr_t)cif);
+
old_code_ptr[1] = s->code_ptr - old_code_ptr;
}
@@ -824,11 +824,9 @@ static void tcg_target_init(TCGContext *s)
s->reserved_regs = 0;
tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
- /* We use negative offsets from "sp" so that we can distinguish
- stores that might pretend to be call arguments. */
- tcg_set_frame(s, TCG_REG_CALL_STACK,
- -CPU_TEMP_BUF_NLONGS * sizeof(long),
- CPU_TEMP_BUF_NLONGS * sizeof(long));
+ /* The call arguments come first, followed by the temp storage. */
+ tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE,
+ TCG_STATIC_FRAME_SIZE);
}
/* Generate global QEMU prologue and epilogue code. */
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 12/26] tcg/tci: Reserve r13 for a temporary
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (10 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 11/26] tcg/tci: Use ffi for calls Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-02 23:57 ` [PATCH v6 13/26] tcg/tci: Emit setcond before brcond Richard Henderson
` (15 subsequent siblings)
27 siblings, 0 replies; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
We're about to adjust the offset range on host memory ops,
and the format of branches. Both will require a temporary.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/tci/tcg-target.h | 1 +
tcg/tci/tcg-target.c.inc | 1 +
2 files changed, 2 insertions(+)
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index 4df10e2e83..1558a6e44e 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -155,6 +155,7 @@ typedef enum {
TCG_REG_R14,
TCG_REG_R15,
+ TCG_REG_TMP = TCG_REG_R13,
TCG_AREG0 = TCG_REG_R14,
TCG_REG_CALL_STACK = TCG_REG_R15,
} TCGReg;
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
index 9ab7916300..d80fec3488 100644
--- a/tcg/tci/tcg-target.c.inc
+++ b/tcg/tci/tcg-target.c.inc
@@ -822,6 +822,7 @@ static void tcg_target_init(TCGContext *s)
MAKE_64BIT_MASK(TCG_REG_R0, 64 / TCG_TARGET_REG_BITS);
s->reserved_regs = 0;
+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP);
tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
/* The call arguments come first, followed by the temp storage. */
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 13/26] tcg/tci: Emit setcond before brcond
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (11 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 12/26] tcg/tci: Reserve r13 for a temporary Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-02 23:57 ` [PATCH v6 14/26] tcg/tci: Remove tci_write_reg Richard Henderson
` (14 subsequent siblings)
27 siblings, 0 replies; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
The encoding planned for tci does not have enough room for
brcond2, with 4 registers and a condition as input as well
as the label. Resolve the condition into TCG_REG_TMP, and
relax brcond to one register plus a label, considering the
condition to always be reg != 0.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/tci.c | 68 ++++++++++------------------------------
tcg/tci/tcg-target.c.inc | 52 +++++++++++-------------------
2 files changed, 35 insertions(+), 85 deletions(-)
diff --git a/tcg/tci.c b/tcg/tci.c
index 743c12af67..5677c3544a 100644
--- a/tcg/tci.c
+++ b/tcg/tci.c
@@ -145,6 +145,16 @@ static void tci_args_nll(const uint8_t **tb_ptr, uint8_t *n0,
check_size(start, tb_ptr);
}
+static void tci_args_rl(const uint8_t **tb_ptr, TCGReg *r0, void **l1)
+{
+ const uint8_t *start = *tb_ptr;
+
+ *r0 = tci_read_r(tb_ptr);
+ *l1 = (void *)tci_read_label(tb_ptr);
+
+ check_size(start, tb_ptr);
+}
+
static void tci_args_rr(const uint8_t **tb_ptr,
TCGReg *r0, TCGReg *r1)
{
@@ -216,19 +226,6 @@ static void tci_args_rrs(const uint8_t **tb_ptr,
check_size(start, tb_ptr);
}
-static void tci_args_rrcl(const uint8_t **tb_ptr,
- TCGReg *r0, TCGReg *r1, TCGCond *c2, void **l3)
-{
- const uint8_t *start = *tb_ptr;
-
- *r0 = tci_read_r(tb_ptr);
- *r1 = tci_read_r(tb_ptr);
- *c2 = tci_read_b(tb_ptr);
- *l3 = (void *)tci_read_label(tb_ptr);
-
- check_size(start, tb_ptr);
-}
-
static void tci_args_rrrc(const uint8_t **tb_ptr,
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGCond *c3)
{
@@ -297,21 +294,6 @@ static void tci_args_rrrr(const uint8_t **tb_ptr,
check_size(start, tb_ptr);
}
-static void tci_args_rrrrcl(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
- TCGReg *r2, TCGReg *r3, TCGCond *c4, void **l5)
-{
- const uint8_t *start = *tb_ptr;
-
- *r0 = tci_read_r(tb_ptr);
- *r1 = tci_read_r(tb_ptr);
- *r2 = tci_read_r(tb_ptr);
- *r3 = tci_read_r(tb_ptr);
- *c4 = tci_read_b(tb_ptr);
- *l5 = (void *)tci_read_label(tb_ptr);
-
- check_size(start, tb_ptr);
-}
-
static void tci_args_rrrrrc(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGCond *c5)
{
@@ -707,8 +689,8 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
break;
#endif
case INDEX_op_brcond_i32:
- tci_args_rrcl(&tb_ptr, &r0, &r1, &condition, &ptr);
- if (tci_compare32(regs[r0], regs[r1], condition)) {
+ tci_args_rl(&tb_ptr, &r0, &ptr);
+ if ((uint32_t)regs[r0]) {
tb_ptr = ptr;
}
break;
@@ -725,15 +707,6 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
T2 = tci_uint64(regs[r5], regs[r4]);
tci_write_reg64(regs, r1, r0, T1 - T2);
break;
- case INDEX_op_brcond2_i32:
- tci_args_rrrrcl(&tb_ptr, &r0, &r1, &r2, &r3, &condition, &ptr);
- T1 = tci_uint64(regs[r1], regs[r0]);
- T2 = tci_uint64(regs[r3], regs[r2]);
- if (tci_compare64(T1, T2, condition)) {
- tb_ptr = ptr;
- continue;
- }
- break;
case INDEX_op_mulu2_i32:
tci_args_rrrr(&tb_ptr, &r0, &r1, &r2, &r3);
tci_write_reg64(regs, r1, r0, (uint64_t)regs[r2] * regs[r3]);
@@ -861,8 +834,8 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
break;
#endif
case INDEX_op_brcond_i64:
- tci_args_rrcl(&tb_ptr, &r0, &r1, &condition, &ptr);
- if (tci_compare64(regs[r0], regs[r1], condition)) {
+ tci_args_rl(&tb_ptr, &r0, &ptr);
+ if (regs[r0]) {
tb_ptr = ptr;
}
break;
@@ -1173,9 +1146,9 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
case INDEX_op_brcond_i32:
case INDEX_op_brcond_i64:
- tci_args_rrcl(&tb_ptr, &r0, &r1, &c, &ptr);
- info->fprintf_func(info->stream, "%-12s %s, %s, %s, %p",
- op_name, str_r(r0), str_r(r1), str_c(c), ptr);
+ tci_args_rl(&tb_ptr, &r0, &ptr);
+ info->fprintf_func(info->stream, "%-12s %s, 0, ne, %p",
+ op_name, str_r(r0), ptr);
break;
case INDEX_op_setcond_i32:
@@ -1300,13 +1273,6 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
str_r(r3), str_r(r4), str_c(c));
break;
- case INDEX_op_brcond2_i32:
- tci_args_rrrrcl(&tb_ptr, &r0, &r1, &r2, &r3, &c, &ptr);
- info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %p",
- op_name, str_r(r0), str_r(r1),
- str_r(r2), str_r(r3), str_c(c), ptr);
- break;
-
case INDEX_op_mulu2_i32:
tci_args_rrrr(&tb_ptr, &r0, &r1, &r2, &r3);
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
index d80fec3488..4841787e5f 100644
--- a/tcg/tci/tcg-target.c.inc
+++ b/tcg/tci/tcg-target.c.inc
@@ -337,6 +337,17 @@ static void tcg_out_op_rI(TCGContext *s, TCGOpcode op,
}
#endif
+static void tcg_out_op_rl(TCGContext *s, TCGOpcode op, TCGReg r0, TCGLabel *l1)
+{
+ uint8_t *old_code_ptr = s->code_ptr;
+
+ tcg_out_op_t(s, op);
+ tcg_out_r(s, r0);
+ tci_out_label(s, l1);
+
+ old_code_ptr[1] = s->code_ptr - old_code_ptr;
+}
+
static void tcg_out_op_rr(TCGContext *s, TCGOpcode op, TCGReg r0, TCGReg r1)
{
uint8_t *old_code_ptr = s->code_ptr;
@@ -388,20 +399,6 @@ static void tcg_out_op_rrs(TCGContext *s, TCGOpcode op,
old_code_ptr[1] = s->code_ptr - old_code_ptr;
}
-static void tcg_out_op_rrcl(TCGContext *s, TCGOpcode op,
- TCGReg r0, TCGReg r1, TCGCond c2, TCGLabel *l3)
-{
- uint8_t *old_code_ptr = s->code_ptr;
-
- tcg_out_op_t(s, op);
- tcg_out_r(s, r0);
- tcg_out_r(s, r1);
- tcg_out8(s, c2);
- tci_out_label(s, l3);
-
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
-}
-
static void tcg_out_op_rrrc(TCGContext *s, TCGOpcode op,
TCGReg r0, TCGReg r1, TCGReg r2, TCGCond c3)
{
@@ -475,23 +472,6 @@ static void tcg_out_op_rrrr(TCGContext *s, TCGOpcode op,
old_code_ptr[1] = s->code_ptr - old_code_ptr;
}
-static void tcg_out_op_rrrrcl(TCGContext *s, TCGOpcode op,
- TCGReg r0, TCGReg r1, TCGReg r2, TCGReg r3,
- TCGCond c4, TCGLabel *l5)
-{
- uint8_t *old_code_ptr = s->code_ptr;
-
- tcg_out_op_t(s, op);
- tcg_out_r(s, r0);
- tcg_out_r(s, r1);
- tcg_out_r(s, r2);
- tcg_out_r(s, r3);
- tcg_out8(s, c4);
- tci_out_label(s, l5);
-
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
-}
-
static void tcg_out_op_rrrrrc(TCGContext *s, TCGOpcode op,
TCGReg r0, TCGReg r1, TCGReg r2,
TCGReg r3, TCGReg r4, TCGCond c5)
@@ -697,7 +677,10 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
break;
CASE_32_64(brcond)
- tcg_out_op_rrcl(s, opc, args[0], args[1], args[2], arg_label(args[3]));
+ tcg_out_op_rrrc(s, (opc == INDEX_op_brcond_i32
+ ? INDEX_op_setcond_i32 : INDEX_op_setcond_i64),
+ TCG_REG_TMP, args[0], args[1], args[2]);
+ tcg_out_op_rl(s, opc, TCG_REG_TMP, arg_label(args[3]));
break;
CASE_32_64(neg) /* Optional (TCG_TARGET_HAS_neg_*). */
@@ -723,8 +706,9 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
args[3], args[4], args[5]);
break;
case INDEX_op_brcond2_i32:
- tcg_out_op_rrrrcl(s, opc, args[0], args[1], args[2],
- args[3], args[4], arg_label(args[5]));
+ tcg_out_op_rrrrrc(s, INDEX_op_setcond2_i32, TCG_REG_TMP,
+ args[0], args[1], args[2], args[3], args[4]);
+ tcg_out_op_rl(s, INDEX_op_brcond_i32, TCG_REG_TMP, arg_label(args[5]));
break;
case INDEX_op_mulu2_i32:
tcg_out_op_rrrr(s, opc, args[0], args[1], args[2], args[3]);
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 14/26] tcg/tci: Remove tci_write_reg
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (12 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 13/26] tcg/tci: Emit setcond before brcond Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-03 21:53 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 15/26] tcg/tci: Change encoding to uint32_t units Richard Henderson
` (13 subsequent siblings)
27 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
Inline it into its one caller, tci_write_reg64.
Drop the asserts that are redundant with tcg_read_r.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/tci.c | 13 ++-----------
1 file changed, 2 insertions(+), 11 deletions(-)
diff --git a/tcg/tci.c b/tcg/tci.c
index 5677c3544a..6900c3e891 100644
--- a/tcg/tci.c
+++ b/tcg/tci.c
@@ -36,20 +36,11 @@
__thread uintptr_t tci_tb_ptr;
-static void
-tci_write_reg(tcg_target_ulong *regs, TCGReg index, tcg_target_ulong value)
-{
- tci_assert(index < TCG_TARGET_NB_REGS);
- tci_assert(index != TCG_AREG0);
- tci_assert(index != TCG_REG_CALL_STACK);
- regs[index] = value;
-}
-
static void tci_write_reg64(tcg_target_ulong *regs, uint32_t high_index,
uint32_t low_index, uint64_t value)
{
- tci_write_reg(regs, low_index, value);
- tci_write_reg(regs, high_index, value >> 32);
+ regs[low_index] = value;
+ regs[high_index] = value >> 32;
}
/* Create a 64 bit value from two 32 bit values. */
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 15/26] tcg/tci: Change encoding to uint32_t units
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (13 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 14/26] tcg/tci: Remove tci_write_reg Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-02 23:57 ` [PATCH v6 16/26] tcg/tci: Implement goto_ptr Richard Henderson
` (12 subsequent siblings)
27 siblings, 0 replies; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i386, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label, which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/tcg/tcg-opc.h | 4 +-
tcg/tci/tcg-target.h | 3 +-
tcg/tci.c | 541 +++++++++++++++------------------------
tcg/tci/tcg-target.c.inc | 379 ++++++++++++---------------
tcg/tci/README | 20 +-
5 files changed, 384 insertions(+), 563 deletions(-)
diff --git a/include/tcg/tcg-opc.h b/include/tcg/tcg-opc.h
index bbb0884af8..5bbec858aa 100644
--- a/include/tcg/tcg-opc.h
+++ b/include/tcg/tcg-opc.h
@@ -277,8 +277,8 @@ DEF(last_generic, 0, 0, 0, TCG_OPF_NOT_PRESENT)
#ifdef TCG_TARGET_INTERPRETER
/* These opcodes are only for use between the tci generator and interpreter. */
-DEF(tci_movi_i32, 1, 0, 1, TCG_OPF_NOT_PRESENT)
-DEF(tci_movi_i64, 1, 0, 1, TCG_OPF_64BIT | TCG_OPF_NOT_PRESENT)
+DEF(tci_movi, 1, 0, 1, TCG_OPF_NOT_PRESENT)
+DEF(tci_movl, 1, 0, 1, TCG_OPF_NOT_PRESENT)
#endif
#undef TLADDR_ARGS
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index 1558a6e44e..d953f2ead3 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -41,7 +41,7 @@
#define TCG_TARGET_H
#define TCG_TARGET_INTERPRETER 1
-#define TCG_TARGET_INSN_UNIT_SIZE 1
+#define TCG_TARGET_INSN_UNIT_SIZE 4
#define TCG_TARGET_TLB_DISPLACEMENT_BITS 32
#if UINTPTR_MAX == UINT32_MAX
@@ -165,6 +165,7 @@ typedef enum {
#define TCG_TARGET_STACK_ALIGN 8
#define HAVE_TCG_QEMU_TB_EXEC
+#define TCG_TARGET_NEED_POOL_LABELS
/* We could notice __i386__ or __s390x__ and reduce the barriers depending
on the host. But if you want performance, you use the normal backend.
diff --git a/tcg/tci.c b/tcg/tci.c
index 6900c3e891..95f57c831f 100644
--- a/tcg/tci.c
+++ b/tcg/tci.c
@@ -49,49 +49,6 @@ static uint64_t tci_uint64(uint32_t high, uint32_t low)
return ((uint64_t)high << 32) + low;
}
-/* Read constant byte from bytecode. */
-static uint8_t tci_read_b(const uint8_t **tb_ptr)
-{
- return *(tb_ptr[0]++);
-}
-
-/* Read register number from bytecode. */
-static TCGReg tci_read_r(const uint8_t **tb_ptr)
-{
- uint8_t regno = tci_read_b(tb_ptr);
- tci_assert(regno < TCG_TARGET_NB_REGS);
- return regno;
-}
-
-/* Read constant (native size) from bytecode. */
-static tcg_target_ulong tci_read_i(const uint8_t **tb_ptr)
-{
- tcg_target_ulong value = *(const tcg_target_ulong *)(*tb_ptr);
- *tb_ptr += sizeof(value);
- return value;
-}
-
-/* Read unsigned constant (32 bit) from bytecode. */
-static uint32_t tci_read_i32(const uint8_t **tb_ptr)
-{
- uint32_t value = *(const uint32_t *)(*tb_ptr);
- *tb_ptr += sizeof(value);
- return value;
-}
-
-/* Read signed constant (32 bit) from bytecode. */
-static int32_t tci_read_s32(const uint8_t **tb_ptr)
-{
- int32_t value = *(const int32_t *)(*tb_ptr);
- *tb_ptr += sizeof(value);
- return value;
-}
-
-static tcg_target_ulong tci_read_label(const uint8_t **tb_ptr)
-{
- return tci_read_i(tb_ptr);
-}
-
/*
* Load sets of arguments all at once. The naming convention is:
* tci_args_<arguments>
@@ -108,211 +65,128 @@ static tcg_target_ulong tci_read_label(const uint8_t **tb_ptr)
* s = signed ldst offset
*/
-static void check_size(const uint8_t *start, const uint8_t **tb_ptr)
+static void tci_args_l(uint32_t insn, const void *tb_ptr, void **l0)
{
- const uint8_t *old_code_ptr = start - 2;
- uint8_t op_size = old_code_ptr[1];
- tci_assert(*tb_ptr == old_code_ptr + op_size);
+ int diff = sextract32(insn, 12, 20);
+ *l0 = diff ? (void *)tb_ptr + diff : NULL;
}
-static void tci_args_l(const uint8_t **tb_ptr, void **l0)
+static void tci_args_nl(uint32_t insn, const void *tb_ptr,
+ uint8_t *n0, void **l1)
{
- const uint8_t *start = *tb_ptr;
-
- *l0 = (void *)tci_read_label(tb_ptr);
-
- check_size(start, tb_ptr);
+ *n0 = extract32(insn, 8, 4);
+ *l1 = sextract32(insn, 12, 20) + (void *)tb_ptr;
}
-static void tci_args_nll(const uint8_t **tb_ptr, uint8_t *n0,
- void **l1, void **l2)
+static void tci_args_rl(uint32_t insn, const void *tb_ptr,
+ TCGReg *r0, void **l1)
{
- const uint8_t *start = *tb_ptr;
-
- *n0 = tci_read_b(tb_ptr);
- *l1 = (void *)tci_read_label(tb_ptr);
- *l2 = (void *)tci_read_label(tb_ptr);
-
- check_size(start, tb_ptr);
+ *r0 = extract32(insn, 8, 4);
+ *l1 = sextract32(insn, 12, 20) + (void *)tb_ptr;
}
-static void tci_args_rl(const uint8_t **tb_ptr, TCGReg *r0, void **l1)
+static void tci_args_rr(uint32_t insn, TCGReg *r0, TCGReg *r1)
{
- const uint8_t *start = *tb_ptr;
-
- *r0 = tci_read_r(tb_ptr);
- *l1 = (void *)tci_read_label(tb_ptr);
-
- check_size(start, tb_ptr);
+ *r0 = extract32(insn, 8, 4);
+ *r1 = extract32(insn, 12, 4);
}
-static void tci_args_rr(const uint8_t **tb_ptr,
- TCGReg *r0, TCGReg *r1)
+static void tci_args_ri(uint32_t insn, TCGReg *r0, tcg_target_ulong *i1)
{
- const uint8_t *start = *tb_ptr;
-
- *r0 = tci_read_r(tb_ptr);
- *r1 = tci_read_r(tb_ptr);
-
- check_size(start, tb_ptr);
+ *r0 = extract32(insn, 8, 4);
+ *i1 = sextract32(insn, 12, 20);
}
-static void tci_args_ri(const uint8_t **tb_ptr,
- TCGReg *r0, tcg_target_ulong *i1)
+static void tci_args_rrm(uint32_t insn, TCGReg *r0,
+ TCGReg *r1, TCGMemOpIdx *m2)
{
- const uint8_t *start = *tb_ptr;
-
- *r0 = tci_read_r(tb_ptr);
- *i1 = tci_read_i32(tb_ptr);
-
- check_size(start, tb_ptr);
+ *r0 = extract32(insn, 8, 4);
+ *r1 = extract32(insn, 12, 4);
+ *m2 = extract32(insn, 20, 12);
}
-#if TCG_TARGET_REG_BITS == 64
-static void tci_args_rI(const uint8_t **tb_ptr,
- TCGReg *r0, tcg_target_ulong *i1)
+static void tci_args_rrr(uint32_t insn, TCGReg *r0, TCGReg *r1, TCGReg *r2)
{
- const uint8_t *start = *tb_ptr;
-
- *r0 = tci_read_r(tb_ptr);
- *i1 = tci_read_i(tb_ptr);
-
- check_size(start, tb_ptr);
-}
-#endif
-
-static void tci_args_rrm(const uint8_t **tb_ptr,
- TCGReg *r0, TCGReg *r1, TCGMemOpIdx *m2)
-{
- const uint8_t *start = *tb_ptr;
-
- *r0 = tci_read_r(tb_ptr);
- *r1 = tci_read_r(tb_ptr);
- *m2 = tci_read_i32(tb_ptr);
-
- check_size(start, tb_ptr);
+ *r0 = extract32(insn, 8, 4);
+ *r1 = extract32(insn, 12, 4);
+ *r2 = extract32(insn, 16, 4);
}
-static void tci_args_rrr(const uint8_t **tb_ptr,
- TCGReg *r0, TCGReg *r1, TCGReg *r2)
+static void tci_args_rrs(uint32_t insn, TCGReg *r0, TCGReg *r1, int32_t *i2)
{
- const uint8_t *start = *tb_ptr;
-
- *r0 = tci_read_r(tb_ptr);
- *r1 = tci_read_r(tb_ptr);
- *r2 = tci_read_r(tb_ptr);
-
- check_size(start, tb_ptr);
+ *r0 = extract32(insn, 8, 4);
+ *r1 = extract32(insn, 12, 4);
+ *i2 = sextract32(insn, 16, 16);
}
-static void tci_args_rrs(const uint8_t **tb_ptr,
- TCGReg *r0, TCGReg *r1, int32_t *i2)
-{
- const uint8_t *start = *tb_ptr;
-
- *r0 = tci_read_r(tb_ptr);
- *r1 = tci_read_r(tb_ptr);
- *i2 = tci_read_s32(tb_ptr);
-
- check_size(start, tb_ptr);
-}
-
-static void tci_args_rrrc(const uint8_t **tb_ptr,
+static void tci_args_rrrc(uint32_t insn,
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGCond *c3)
{
- const uint8_t *start = *tb_ptr;
-
- *r0 = tci_read_r(tb_ptr);
- *r1 = tci_read_r(tb_ptr);
- *r2 = tci_read_r(tb_ptr);
- *c3 = tci_read_b(tb_ptr);
-
- check_size(start, tb_ptr);
+ *r0 = extract32(insn, 8, 4);
+ *r1 = extract32(insn, 12, 4);
+ *r2 = extract32(insn, 16, 4);
+ *c3 = extract32(insn, 20, 4);
}
-static void tci_args_rrrm(const uint8_t **tb_ptr,
+static void tci_args_rrrm(uint32_t insn,
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGMemOpIdx *m3)
{
- const uint8_t *start = *tb_ptr;
-
- *r0 = tci_read_r(tb_ptr);
- *r1 = tci_read_r(tb_ptr);
- *r2 = tci_read_r(tb_ptr);
- *m3 = tci_read_i32(tb_ptr);
-
- check_size(start, tb_ptr);
+ *r0 = extract32(insn, 8, 4);
+ *r1 = extract32(insn, 12, 4);
+ *r2 = extract32(insn, 16, 4);
+ *m3 = extract32(insn, 20, 12);
}
-static void tci_args_rrrbb(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
+static void tci_args_rrrbb(uint32_t insn, TCGReg *r0, TCGReg *r1,
TCGReg *r2, uint8_t *i3, uint8_t *i4)
{
- const uint8_t *start = *tb_ptr;
-
- *r0 = tci_read_r(tb_ptr);
- *r1 = tci_read_r(tb_ptr);
- *r2 = tci_read_r(tb_ptr);
- *i3 = tci_read_b(tb_ptr);
- *i4 = tci_read_b(tb_ptr);
-
- check_size(start, tb_ptr);
+ *r0 = extract32(insn, 8, 4);
+ *r1 = extract32(insn, 12, 4);
+ *r2 = extract32(insn, 16, 4);
+ *i3 = extract32(insn, 20, 6);
+ *i4 = extract32(insn, 26, 6);
}
-static void tci_args_rrrrm(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
- TCGReg *r2, TCGReg *r3, TCGMemOpIdx *m4)
+static void tci_args_rrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
+ TCGReg *r2, TCGReg *r3, TCGReg *r4)
{
- const uint8_t *start = *tb_ptr;
-
- *r0 = tci_read_r(tb_ptr);
- *r1 = tci_read_r(tb_ptr);
- *r2 = tci_read_r(tb_ptr);
- *r3 = tci_read_r(tb_ptr);
- *m4 = tci_read_i32(tb_ptr);
-
- check_size(start, tb_ptr);
+ *r0 = extract32(insn, 8, 4);
+ *r1 = extract32(insn, 12, 4);
+ *r2 = extract32(insn, 16, 4);
+ *r3 = extract32(insn, 20, 4);
+ *r4 = extract32(insn, 24, 4);
}
#if TCG_TARGET_REG_BITS == 32
-static void tci_args_rrrr(const uint8_t **tb_ptr,
+static void tci_args_rrrr(uint32_t insn,
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGReg *r3)
{
- const uint8_t *start = *tb_ptr;
-
- *r0 = tci_read_r(tb_ptr);
- *r1 = tci_read_r(tb_ptr);
- *r2 = tci_read_r(tb_ptr);
- *r3 = tci_read_r(tb_ptr);
-
- check_size(start, tb_ptr);
+ *r0 = extract32(insn, 8, 4);
+ *r1 = extract32(insn, 12, 4);
+ *r2 = extract32(insn, 16, 4);
+ *r3 = extract32(insn, 20, 4);
}
-static void tci_args_rrrrrc(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
+static void tci_args_rrrrrc(uint32_t insn, TCGReg *r0, TCGReg *r1,
TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGCond *c5)
{
- const uint8_t *start = *tb_ptr;
-
- *r0 = tci_read_r(tb_ptr);
- *r1 = tci_read_r(tb_ptr);
- *r2 = tci_read_r(tb_ptr);
- *r3 = tci_read_r(tb_ptr);
- *r4 = tci_read_r(tb_ptr);
- *c5 = tci_read_b(tb_ptr);
-
- check_size(start, tb_ptr);
+ *r0 = extract32(insn, 8, 4);
+ *r1 = extract32(insn, 12, 4);
+ *r2 = extract32(insn, 16, 4);
+ *r3 = extract32(insn, 20, 4);
+ *r4 = extract32(insn, 24, 4);
+ *c5 = extract32(insn, 28, 4);
}
-static void tci_args_rrrrrr(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
+static void tci_args_rrrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGReg *r5)
{
- const uint8_t *start = *tb_ptr;
-
- *r0 = tci_read_r(tb_ptr);
- *r1 = tci_read_r(tb_ptr);
- *r2 = tci_read_r(tb_ptr);
- *r3 = tci_read_r(tb_ptr);
- *r4 = tci_read_r(tb_ptr);
- *r5 = tci_read_r(tb_ptr);
-
- check_size(start, tb_ptr);
+ *r0 = extract32(insn, 8, 4);
+ *r1 = extract32(insn, 12, 4);
+ *r2 = extract32(insn, 16, 4);
+ *r3 = extract32(insn, 20, 4);
+ *r4 = extract32(insn, 24, 4);
+ *r5 = extract32(insn, 28, 4);
}
#endif
@@ -450,7 +324,7 @@ static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
const void *v_tb_ptr)
{
- const uint8_t *tb_ptr = v_tb_ptr;
+ const uint32_t *tb_ptr = v_tb_ptr;
tcg_target_ulong regs[TCG_TARGET_NB_REGS];
uint64_t stack[(TCG_STATIC_CALL_ARGS_SIZE + TCG_STATIC_FRAME_SIZE)
/ sizeof(uint64_t)];
@@ -462,8 +336,9 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
tci_assert(tb_ptr);
for (;;) {
- TCGOpcode opc = tb_ptr[0];
- TCGReg r0, r1, r2, r3;
+ uint32_t insn;
+ TCGOpcode opc;
+ TCGReg r0, r1, r2, r3, r4;
tcg_target_ulong t1;
TCGCond condition;
target_ulong taddr;
@@ -471,15 +346,15 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
uint32_t tmp32;
uint64_t tmp64;
#if TCG_TARGET_REG_BITS == 32
- TCGReg r4, r5;
+ TCGReg r5;
uint64_t T1, T2;
#endif
TCGMemOpIdx oi;
int32_t ofs;
- void *ptr, *cif;
+ void *ptr;
- /* Skip opcode and size entry. */
- tb_ptr += 2;
+ insn = *tb_ptr++;
+ opc = extract32(insn, 0, 8);
switch (opc) {
case INDEX_op_call:
@@ -495,12 +370,15 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
}
}
- tci_args_nll(&tb_ptr, &len, &ptr, &cif);
+ tci_args_nl(insn, tb_ptr, &len, &ptr);
/* Helper functions may need to access the "return address" */
tci_tb_ptr = (uintptr_t)tb_ptr;
- ffi_call(cif, ptr, stack, call_slots);
+ {
+ void **pptr = ptr;
+ ffi_call(pptr[1], pptr[0], stack, call_slots);
+ }
/* Any result winds up "left-aligned" in the stack[0] slot. */
switch (len) {
@@ -529,76 +407,80 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
break;
case INDEX_op_br:
- tci_args_l(&tb_ptr, &ptr);
+ tci_args_l(insn, tb_ptr, &ptr);
tb_ptr = ptr;
continue;
case INDEX_op_setcond_i32:
- tci_args_rrrc(&tb_ptr, &r0, &r1, &r2, &condition);
+ tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
regs[r0] = tci_compare32(regs[r1], regs[r2], condition);
break;
#if TCG_TARGET_REG_BITS == 32
case INDEX_op_setcond2_i32:
- tci_args_rrrrrc(&tb_ptr, &r0, &r1, &r2, &r3, &r4, &condition);
+ tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
T1 = tci_uint64(regs[r2], regs[r1]);
T2 = tci_uint64(regs[r4], regs[r3]);
regs[r0] = tci_compare64(T1, T2, condition);
break;
#elif TCG_TARGET_REG_BITS == 64
case INDEX_op_setcond_i64:
- tci_args_rrrc(&tb_ptr, &r0, &r1, &r2, &condition);
+ tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
regs[r0] = tci_compare64(regs[r1], regs[r2], condition);
break;
#endif
CASE_32_64(mov)
- tci_args_rr(&tb_ptr, &r0, &r1);
+ tci_args_rr(insn, &r0, &r1);
regs[r0] = regs[r1];
break;
- case INDEX_op_tci_movi_i32:
- tci_args_ri(&tb_ptr, &r0, &t1);
+ case INDEX_op_tci_movi:
+ tci_args_ri(insn, &r0, &t1);
regs[r0] = t1;
break;
+ case INDEX_op_tci_movl:
+ tci_args_rl(insn, tb_ptr, &r0, &ptr);
+ regs[r0] = *(tcg_target_ulong *)ptr;
+ break;
/* Load/store operations (32 bit). */
CASE_32_64(ld8u)
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ tci_args_rrs(insn, &r0, &r1, &ofs);
ptr = (void *)(regs[r1] + ofs);
regs[r0] = *(uint8_t *)ptr;
break;
CASE_32_64(ld8s)
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ tci_args_rrs(insn, &r0, &r1, &ofs);
ptr = (void *)(regs[r1] + ofs);
regs[r0] = *(int8_t *)ptr;
break;
CASE_32_64(ld16u)
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ tci_args_rrs(insn, &r0, &r1, &ofs);
ptr = (void *)(regs[r1] + ofs);
regs[r0] = *(uint16_t *)ptr;
break;
CASE_32_64(ld16s)
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ tci_args_rrs(insn, &r0, &r1, &ofs);
ptr = (void *)(regs[r1] + ofs);
regs[r0] = *(int16_t *)ptr;
break;
case INDEX_op_ld_i32:
CASE_64(ld32u)
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ tci_args_rrs(insn, &r0, &r1, &ofs);
ptr = (void *)(regs[r1] + ofs);
regs[r0] = *(uint32_t *)ptr;
break;
CASE_32_64(st8)
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ tci_args_rrs(insn, &r0, &r1, &ofs);
ptr = (void *)(regs[r1] + ofs);
*(uint8_t *)ptr = regs[r0];
break;
CASE_32_64(st16)
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ tci_args_rrs(insn, &r0, &r1, &ofs);
ptr = (void *)(regs[r1] + ofs);
*(uint16_t *)ptr = regs[r0];
break;
case INDEX_op_st_i32:
CASE_64(st32)
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ tci_args_rrs(insn, &r0, &r1, &ofs);
ptr = (void *)(regs[r1] + ofs);
*(uint32_t *)ptr = regs[r0];
break;
@@ -606,171 +488,166 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
/* Arithmetic operations (mixed 32/64 bit). */
CASE_32_64(add)
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = regs[r1] + regs[r2];
break;
CASE_32_64(sub)
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = regs[r1] - regs[r2];
break;
CASE_32_64(mul)
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = regs[r1] * regs[r2];
break;
CASE_32_64(and)
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = regs[r1] & regs[r2];
break;
CASE_32_64(or)
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = regs[r1] | regs[r2];
break;
CASE_32_64(xor)
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = regs[r1] ^ regs[r2];
break;
/* Arithmetic operations (32 bit). */
case INDEX_op_div_i32:
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = (int32_t)regs[r1] / (int32_t)regs[r2];
break;
case INDEX_op_divu_i32:
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = (uint32_t)regs[r1] / (uint32_t)regs[r2];
break;
case INDEX_op_rem_i32:
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = (int32_t)regs[r1] % (int32_t)regs[r2];
break;
case INDEX_op_remu_i32:
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = (uint32_t)regs[r1] % (uint32_t)regs[r2];
break;
/* Shift/rotate operations (32 bit). */
case INDEX_op_shl_i32:
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = (uint32_t)regs[r1] << (regs[r2] & 31);
break;
case INDEX_op_shr_i32:
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = (uint32_t)regs[r1] >> (regs[r2] & 31);
break;
case INDEX_op_sar_i32:
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = (int32_t)regs[r1] >> (regs[r2] & 31);
break;
#if TCG_TARGET_HAS_rot_i32
case INDEX_op_rotl_i32:
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = rol32(regs[r1], regs[r2] & 31);
break;
case INDEX_op_rotr_i32:
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = ror32(regs[r1], regs[r2] & 31);
break;
#endif
#if TCG_TARGET_HAS_deposit_i32
case INDEX_op_deposit_i32:
- tci_args_rrrbb(&tb_ptr, &r0, &r1, &r2, &pos, &len);
+ tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
regs[r0] = deposit32(regs[r1], pos, len, regs[r2]);
break;
#endif
case INDEX_op_brcond_i32:
- tci_args_rl(&tb_ptr, &r0, &ptr);
+ tci_args_rl(insn, tb_ptr, &r0, &ptr);
if ((uint32_t)regs[r0]) {
tb_ptr = ptr;
}
break;
#if TCG_TARGET_REG_BITS == 32
case INDEX_op_add2_i32:
- tci_args_rrrrrr(&tb_ptr, &r0, &r1, &r2, &r3, &r4, &r5);
+ tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
T1 = tci_uint64(regs[r3], regs[r2]);
T2 = tci_uint64(regs[r5], regs[r4]);
tci_write_reg64(regs, r1, r0, T1 + T2);
break;
case INDEX_op_sub2_i32:
- tci_args_rrrrrr(&tb_ptr, &r0, &r1, &r2, &r3, &r4, &r5);
+ tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
T1 = tci_uint64(regs[r3], regs[r2]);
T2 = tci_uint64(regs[r5], regs[r4]);
tci_write_reg64(regs, r1, r0, T1 - T2);
break;
case INDEX_op_mulu2_i32:
- tci_args_rrrr(&tb_ptr, &r0, &r1, &r2, &r3);
+ tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
tci_write_reg64(regs, r1, r0, (uint64_t)regs[r2] * regs[r3]);
break;
#endif /* TCG_TARGET_REG_BITS == 32 */
#if TCG_TARGET_HAS_ext8s_i32 || TCG_TARGET_HAS_ext8s_i64
CASE_32_64(ext8s)
- tci_args_rr(&tb_ptr, &r0, &r1);
+ tci_args_rr(insn, &r0, &r1);
regs[r0] = (int8_t)regs[r1];
break;
#endif
#if TCG_TARGET_HAS_ext16s_i32 || TCG_TARGET_HAS_ext16s_i64
CASE_32_64(ext16s)
- tci_args_rr(&tb_ptr, &r0, &r1);
+ tci_args_rr(insn, &r0, &r1);
regs[r0] = (int16_t)regs[r1];
break;
#endif
#if TCG_TARGET_HAS_ext8u_i32 || TCG_TARGET_HAS_ext8u_i64
CASE_32_64(ext8u)
- tci_args_rr(&tb_ptr, &r0, &r1);
+ tci_args_rr(insn, &r0, &r1);
regs[r0] = (uint8_t)regs[r1];
break;
#endif
#if TCG_TARGET_HAS_ext16u_i32 || TCG_TARGET_HAS_ext16u_i64
CASE_32_64(ext16u)
- tci_args_rr(&tb_ptr, &r0, &r1);
+ tci_args_rr(insn, &r0, &r1);
regs[r0] = (uint16_t)regs[r1];
break;
#endif
#if TCG_TARGET_HAS_bswap16_i32 || TCG_TARGET_HAS_bswap16_i64
CASE_32_64(bswap16)
- tci_args_rr(&tb_ptr, &r0, &r1);
+ tci_args_rr(insn, &r0, &r1);
regs[r0] = bswap16(regs[r1]);
break;
#endif
#if TCG_TARGET_HAS_bswap32_i32 || TCG_TARGET_HAS_bswap32_i64
CASE_32_64(bswap32)
- tci_args_rr(&tb_ptr, &r0, &r1);
+ tci_args_rr(insn, &r0, &r1);
regs[r0] = bswap32(regs[r1]);
break;
#endif
#if TCG_TARGET_HAS_not_i32 || TCG_TARGET_HAS_not_i64
CASE_32_64(not)
- tci_args_rr(&tb_ptr, &r0, &r1);
+ tci_args_rr(insn, &r0, &r1);
regs[r0] = ~regs[r1];
break;
#endif
#if TCG_TARGET_HAS_neg_i32 || TCG_TARGET_HAS_neg_i64
CASE_32_64(neg)
- tci_args_rr(&tb_ptr, &r0, &r1);
+ tci_args_rr(insn, &r0, &r1);
regs[r0] = -regs[r1];
break;
#endif
#if TCG_TARGET_REG_BITS == 64
- case INDEX_op_tci_movi_i64:
- tci_args_rI(&tb_ptr, &r0, &t1);
- regs[r0] = t1;
- break;
-
/* Load/store operations (64 bit). */
case INDEX_op_ld32s_i64:
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ tci_args_rrs(insn, &r0, &r1, &ofs);
ptr = (void *)(regs[r1] + ofs);
regs[r0] = *(int32_t *)ptr;
break;
case INDEX_op_ld_i64:
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ tci_args_rrs(insn, &r0, &r1, &ofs);
ptr = (void *)(regs[r1] + ofs);
regs[r0] = *(uint64_t *)ptr;
break;
case INDEX_op_st_i64:
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
+ tci_args_rrs(insn, &r0, &r1, &ofs);
ptr = (void *)(regs[r1] + ofs);
*(uint64_t *)ptr = regs[r0];
break;
@@ -778,71 +655,71 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
/* Arithmetic operations (64 bit). */
case INDEX_op_div_i64:
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = (int64_t)regs[r1] / (int64_t)regs[r2];
break;
case INDEX_op_divu_i64:
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = (uint64_t)regs[r1] / (uint64_t)regs[r2];
break;
case INDEX_op_rem_i64:
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = (int64_t)regs[r1] % (int64_t)regs[r2];
break;
case INDEX_op_remu_i64:
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = (uint64_t)regs[r1] % (uint64_t)regs[r2];
break;
/* Shift/rotate operations (64 bit). */
case INDEX_op_shl_i64:
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = regs[r1] << (regs[r2] & 63);
break;
case INDEX_op_shr_i64:
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = regs[r1] >> (regs[r2] & 63);
break;
case INDEX_op_sar_i64:
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = (int64_t)regs[r1] >> (regs[r2] & 63);
break;
#if TCG_TARGET_HAS_rot_i64
case INDEX_op_rotl_i64:
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = rol64(regs[r1], regs[r2] & 63);
break;
case INDEX_op_rotr_i64:
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = ror64(regs[r1], regs[r2] & 63);
break;
#endif
#if TCG_TARGET_HAS_deposit_i64
case INDEX_op_deposit_i64:
- tci_args_rrrbb(&tb_ptr, &r0, &r1, &r2, &pos, &len);
+ tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
regs[r0] = deposit64(regs[r1], pos, len, regs[r2]);
break;
#endif
case INDEX_op_brcond_i64:
- tci_args_rl(&tb_ptr, &r0, &ptr);
+ tci_args_rl(insn, tb_ptr, &r0, &ptr);
if (regs[r0]) {
tb_ptr = ptr;
}
break;
case INDEX_op_ext32s_i64:
case INDEX_op_ext_i32_i64:
- tci_args_rr(&tb_ptr, &r0, &r1);
+ tci_args_rr(insn, &r0, &r1);
regs[r0] = (int32_t)regs[r1];
break;
case INDEX_op_ext32u_i64:
case INDEX_op_extu_i32_i64:
- tci_args_rr(&tb_ptr, &r0, &r1);
+ tci_args_rr(insn, &r0, &r1);
regs[r0] = (uint32_t)regs[r1];
break;
#if TCG_TARGET_HAS_bswap64_i64
case INDEX_op_bswap64_i64:
- tci_args_rr(&tb_ptr, &r0, &r1);
+ tci_args_rr(insn, &r0, &r1);
regs[r0] = bswap64(regs[r1]);
break;
#endif
@@ -851,20 +728,20 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
/* QEMU specific operations. */
case INDEX_op_exit_tb:
- tci_args_l(&tb_ptr, &ptr);
+ tci_args_l(insn, tb_ptr, &ptr);
return (uintptr_t)ptr;
case INDEX_op_goto_tb:
- tci_args_l(&tb_ptr, &ptr);
+ tci_args_l(insn, tb_ptr, &ptr);
tb_ptr = *(void **)ptr;
break;
case INDEX_op_qemu_ld_i32:
if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
- tci_args_rrm(&tb_ptr, &r0, &r1, &oi);
+ tci_args_rrm(insn, &r0, &r1, &oi);
taddr = regs[r1];
} else {
- tci_args_rrrm(&tb_ptr, &r0, &r1, &r2, &oi);
+ tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
taddr = tci_uint64(regs[r2], regs[r1]);
}
switch (get_memop(oi) & (MO_BSWAP | MO_SSIZE)) {
@@ -900,14 +777,15 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
case INDEX_op_qemu_ld_i64:
if (TCG_TARGET_REG_BITS == 64) {
- tci_args_rrm(&tb_ptr, &r0, &r1, &oi);
+ tci_args_rrm(insn, &r0, &r1, &oi);
taddr = regs[r1];
} else if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
- tci_args_rrrm(&tb_ptr, &r0, &r1, &r2, &oi);
+ tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
taddr = regs[r2];
} else {
- tci_args_rrrrm(&tb_ptr, &r0, &r1, &r2, &r3, &oi);
+ tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
taddr = tci_uint64(regs[r3], regs[r2]);
+ oi = regs[r4];
}
switch (get_memop(oi) & (MO_BSWAP | MO_SSIZE)) {
case MO_UB:
@@ -958,10 +836,10 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
case INDEX_op_qemu_st_i32:
if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
- tci_args_rrm(&tb_ptr, &r0, &r1, &oi);
+ tci_args_rrm(insn, &r0, &r1, &oi);
taddr = regs[r1];
} else {
- tci_args_rrrm(&tb_ptr, &r0, &r1, &r2, &oi);
+ tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
taddr = tci_uint64(regs[r2], regs[r1]);
}
tmp32 = regs[r0];
@@ -988,16 +866,17 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
case INDEX_op_qemu_st_i64:
if (TCG_TARGET_REG_BITS == 64) {
- tci_args_rrm(&tb_ptr, &r0, &r1, &oi);
+ tci_args_rrm(insn, &r0, &r1, &oi);
taddr = regs[r1];
tmp64 = regs[r0];
} else {
if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
- tci_args_rrrm(&tb_ptr, &r0, &r1, &r2, &oi);
+ tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
taddr = regs[r2];
} else {
- tci_args_rrrrm(&tb_ptr, &r0, &r1, &r2, &r3, &oi);
+ tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
taddr = tci_uint64(regs[r3], regs[r2]);
+ oi = regs[r4];
}
tmp64 = tci_uint64(regs[r1], regs[r0]);
}
@@ -1081,87 +960,69 @@ static const char *str_c(TCGCond c)
/* Disassemble TCI bytecode. */
int print_insn_tci(bfd_vma addr, disassemble_info *info)
{
- uint8_t buf[256];
- int length, status;
+ const uint32_t *tb_ptr = (const void *)(uintptr_t)addr;
const TCGOpDef *def;
const char *op_name;
+ uint32_t insn;
TCGOpcode op;
- TCGReg r0, r1, r2, r3;
+ TCGReg r0, r1, r2, r3, r4;
#if TCG_TARGET_REG_BITS == 32
- TCGReg r4, r5;
+ TCGReg r5;
#endif
tcg_target_ulong i1;
int32_t s2;
TCGCond c;
TCGMemOpIdx oi;
uint8_t pos, len;
- void *ptr, *cif;
- const uint8_t *tb_ptr;
+ void *ptr;
- status = info->read_memory_func(addr, buf, 2, info);
- if (status != 0) {
- info->memory_error_func(status, addr, info);
- return -1;
- }
- op = buf[0];
- length = buf[1];
+ /* TCI is always the host, so we don't need to load indirect. */
+ insn = *tb_ptr++;
- if (length < 2) {
- info->fprintf_func(info->stream, "invalid length %d", length);
- return 1;
- }
-
- status = info->read_memory_func(addr + 2, buf + 2, length - 2, info);
- if (status != 0) {
- info->memory_error_func(status, addr + 2, info);
- return -1;
- }
+ info->fprintf_func(info->stream, "%08x ", insn);
+ op = extract32(insn, 0, 8);
def = &tcg_op_defs[op];
op_name = def->name;
- tb_ptr = buf + 2;
switch (op) {
case INDEX_op_br:
case INDEX_op_exit_tb:
case INDEX_op_goto_tb:
- tci_args_l(&tb_ptr, &ptr);
+ tci_args_l(insn, tb_ptr, &ptr);
info->fprintf_func(info->stream, "%-12s %p", op_name, ptr);
break;
case INDEX_op_call:
- tci_args_nll(&tb_ptr, &len, &ptr, &cif);
- info->fprintf_func(info->stream, "%-12s %d, %p, %p",
- op_name, len, ptr, cif);
+ tci_args_nl(insn, tb_ptr, &len, &ptr);
+ info->fprintf_func(info->stream, "%-12s %d, %p", op_name, len, ptr);
break;
case INDEX_op_brcond_i32:
case INDEX_op_brcond_i64:
- tci_args_rl(&tb_ptr, &r0, &ptr);
+ tci_args_rl(insn, tb_ptr, &r0, &ptr);
info->fprintf_func(info->stream, "%-12s %s, 0, ne, %p",
op_name, str_r(r0), ptr);
break;
case INDEX_op_setcond_i32:
case INDEX_op_setcond_i64:
- tci_args_rrrc(&tb_ptr, &r0, &r1, &r2, &c);
+ tci_args_rrrc(insn, &r0, &r1, &r2, &c);
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
op_name, str_r(r0), str_r(r1), str_r(r2), str_c(c));
break;
- case INDEX_op_tci_movi_i32:
- tci_args_ri(&tb_ptr, &r0, &i1);
- info->fprintf_func(info->stream, "%-12s %s, 0x%" TCG_PRIlx,
+ case INDEX_op_tci_movi:
+ tci_args_ri(insn, &r0, &i1);
+ info->fprintf_func(info->stream, "%-12s %s,0x%" TCG_PRIlx "",
op_name, str_r(r0), i1);
break;
-#if TCG_TARGET_REG_BITS == 64
- case INDEX_op_tci_movi_i64:
- tci_args_rI(&tb_ptr, &r0, &i1);
- info->fprintf_func(info->stream, "%-12s %s, 0x%" TCG_PRIlx,
- op_name, str_r(r0), i1);
+ case INDEX_op_tci_movl:
+ tci_args_rl(insn, tb_ptr, &r0, &ptr);
+ info->fprintf_func(info->stream, "%-12s %s, %p",
+ op_name, str_r(r0), ptr);
break;
-#endif
case INDEX_op_ld8u_i32:
case INDEX_op_ld8u_i64:
@@ -1182,7 +1043,7 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
case INDEX_op_st32_i64:
case INDEX_op_st_i32:
case INDEX_op_st_i64:
- tci_args_rrs(&tb_ptr, &r0, &r1, &s2);
+ tci_args_rrs(insn, &r0, &r1, &s2);
info->fprintf_func(info->stream, "%-12s %s, %s, %d",
op_name, str_r(r0), str_r(r1), s2);
break;
@@ -1209,7 +1070,7 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
case INDEX_op_not_i64:
case INDEX_op_neg_i32:
case INDEX_op_neg_i64:
- tci_args_rr(&tb_ptr, &r0, &r1);
+ tci_args_rr(insn, &r0, &r1);
info->fprintf_func(info->stream, "%-12s %s, %s",
op_name, str_r(r0), str_r(r1));
break;
@@ -1244,28 +1105,28 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
case INDEX_op_rotl_i64:
case INDEX_op_rotr_i32:
case INDEX_op_rotr_i64:
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
+ tci_args_rrr(insn, &r0, &r1, &r2);
info->fprintf_func(info->stream, "%-12s %s, %s, %s",
op_name, str_r(r0), str_r(r1), str_r(r2));
break;
case INDEX_op_deposit_i32:
case INDEX_op_deposit_i64:
- tci_args_rrrbb(&tb_ptr, &r0, &r1, &r2, &pos, &len);
+ tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %d, %d",
op_name, str_r(r0), str_r(r1), str_r(r2), pos, len);
break;
#if TCG_TARGET_REG_BITS == 32
case INDEX_op_setcond2_i32:
- tci_args_rrrrrc(&tb_ptr, &r0, &r1, &r2, &r3, &r4, &c);
+ tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &c);
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %s",
op_name, str_r(r0), str_r(r1), str_r(r2),
str_r(r3), str_r(r4), str_c(c));
break;
case INDEX_op_mulu2_i32:
- tci_args_rrrr(&tb_ptr, &r0, &r1, &r2, &r3);
+ tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
op_name, str_r(r0), str_r(r1),
str_r(r2), str_r(r3));
@@ -1273,7 +1134,7 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
case INDEX_op_add2_i32:
case INDEX_op_sub2_i32:
- tci_args_rrrrrr(&tb_ptr, &r0, &r1, &r2, &r3, &r4, &r5);
+ tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %s",
op_name, str_r(r0), str_r(r1), str_r(r2),
str_r(r3), str_r(r4), str_r(r5));
@@ -1291,30 +1152,38 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
len += DIV_ROUND_UP(TARGET_LONG_BITS, TCG_TARGET_REG_BITS);
switch (len) {
case 2:
- tci_args_rrm(&tb_ptr, &r0, &r1, &oi);
+ tci_args_rrm(insn, &r0, &r1, &oi);
info->fprintf_func(info->stream, "%-12s %s, %s, %x",
op_name, str_r(r0), str_r(r1), oi);
break;
case 3:
- tci_args_rrrm(&tb_ptr, &r0, &r1, &r2, &oi);
+ tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %x",
op_name, str_r(r0), str_r(r1), str_r(r2), oi);
break;
case 4:
- tci_args_rrrrm(&tb_ptr, &r0, &r1, &r2, &r3, &oi);
- info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %x",
+ tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
+ info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s",
op_name, str_r(r0), str_r(r1),
- str_r(r2), str_r(r3), oi);
+ str_r(r2), str_r(r3), str_r(r4));
break;
default:
g_assert_not_reached();
}
break;
+ case 0:
+ /* tcg_out_nop_fill uses zeros */
+ if (insn == 0) {
+ info->fprintf_func(info->stream, "align");
+ break;
+ }
+ /* fall through */
+
default:
info->fprintf_func(info->stream, "illegal opcode %d", op);
break;
}
- return length;
+ return sizeof(insn);
}
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
index 4841787e5f..acb5f6c75e 100644
--- a/tcg/tci/tcg-target.c.inc
+++ b/tcg/tci/tcg-target.c.inc
@@ -22,20 +22,7 @@
* THE SOFTWARE.
*/
-/* TODO list:
- * - See TODO comments in code.
- */
-
-/* Marker for missing code. */
-#define TODO() \
- do { \
- fprintf(stderr, "TODO %s:%u: %s()\n", \
- __FILE__, __LINE__, __func__); \
- tcg_abort(); \
- } while (0)
-
-/* Bitfield n...m (in 32 bit value). */
-#define BITS(n, m) (((0xffffffffU << (31 - n)) >> (31 - n + m)) << m)
+#include "../tcg-pool.c.inc"
static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
{
@@ -226,52 +213,16 @@ static const char *const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
intptr_t value, intptr_t addend)
{
- /* tcg_out_reloc always uses the same type, addend. */
- tcg_debug_assert(type == sizeof(tcg_target_long));
+ intptr_t diff = value - (intptr_t)(code_ptr + 1);
+
tcg_debug_assert(addend == 0);
- tcg_debug_assert(value != 0);
- if (TCG_TARGET_REG_BITS == 32) {
- tcg_patch32(code_ptr, value);
- } else {
- tcg_patch64(code_ptr, value);
- }
- return true;
-}
-
-/* Write value (native size). */
-static void tcg_out_i(TCGContext *s, tcg_target_ulong v)
-{
- if (TCG_TARGET_REG_BITS == 32) {
- tcg_out32(s, v);
- } else {
- tcg_out64(s, v);
- }
-}
-
-/* Write opcode. */
-static void tcg_out_op_t(TCGContext *s, TCGOpcode op)
-{
- tcg_out8(s, op);
- tcg_out8(s, 0);
-}
-
-/* Write register. */
-static void tcg_out_r(TCGContext *s, TCGArg t0)
-{
- tcg_debug_assert(t0 < TCG_TARGET_NB_REGS);
- tcg_out8(s, t0);
-}
-
-/* Write label. */
-static void tci_out_label(TCGContext *s, TCGLabel *label)
-{
- if (label->has_value) {
- tcg_out_i(s, label->u.value);
- tcg_debug_assert(label->u.value);
- } else {
- tcg_out_reloc(s, s->code_ptr, sizeof(tcg_target_ulong), label, 0);
- s->code_ptr += sizeof(tcg_target_ulong);
+ tcg_debug_assert(type == 20);
+
+ if (diff == sextract32(diff, 0, type)) {
+ tcg_patch32(code_ptr, deposit32(*code_ptr, 32 - type, type, diff));
+ return true;
}
+ return false;
}
static void stack_bounds_check(TCGReg base, target_long offset)
@@ -285,239 +236,236 @@ static void stack_bounds_check(TCGReg base, target_long offset)
static void tcg_out_op_l(TCGContext *s, TCGOpcode op, TCGLabel *l0)
{
- uint8_t *old_code_ptr = s->code_ptr;
+ tcg_insn_unit insn = 0;
- tcg_out_op_t(s, op);
- tci_out_label(s, l0);
-
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
+ tcg_out_reloc(s, s->code_ptr, 20, l0, 0);
+ insn = deposit32(insn, 0, 8, op);
+ tcg_out32(s, insn);
}
static void tcg_out_op_p(TCGContext *s, TCGOpcode op, void *p0)
{
- uint8_t *old_code_ptr = s->code_ptr;
+ tcg_insn_unit insn = 0;
+ intptr_t diff;
- tcg_out_op_t(s, op);
- tcg_out_i(s, (uintptr_t)p0);
-
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
+ /* Special case for exit_tb: map null -> 0. */
+ if (p0 == NULL) {
+ diff = 0;
+ } else {
+ diff = p0 - (void *)(s->code_ptr + 1);
+ tcg_debug_assert(diff != 0);
+ if (diff != sextract32(diff, 0, 20)) {
+ tcg_raise_tb_overflow(s);
+ }
+ }
+ insn = deposit32(insn, 0, 8, op);
+ insn = deposit32(insn, 12, 20, diff);
+ tcg_out32(s, insn);
}
static void tcg_out_op_v(TCGContext *s, TCGOpcode op)
{
- uint8_t *old_code_ptr = s->code_ptr;
-
- tcg_out_op_t(s, op);
-
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
+ tcg_out32(s, (uint8_t)op);
}
static void tcg_out_op_ri(TCGContext *s, TCGOpcode op, TCGReg r0, int32_t i1)
{
- uint8_t *old_code_ptr = s->code_ptr;
+ tcg_insn_unit insn = 0;
- tcg_out_op_t(s, op);
- tcg_out_r(s, r0);
- tcg_out32(s, i1);
-
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
+ tcg_debug_assert(i1 == sextract32(i1, 0, 20));
+ insn = deposit32(insn, 0, 8, op);
+ insn = deposit32(insn, 8, 4, r0);
+ insn = deposit32(insn, 12, 20, i1);
+ tcg_out32(s, insn);
}
-#if TCG_TARGET_REG_BITS == 64
-static void tcg_out_op_rI(TCGContext *s, TCGOpcode op,
- TCGReg r0, uint64_t i1)
-{
- uint8_t *old_code_ptr = s->code_ptr;
-
- tcg_out_op_t(s, op);
- tcg_out_r(s, r0);
- tcg_out64(s, i1);
-
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
-}
-#endif
-
static void tcg_out_op_rl(TCGContext *s, TCGOpcode op, TCGReg r0, TCGLabel *l1)
{
- uint8_t *old_code_ptr = s->code_ptr;
+ tcg_insn_unit insn = 0;
- tcg_out_op_t(s, op);
- tcg_out_r(s, r0);
- tci_out_label(s, l1);
-
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
+ tcg_out_reloc(s, s->code_ptr, 20, l1, 0);
+ insn = deposit32(insn, 0, 8, op);
+ insn = deposit32(insn, 8, 4, r0);
+ tcg_out32(s, insn);
}
static void tcg_out_op_rr(TCGContext *s, TCGOpcode op, TCGReg r0, TCGReg r1)
{
- uint8_t *old_code_ptr = s->code_ptr;
+ tcg_insn_unit insn = 0;
- tcg_out_op_t(s, op);
- tcg_out_r(s, r0);
- tcg_out_r(s, r1);
-
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
+ insn = deposit32(insn, 0, 8, op);
+ insn = deposit32(insn, 8, 4, r0);
+ insn = deposit32(insn, 12, 4, r1);
+ tcg_out32(s, insn);
}
static void tcg_out_op_rrm(TCGContext *s, TCGOpcode op,
TCGReg r0, TCGReg r1, TCGArg m2)
{
- uint8_t *old_code_ptr = s->code_ptr;
+ tcg_insn_unit insn = 0;
- tcg_out_op_t(s, op);
- tcg_out_r(s, r0);
- tcg_out_r(s, r1);
- tcg_out32(s, m2);
-
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
+ tcg_debug_assert(m2 == extract32(m2, 0, 12));
+ insn = deposit32(insn, 0, 8, op);
+ insn = deposit32(insn, 8, 4, r0);
+ insn = deposit32(insn, 12, 4, r1);
+ insn = deposit32(insn, 20, 12, m2);
+ tcg_out32(s, insn);
}
static void tcg_out_op_rrr(TCGContext *s, TCGOpcode op,
TCGReg r0, TCGReg r1, TCGReg r2)
{
- uint8_t *old_code_ptr = s->code_ptr;
+ tcg_insn_unit insn = 0;
- tcg_out_op_t(s, op);
- tcg_out_r(s, r0);
- tcg_out_r(s, r1);
- tcg_out_r(s, r2);
-
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
+ insn = deposit32(insn, 0, 8, op);
+ insn = deposit32(insn, 8, 4, r0);
+ insn = deposit32(insn, 12, 4, r1);
+ insn = deposit32(insn, 16, 4, r2);
+ tcg_out32(s, insn);
}
static void tcg_out_op_rrs(TCGContext *s, TCGOpcode op,
TCGReg r0, TCGReg r1, intptr_t i2)
{
- uint8_t *old_code_ptr = s->code_ptr;
+ tcg_insn_unit insn = 0;
- tcg_out_op_t(s, op);
- tcg_out_r(s, r0);
- tcg_out_r(s, r1);
- tcg_debug_assert(i2 == (int32_t)i2);
- tcg_out32(s, i2);
-
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
+ tcg_debug_assert(i2 == sextract32(i2, 0, 16));
+ insn = deposit32(insn, 0, 8, op);
+ insn = deposit32(insn, 8, 4, r0);
+ insn = deposit32(insn, 12, 4, r1);
+ insn = deposit32(insn, 16, 16, i2);
+ tcg_out32(s, insn);
}
static void tcg_out_op_rrrc(TCGContext *s, TCGOpcode op,
TCGReg r0, TCGReg r1, TCGReg r2, TCGCond c3)
{
- uint8_t *old_code_ptr = s->code_ptr;
+ tcg_insn_unit insn = 0;
- tcg_out_op_t(s, op);
- tcg_out_r(s, r0);
- tcg_out_r(s, r1);
- tcg_out_r(s, r2);
- tcg_out8(s, c3);
-
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
+ insn = deposit32(insn, 0, 8, op);
+ insn = deposit32(insn, 8, 4, r0);
+ insn = deposit32(insn, 12, 4, r1);
+ insn = deposit32(insn, 16, 4, r2);
+ insn = deposit32(insn, 20, 4, c3);
+ tcg_out32(s, insn);
}
static void tcg_out_op_rrrm(TCGContext *s, TCGOpcode op,
TCGReg r0, TCGReg r1, TCGReg r2, TCGArg m3)
{
- uint8_t *old_code_ptr = s->code_ptr;
+ tcg_insn_unit insn = 0;
- tcg_out_op_t(s, op);
- tcg_out_r(s, r0);
- tcg_out_r(s, r1);
- tcg_out_r(s, r2);
- tcg_out32(s, m3);
-
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
+ tcg_debug_assert(m3 == extract32(m3, 0, 12));
+ insn = deposit32(insn, 0, 8, op);
+ insn = deposit32(insn, 8, 4, r0);
+ insn = deposit32(insn, 12, 4, r1);
+ insn = deposit32(insn, 16, 4, r2);
+ insn = deposit32(insn, 20, 12, m3);
+ tcg_out32(s, insn);
}
static void tcg_out_op_rrrbb(TCGContext *s, TCGOpcode op, TCGReg r0,
TCGReg r1, TCGReg r2, uint8_t b3, uint8_t b4)
{
- uint8_t *old_code_ptr = s->code_ptr;
+ tcg_insn_unit insn = 0;
- tcg_out_op_t(s, op);
- tcg_out_r(s, r0);
- tcg_out_r(s, r1);
- tcg_out_r(s, r2);
- tcg_out8(s, b3);
- tcg_out8(s, b4);
-
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
+ tcg_debug_assert(b3 == extract32(b3, 0, 6));
+ tcg_debug_assert(b4 == extract32(b4, 0, 6));
+ insn = deposit32(insn, 0, 8, op);
+ insn = deposit32(insn, 8, 4, r0);
+ insn = deposit32(insn, 12, 4, r1);
+ insn = deposit32(insn, 16, 4, r2);
+ insn = deposit32(insn, 20, 6, b3);
+ insn = deposit32(insn, 26, 6, b4);
+ tcg_out32(s, insn);
}
-static void tcg_out_op_rrrrm(TCGContext *s, TCGOpcode op, TCGReg r0,
- TCGReg r1, TCGReg r2, TCGReg r3, TCGArg m4)
+static void tcg_out_op_rrrrr(TCGContext *s, TCGOpcode op, TCGReg r0,
+ TCGReg r1, TCGReg r2, TCGReg r3, TCGReg r4)
{
- uint8_t *old_code_ptr = s->code_ptr;
+ tcg_insn_unit insn = 0;
- tcg_out_op_t(s, op);
- tcg_out_r(s, r0);
- tcg_out_r(s, r1);
- tcg_out_r(s, r2);
- tcg_out_r(s, r3);
- tcg_out32(s, m4);
-
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
+ insn = deposit32(insn, 0, 8, op);
+ insn = deposit32(insn, 8, 4, r0);
+ insn = deposit32(insn, 12, 4, r1);
+ insn = deposit32(insn, 16, 4, r2);
+ insn = deposit32(insn, 20, 4, r3);
+ insn = deposit32(insn, 24, 4, r4);
+ tcg_out32(s, insn);
}
#if TCG_TARGET_REG_BITS == 32
static void tcg_out_op_rrrr(TCGContext *s, TCGOpcode op,
TCGReg r0, TCGReg r1, TCGReg r2, TCGReg r3)
{
- uint8_t *old_code_ptr = s->code_ptr;
+ tcg_insn_unit insn = 0;
- tcg_out_op_t(s, op);
- tcg_out_r(s, r0);
- tcg_out_r(s, r1);
- tcg_out_r(s, r2);
- tcg_out_r(s, r3);
-
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
+ insn = deposit32(insn, 0, 8, op);
+ insn = deposit32(insn, 8, 4, r0);
+ insn = deposit32(insn, 12, 4, r1);
+ insn = deposit32(insn, 16, 4, r2);
+ insn = deposit32(insn, 20, 4, r3);
+ tcg_out32(s, insn);
}
static void tcg_out_op_rrrrrc(TCGContext *s, TCGOpcode op,
TCGReg r0, TCGReg r1, TCGReg r2,
TCGReg r3, TCGReg r4, TCGCond c5)
{
- uint8_t *old_code_ptr = s->code_ptr;
+ tcg_insn_unit insn = 0;
- tcg_out_op_t(s, op);
- tcg_out_r(s, r0);
- tcg_out_r(s, r1);
- tcg_out_r(s, r2);
- tcg_out_r(s, r3);
- tcg_out_r(s, r4);
- tcg_out8(s, c5);
-
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
+ insn = deposit32(insn, 0, 8, op);
+ insn = deposit32(insn, 8, 4, r0);
+ insn = deposit32(insn, 12, 4, r1);
+ insn = deposit32(insn, 16, 4, r2);
+ insn = deposit32(insn, 20, 4, r3);
+ insn = deposit32(insn, 24, 4, r4);
+ insn = deposit32(insn, 28, 4, c5);
+ tcg_out32(s, insn);
}
static void tcg_out_op_rrrrrr(TCGContext *s, TCGOpcode op,
TCGReg r0, TCGReg r1, TCGReg r2,
TCGReg r3, TCGReg r4, TCGReg r5)
{
- uint8_t *old_code_ptr = s->code_ptr;
+ tcg_insn_unit insn = 0;
- tcg_out_op_t(s, op);
- tcg_out_r(s, r0);
- tcg_out_r(s, r1);
- tcg_out_r(s, r2);
- tcg_out_r(s, r3);
- tcg_out_r(s, r4);
- tcg_out_r(s, r5);
-
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
+ insn = deposit32(insn, 0, 8, op);
+ insn = deposit32(insn, 8, 4, r0);
+ insn = deposit32(insn, 12, 4, r1);
+ insn = deposit32(insn, 16, 4, r2);
+ insn = deposit32(insn, 20, 4, r3);
+ insn = deposit32(insn, 24, 4, r4);
+ insn = deposit32(insn, 28, 4, r5);
+ tcg_out32(s, insn);
}
#endif
+static void tcg_out_ldst(TCGContext *s, TCGOpcode op, TCGReg val,
+ TCGReg base, intptr_t offset)
+{
+ stack_bounds_check(base, offset);
+ if (offset != sextract32(offset, 0, 16)) {
+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP, offset);
+ tcg_out_op_rrr(s, (TCG_TARGET_REG_BITS == 32
+ ? INDEX_op_add_i32 : INDEX_op_add_i64),
+ TCG_REG_TMP, TCG_REG_TMP, base);
+ base = TCG_REG_TMP;
+ offset = 0;
+ }
+ tcg_out_op_rrs(s, op, val, base, offset);
+}
+
static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg val, TCGReg base,
intptr_t offset)
{
- stack_bounds_check(base, offset);
switch (type) {
case TCG_TYPE_I32:
- tcg_out_op_rrs(s, INDEX_op_ld_i32, val, base, offset);
+ tcg_out_ldst(s, INDEX_op_ld_i32, val, base, offset);
break;
#if TCG_TARGET_REG_BITS == 64
case TCG_TYPE_I64:
- tcg_out_op_rrs(s, INDEX_op_ld_i64, val, base, offset);
+ tcg_out_ldst(s, INDEX_op_ld_i64, val, base, offset);
break;
#endif
default:
@@ -547,22 +495,32 @@ static void tcg_out_movi(TCGContext *s, TCGType type,
{
switch (type) {
case TCG_TYPE_I32:
- tcg_out_op_ri(s, INDEX_op_tci_movi_i32, ret, arg);
- break;
#if TCG_TARGET_REG_BITS == 64
+ arg = (int32_t)arg;
+ /* fall through */
case TCG_TYPE_I64:
- tcg_out_op_rI(s, INDEX_op_tci_movi_i64, ret, arg);
- break;
#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);
+ }
}
static void tcg_out_call(TCGContext *s, const tcg_insn_unit *func,
ffi_cif *cif)
{
- uint8_t *old_code_ptr = s->code_ptr;
+ tcg_insn_unit insn = 0;
uint8_t which;
if (cif->rtype == &ffi_type_void) {
@@ -573,12 +531,10 @@ static void tcg_out_call(TCGContext *s, const tcg_insn_unit *func,
tcg_debug_assert(cif->rtype->size == 8);
which = 2;
}
- tcg_out_op_t(s, INDEX_op_call);
- tcg_out8(s, which);
- tcg_out_i(s, (uintptr_t)func);
- tcg_out_i(s, (uintptr_t)cif);
-
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
+ new_pool_l2(s, 20, s->code_ptr, 0, (uintptr_t)func, (uintptr_t)cif);
+ insn = deposit32(insn, 0, 8, INDEX_op_call);
+ insn = deposit32(insn, 8, 4, which);
+ tcg_out32(s, insn);
}
#if TCG_TARGET_REG_BITS == 64
@@ -637,8 +593,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
case INDEX_op_st_i32:
CASE_64(st32)
CASE_64(st)
- stack_bounds_check(args[1], args[2]);
- tcg_out_op_rrs(s, opc, args[0], args[1], args[2]);
+ tcg_out_ldst(s, opc, args[0], args[1], args[2]);
break;
CASE_32_64(add)
@@ -731,8 +686,9 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
} else if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
tcg_out_op_rrrm(s, opc, args[0], args[1], args[2], args[3]);
} else {
- tcg_out_op_rrrrm(s, opc, args[0], args[1],
- args[2], args[3], args[4]);
+ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_TMP, args[4]);
+ tcg_out_op_rrrrr(s, opc, args[0], args[1],
+ args[2], args[3], TCG_REG_TMP);
}
break;
@@ -780,6 +736,11 @@ static int tcg_target_const_match(tcg_target_long val, TCGType type,
return arg_ct->ct & TCG_CT_CONST;
}
+static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
+{
+ memset(p, 0, sizeof(*p) * count);
+}
+
static void tcg_target_init(TCGContext *s)
{
#if defined(CONFIG_DEBUG_TCG_INTERPRETER)
diff --git a/tcg/tci/README b/tcg/tci/README
index 9bb7d7a5d3..f72a40a395 100644
--- a/tcg/tci/README
+++ b/tcg/tci/README
@@ -23,10 +23,12 @@ This is what TCI (Tiny Code Interpreter) does.
Like each TCG host frontend, TCI implements the code generator in
tcg-target.c.inc, tcg-target.h. Both files are in directory tcg/tci.
-The additional file tcg/tci.c adds the interpreter.
+The additional file tcg/tci.c adds the interpreter and disassembler.
-The bytecode consists of opcodes (same numeric values as those used by
-TCG), command length and arguments of variable size and number.
+The bytecode consists of opcodes (with only a few exceptions, with
+the same same numeric values and semantics as used by TCG), and up
+to six arguments packed into a 32-bit integer. See comments in tci.c
+for details on the encoding.
3) Usage
@@ -39,11 +41,6 @@ suggest using this option. Setting it automatically would need
additional code in configure which must be fixed when new native TCG
implementations are added.
-System emulation should work on any 32 or 64 bit host.
-User mode emulation might work. Maybe a new linker script (*.ld)
-is needed. Byte order might be wrong (on big endian hosts)
-and need fixes in configure.
-
For hosts with native TCG, the interpreter TCI can be enabled by
configure --enable-tcg-interpreter
@@ -118,13 +115,6 @@ u1 = linux-user-test works
in the interpreter. These opcodes raise a runtime exception, so it is
possible to see where code must be added.
-* The pseudo code is not optimized and still ugly. For hosts with special
- alignment requirements, it needs some fixes (maybe aligned bytecode
- would also improve speed for hosts which support byte alignment).
-
-* A better disassembler for the pseudo code would be nice (a very primitive
- disassembler is included in tcg-target.c.inc).
-
* It might be useful to have a runtime option which selects the native TCG
or TCI, so QEMU would have to include two TCGs. Today, selecting TCI
is a configure option, so you need two compilations of QEMU.
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 16/26] tcg/tci: Implement goto_ptr
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (14 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 15/26] tcg/tci: Change encoding to uint32_t units Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-02 23:57 ` [PATCH v6 17/26] tcg/tci: Implement movcond Richard Henderson
` (11 subsequent siblings)
27 siblings, 0 replies; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
This operation is critical to staying within the interpretation
loop longer, which avoids the overhead of setup and teardown for
many TBs.
The check in tcg_prologue_init is disabled because TCI does
want to use NULL to indicate exit, as opposed to branching to
a real epilogue.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/tci/tcg-target-con-set.h | 1 +
tcg/tci/tcg-target.h | 2 +-
tcg/tcg.c | 2 ++
tcg/tci.c | 19 +++++++++++++++++++
tcg/tci/tcg-target.c.inc | 16 ++++++++++++++++
5 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/tcg/tci/tcg-target-con-set.h b/tcg/tci/tcg-target-con-set.h
index 316730f32c..ae2dc3b844 100644
--- a/tcg/tci/tcg-target-con-set.h
+++ b/tcg/tci/tcg-target-con-set.h
@@ -9,6 +9,7 @@
* Each operand should be a sequence of constraint letters as defined by
* tcg-target-con-str.h; the constraint combination is inclusive or.
*/
+C_O0_I1(r)
C_O0_I2(r, r)
C_O0_I3(r, r, r)
C_O0_I4(r, r, r, r)
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index d953f2ead3..17911d3297 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -86,7 +86,7 @@
#define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
-#define TCG_TARGET_HAS_goto_ptr 0
+#define TCG_TARGET_HAS_goto_ptr 1
#define TCG_TARGET_HAS_direct_jump 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 7b9e31d15e..4f20aaeab0 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1355,10 +1355,12 @@ void tcg_prologue_init(TCGContext *s)
}
#endif
+#ifndef CONFIG_TCG_INTERPRETER
/* Assert that goto_ptr is implemented completely. */
if (TCG_TARGET_HAS_goto_ptr) {
tcg_debug_assert(tcg_code_gen_epilogue != NULL);
}
+#endif
}
void tcg_func_start(TCGContext *s)
diff --git a/tcg/tci.c b/tcg/tci.c
index 95f57c831f..ea28077847 100644
--- a/tcg/tci.c
+++ b/tcg/tci.c
@@ -71,6 +71,11 @@ static void tci_args_l(uint32_t insn, const void *tb_ptr, void **l0)
*l0 = diff ? (void *)tb_ptr + diff : NULL;
}
+static void tci_args_r(uint32_t insn, TCGReg *r0)
+{
+ *r0 = extract32(insn, 8, 4);
+}
+
static void tci_args_nl(uint32_t insn, const void *tb_ptr,
uint8_t *n0, void **l1)
{
@@ -736,6 +741,15 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
tb_ptr = *(void **)ptr;
break;
+ case INDEX_op_goto_ptr:
+ tci_args_r(insn, &r0);
+ ptr = (void *)regs[r0];
+ if (!ptr) {
+ return 0;
+ }
+ tb_ptr = ptr;
+ break;
+
case INDEX_op_qemu_ld_i32:
if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
tci_args_rrm(insn, &r0, &r1, &oi);
@@ -993,6 +1007,11 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
info->fprintf_func(info->stream, "%-12s %p", op_name, ptr);
break;
+ case INDEX_op_goto_ptr:
+ tci_args_r(insn, &r0);
+ info->fprintf_func(info->stream, "%-12s %s", op_name, str_r(r0));
+ break;
+
case INDEX_op_call:
tci_args_nl(insn, tb_ptr, &len, &ptr);
info->fprintf_func(info->stream, "%-12s %d, %p", op_name, len, ptr);
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
index acb5f6c75e..01a8e20c5d 100644
--- a/tcg/tci/tcg-target.c.inc
+++ b/tcg/tci/tcg-target.c.inc
@@ -27,6 +27,9 @@
static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
{
switch (op) {
+ case INDEX_op_goto_ptr:
+ return C_O0_I1(r);
+
case INDEX_op_ld8u_i32:
case INDEX_op_ld8s_i32:
case INDEX_op_ld16u_i32:
@@ -263,6 +266,15 @@ static void tcg_out_op_p(TCGContext *s, TCGOpcode op, void *p0)
tcg_out32(s, insn);
}
+static void tcg_out_op_r(TCGContext *s, TCGOpcode op, TCGReg r0)
+{
+ tcg_insn_unit insn = 0;
+
+ insn = deposit32(insn, 0, 8, op);
+ insn = deposit32(insn, 8, 4, r0);
+ tcg_out32(s, insn);
+}
+
static void tcg_out_op_v(TCGContext *s, TCGOpcode op)
{
tcg_out32(s, (uint8_t)op);
@@ -565,6 +577,10 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
set_jmp_reset_offset(s, args[0]);
break;
+ case INDEX_op_goto_ptr:
+ tcg_out_op_r(s, opc, args[0]);
+ break;
+
case INDEX_op_br:
tcg_out_op_l(s, opc, arg_label(args[0]));
break;
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 17/26] tcg/tci: Implement movcond
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (15 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 16/26] tcg/tci: Implement goto_ptr Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-15 9:34 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 18/26] tcg/tci: Implement andc, orc, eqv, nand, nor Richard Henderson
` (10 subsequent siblings)
27 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
When this opcode is not available in the backend, tcg middle-end
will expand this as a series of 5 opcodes. So implementing this
saves bytecode space.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/tci/tcg-target.h | 4 ++--
tcg/tci.c | 16 +++++++++++++++-
tcg/tci/tcg-target.c.inc | 10 +++++++---
3 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index 17911d3297..f53773a555 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -82,7 +82,7 @@
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_orc_i32 0
#define TCG_TARGET_HAS_rot_i32 1
-#define TCG_TARGET_HAS_movcond_i32 0
+#define TCG_TARGET_HAS_movcond_i32 1
#define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
@@ -119,7 +119,7 @@
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_orc_i64 0
#define TCG_TARGET_HAS_rot_i64 1
-#define TCG_TARGET_HAS_movcond_i64 0
+#define TCG_TARGET_HAS_movcond_i64 1
#define TCG_TARGET_HAS_muls2_i64 0
#define TCG_TARGET_HAS_add2_i32 0
#define TCG_TARGET_HAS_sub2_i32 0
diff --git a/tcg/tci.c b/tcg/tci.c
index ea28077847..7f1d54158e 100644
--- a/tcg/tci.c
+++ b/tcg/tci.c
@@ -171,6 +171,7 @@ static void tci_args_rrrr(uint32_t insn,
*r2 = extract32(insn, 16, 4);
*r3 = extract32(insn, 20, 4);
}
+#endif
static void tci_args_rrrrrc(uint32_t insn, TCGReg *r0, TCGReg *r1,
TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGCond *c5)
@@ -183,6 +184,7 @@ static void tci_args_rrrrrc(uint32_t insn, TCGReg *r0, TCGReg *r1,
*c5 = extract32(insn, 28, 4);
}
+#if TCG_TARGET_REG_BITS == 32
static void tci_args_rrrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGReg *r5)
{
@@ -419,6 +421,11 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
regs[r0] = tci_compare32(regs[r1], regs[r2], condition);
break;
+ case INDEX_op_movcond_i32:
+ tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
+ tmp32 = tci_compare32(regs[r1], regs[r2], condition);
+ regs[r0] = regs[tmp32 ? r3 : r4];
+ break;
#if TCG_TARGET_REG_BITS == 32
case INDEX_op_setcond2_i32:
tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
@@ -431,6 +438,11 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
regs[r0] = tci_compare64(regs[r1], regs[r2], condition);
break;
+ case INDEX_op_movcond_i64:
+ tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
+ tmp32 = tci_compare64(regs[r1], regs[r2], condition);
+ regs[r0] = regs[tmp32 ? r3 : r4];
+ break;
#endif
CASE_32_64(mov)
tci_args_rr(insn, &r0, &r1);
@@ -1136,7 +1148,8 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
op_name, str_r(r0), str_r(r1), str_r(r2), pos, len);
break;
-#if TCG_TARGET_REG_BITS == 32
+ case INDEX_op_movcond_i32:
+ case INDEX_op_movcond_i64:
case INDEX_op_setcond2_i32:
tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &c);
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %s",
@@ -1144,6 +1157,7 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
str_r(r3), str_r(r4), str_c(c));
break;
+#if TCG_TARGET_REG_BITS == 32
case INDEX_op_mulu2_i32:
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
index 01a8e20c5d..e7a07c1811 100644
--- a/tcg/tci/tcg-target.c.inc
+++ b/tcg/tci/tcg-target.c.inc
@@ -133,9 +133,12 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
return C_O0_I4(r, r, r, r);
case INDEX_op_mulu2_i32:
return C_O2_I2(r, r, r, r);
+#endif
+
+ case INDEX_op_movcond_i32:
+ case INDEX_op_movcond_i64:
case INDEX_op_setcond2_i32:
return C_O1_I4(r, r, r, r, r);
-#endif
case INDEX_op_qemu_ld_i32:
return (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
@@ -419,6 +422,7 @@ static void tcg_out_op_rrrr(TCGContext *s, TCGOpcode op,
insn = deposit32(insn, 20, 4, r3);
tcg_out32(s, insn);
}
+#endif
static void tcg_out_op_rrrrrc(TCGContext *s, TCGOpcode op,
TCGReg r0, TCGReg r1, TCGReg r2,
@@ -436,6 +440,7 @@ static void tcg_out_op_rrrrrc(TCGContext *s, TCGOpcode op,
tcg_out32(s, insn);
}
+#if TCG_TARGET_REG_BITS == 32
static void tcg_out_op_rrrrrr(TCGContext *s, TCGOpcode op,
TCGReg r0, TCGReg r1, TCGReg r2,
TCGReg r3, TCGReg r4, TCGReg r5)
@@ -589,12 +594,11 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
tcg_out_op_rrrc(s, opc, args[0], args[1], args[2], args[3]);
break;
-#if TCG_TARGET_REG_BITS == 32
+ CASE_32_64(movcond)
case INDEX_op_setcond2_i32:
tcg_out_op_rrrrrc(s, opc, args[0], args[1], args[2],
args[3], args[4], args[5]);
break;
-#endif
CASE_32_64(ld8u)
CASE_32_64(ld8s)
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 18/26] tcg/tci: Implement andc, orc, eqv, nand, nor
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (16 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 17/26] tcg/tci: Implement movcond Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-03 22:13 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 19/26] tcg/tci: Implement extract, sextract Richard Henderson
` (9 subsequent siblings)
27 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
These were already present in tcg-target.c.inc,
but not in the interpreter.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/tci/tcg-target.h | 20 ++++++++++----------
tcg/tci.c | 40 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 50 insertions(+), 10 deletions(-)
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index f53773a555..5945272a43 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -67,20 +67,20 @@
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_ext8u_i32 1
#define TCG_TARGET_HAS_ext16u_i32 1
-#define TCG_TARGET_HAS_andc_i32 0
+#define TCG_TARGET_HAS_andc_i32 1
#define TCG_TARGET_HAS_deposit_i32 1
#define TCG_TARGET_HAS_extract_i32 0
#define TCG_TARGET_HAS_sextract_i32 0
#define TCG_TARGET_HAS_extract2_i32 0
-#define TCG_TARGET_HAS_eqv_i32 0
-#define TCG_TARGET_HAS_nand_i32 0
-#define TCG_TARGET_HAS_nor_i32 0
+#define TCG_TARGET_HAS_eqv_i32 1
+#define TCG_TARGET_HAS_nand_i32 1
+#define TCG_TARGET_HAS_nor_i32 1
#define TCG_TARGET_HAS_clz_i32 0
#define TCG_TARGET_HAS_ctz_i32 0
#define TCG_TARGET_HAS_ctpop_i32 0
#define TCG_TARGET_HAS_neg_i32 1
#define TCG_TARGET_HAS_not_i32 1
-#define TCG_TARGET_HAS_orc_i32 0
+#define TCG_TARGET_HAS_orc_i32 1
#define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_movcond_i32 1
#define TCG_TARGET_HAS_muls2_i32 0
@@ -108,16 +108,16 @@
#define TCG_TARGET_HAS_ext8u_i64 1
#define TCG_TARGET_HAS_ext16u_i64 1
#define TCG_TARGET_HAS_ext32u_i64 1
-#define TCG_TARGET_HAS_andc_i64 0
-#define TCG_TARGET_HAS_eqv_i64 0
-#define TCG_TARGET_HAS_nand_i64 0
-#define TCG_TARGET_HAS_nor_i64 0
+#define TCG_TARGET_HAS_andc_i64 1
+#define TCG_TARGET_HAS_eqv_i64 1
+#define TCG_TARGET_HAS_nand_i64 1
+#define TCG_TARGET_HAS_nor_i64 1
#define TCG_TARGET_HAS_clz_i64 0
#define TCG_TARGET_HAS_ctz_i64 0
#define TCG_TARGET_HAS_ctpop_i64 0
#define TCG_TARGET_HAS_neg_i64 1
#define TCG_TARGET_HAS_not_i64 1
-#define TCG_TARGET_HAS_orc_i64 0
+#define TCG_TARGET_HAS_orc_i64 1
#define TCG_TARGET_HAS_rot_i64 1
#define TCG_TARGET_HAS_movcond_i64 1
#define TCG_TARGET_HAS_muls2_i64 0
diff --git a/tcg/tci.c b/tcg/tci.c
index 7f1d54158e..3e16dc30cf 100644
--- a/tcg/tci.c
+++ b/tcg/tci.c
@@ -528,6 +528,36 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = regs[r1] ^ regs[r2];
break;
+#if TCG_TARGET_HAS_andc_i32 || TCG_TARGET_HAS_andc_i64
+ CASE_32_64(andc)
+ tci_args_rrr(insn, &r0, &r1, &r2);
+ regs[r0] = regs[r1] & ~regs[r2];
+ break;
+#endif
+#if TCG_TARGET_HAS_orc_i32 || TCG_TARGET_HAS_orc_i64
+ CASE_32_64(orc)
+ tci_args_rrr(insn, &r0, &r1, &r2);
+ regs[r0] = regs[r1] | ~regs[r2];
+ break;
+#endif
+#if TCG_TARGET_HAS_eqv_i32 || TCG_TARGET_HAS_eqv_i64
+ CASE_32_64(eqv)
+ tci_args_rrr(insn, &r0, &r1, &r2);
+ regs[r0] = ~(regs[r1] ^ regs[r2]);
+ break;
+#endif
+#if TCG_TARGET_HAS_nand_i32 || TCG_TARGET_HAS_nand_i64
+ CASE_32_64(nand)
+ tci_args_rrr(insn, &r0, &r1, &r2);
+ regs[r0] = ~(regs[r1] & regs[r2]);
+ break;
+#endif
+#if TCG_TARGET_HAS_nor_i32 || TCG_TARGET_HAS_nor_i64
+ CASE_32_64(nor)
+ tci_args_rrr(insn, &r0, &r1, &r2);
+ regs[r0] = ~(regs[r1] | regs[r2]);
+ break;
+#endif
/* Arithmetic operations (32 bit). */
@@ -1118,6 +1148,16 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
case INDEX_op_or_i64:
case INDEX_op_xor_i32:
case INDEX_op_xor_i64:
+ case INDEX_op_andc_i32:
+ case INDEX_op_andc_i64:
+ case INDEX_op_orc_i32:
+ case INDEX_op_orc_i64:
+ case INDEX_op_eqv_i32:
+ case INDEX_op_eqv_i64:
+ case INDEX_op_nand_i32:
+ case INDEX_op_nand_i64:
+ case INDEX_op_nor_i32:
+ case INDEX_op_nor_i64:
case INDEX_op_div_i32:
case INDEX_op_div_i64:
case INDEX_op_rem_i32:
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 19/26] tcg/tci: Implement extract, sextract
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (17 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 18/26] tcg/tci: Implement andc, orc, eqv, nand, nor Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-03 22:04 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 20/26] tcg/tci: Implement clz, ctz, ctpop Richard Henderson
` (8 subsequent siblings)
27 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/tci/tcg-target.h | 8 ++++----
tcg/tci.c | 42 ++++++++++++++++++++++++++++++++++++++++
tcg/tci/tcg-target.c.inc | 32 ++++++++++++++++++++++++++++++
3 files changed, 78 insertions(+), 4 deletions(-)
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index 5945272a43..60b67b196b 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -69,8 +69,8 @@
#define TCG_TARGET_HAS_ext16u_i32 1
#define TCG_TARGET_HAS_andc_i32 1
#define TCG_TARGET_HAS_deposit_i32 1
-#define TCG_TARGET_HAS_extract_i32 0
-#define TCG_TARGET_HAS_sextract_i32 0
+#define TCG_TARGET_HAS_extract_i32 1
+#define TCG_TARGET_HAS_sextract_i32 1
#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_eqv_i32 1
#define TCG_TARGET_HAS_nand_i32 1
@@ -97,8 +97,8 @@
#define TCG_TARGET_HAS_bswap32_i64 1
#define TCG_TARGET_HAS_bswap64_i64 1
#define TCG_TARGET_HAS_deposit_i64 1
-#define TCG_TARGET_HAS_extract_i64 0
-#define TCG_TARGET_HAS_sextract_i64 0
+#define TCG_TARGET_HAS_extract_i64 1
+#define TCG_TARGET_HAS_sextract_i64 1
#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 1
diff --git a/tcg/tci.c b/tcg/tci.c
index 3e16dc30cf..d9a00f9f3a 100644
--- a/tcg/tci.c
+++ b/tcg/tci.c
@@ -124,6 +124,15 @@ static void tci_args_rrs(uint32_t insn, TCGReg *r0, TCGReg *r1, int32_t *i2)
*i2 = sextract32(insn, 16, 16);
}
+static void tci_args_rrbb(uint32_t insn, TCGReg *r0, TCGReg *r1,
+ uint8_t *i2, uint8_t *i3)
+{
+ *r0 = extract32(insn, 8, 4);
+ *r1 = extract32(insn, 12, 4);
+ *i2 = extract32(insn, 16, 6);
+ *i3 = extract32(insn, 22, 6);
+}
+
static void tci_args_rrrc(uint32_t insn,
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGCond *c3)
{
@@ -607,6 +616,18 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
regs[r0] = deposit32(regs[r1], pos, len, regs[r2]);
break;
+#endif
+#if TCG_TARGET_HAS_extract_i32
+ case INDEX_op_extract_i32:
+ tci_args_rrbb(insn, &r0, &r1, &pos, &len);
+ regs[r0] = extract32(regs[r1], pos, len);
+ break;
+#endif
+#if TCG_TARGET_HAS_sextract_i32
+ case INDEX_op_sextract_i32:
+ tci_args_rrbb(insn, &r0, &r1, &pos, &len);
+ regs[r0] = sextract32(regs[r1], pos, len);
+ break;
#endif
case INDEX_op_brcond_i32:
tci_args_rl(insn, tb_ptr, &r0, &ptr);
@@ -747,6 +768,18 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
regs[r0] = deposit64(regs[r1], pos, len, regs[r2]);
break;
+#endif
+#if TCG_TARGET_HAS_extract_i64
+ case INDEX_op_extract_i64:
+ tci_args_rrbb(insn, &r0, &r1, &pos, &len);
+ regs[r0] = extract64(regs[r1], pos, len);
+ break;
+#endif
+#if TCG_TARGET_HAS_sextract_i64
+ case INDEX_op_sextract_i64:
+ tci_args_rrbb(insn, &r0, &r1, &pos, &len);
+ regs[r0] = sextract64(regs[r1], pos, len);
+ break;
#endif
case INDEX_op_brcond_i64:
tci_args_rl(insn, tb_ptr, &r0, &ptr);
@@ -1188,6 +1221,15 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
op_name, str_r(r0), str_r(r1), str_r(r2), pos, len);
break;
+ case INDEX_op_extract_i32:
+ case INDEX_op_extract_i64:
+ case INDEX_op_sextract_i32:
+ case INDEX_op_sextract_i64:
+ tci_args_rrbb(insn, &r0, &r1, &pos, &len);
+ info->fprintf_func(info->stream, "%-12s %s,%s,%d,%d",
+ op_name, str_r(r0), str_r(r1), pos, len);
+ break;
+
case INDEX_op_movcond_i32:
case INDEX_op_movcond_i64:
case INDEX_op_setcond2_i32:
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
index e7a07c1811..677ae2dceb 100644
--- a/tcg/tci/tcg-target.c.inc
+++ b/tcg/tci/tcg-target.c.inc
@@ -63,6 +63,10 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_bswap32_i32:
case INDEX_op_bswap32_i64:
case INDEX_op_bswap64_i64:
+ case INDEX_op_extract_i32:
+ case INDEX_op_extract_i64:
+ case INDEX_op_sextract_i32:
+ case INDEX_op_sextract_i64:
return C_O1_I1(r, r);
case INDEX_op_st8_i32:
@@ -352,6 +356,21 @@ static void tcg_out_op_rrs(TCGContext *s, TCGOpcode op,
tcg_out32(s, insn);
}
+static void tcg_out_op_rrbb(TCGContext *s, TCGOpcode op, TCGReg r0,
+ TCGReg r1, uint8_t b2, uint8_t b3)
+{
+ tcg_insn_unit insn = 0;
+
+ tcg_debug_assert(b2 == extract32(b2, 0, 6));
+ tcg_debug_assert(b3 == extract32(b3, 0, 6));
+ insn = deposit32(insn, 0, 8, op);
+ insn = deposit32(insn, 8, 4, r0);
+ insn = deposit32(insn, 12, 4, r1);
+ insn = deposit32(insn, 16, 6, b2);
+ insn = deposit32(insn, 22, 6, b3);
+ tcg_out32(s, insn);
+}
+
static void tcg_out_op_rrrc(TCGContext *s, TCGOpcode op,
TCGReg r0, TCGReg r1, TCGReg r2, TCGCond c3)
{
@@ -651,6 +670,19 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
}
break;
+ CASE_32_64(extract) /* Optional (TCG_TARGET_HAS_extract_*). */
+ CASE_32_64(sextract) /* Optional (TCG_TARGET_HAS_sextract_*). */
+ {
+ TCGArg pos = args[2], len = args[3];
+ TCGArg max = tcg_op_defs[opc].flags & TCG_OPF_64BIT ? 64 : 32;
+
+ tcg_debug_assert(pos < max);
+ tcg_debug_assert(pos + len <= max);
+
+ tcg_out_op_rrbb(s, opc, args[0], args[1], pos, len);
+ }
+ break;
+
CASE_32_64(brcond)
tcg_out_op_rrrc(s, (opc == INDEX_op_brcond_i32
? INDEX_op_setcond_i32 : INDEX_op_setcond_i64),
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 20/26] tcg/tci: Implement clz, ctz, ctpop
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (18 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 19/26] tcg/tci: Implement extract, sextract Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-03 22:10 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 21/26] tcg/tci: Implement mulu2, muls2 Richard Henderson
` (7 subsequent siblings)
27 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/tci/tcg-target.h | 12 +++++------
tcg/tci.c | 44 ++++++++++++++++++++++++++++++++++++++++
tcg/tci/tcg-target.c.inc | 9 ++++++++
3 files changed, 59 insertions(+), 6 deletions(-)
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index 60b67b196b..59859bd8a6 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -75,9 +75,9 @@
#define TCG_TARGET_HAS_eqv_i32 1
#define TCG_TARGET_HAS_nand_i32 1
#define TCG_TARGET_HAS_nor_i32 1
-#define TCG_TARGET_HAS_clz_i32 0
-#define TCG_TARGET_HAS_ctz_i32 0
-#define TCG_TARGET_HAS_ctpop_i32 0
+#define TCG_TARGET_HAS_clz_i32 1
+#define TCG_TARGET_HAS_ctz_i32 1
+#define TCG_TARGET_HAS_ctpop_i32 1
#define TCG_TARGET_HAS_neg_i32 1
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_orc_i32 1
@@ -112,9 +112,9 @@
#define TCG_TARGET_HAS_eqv_i64 1
#define TCG_TARGET_HAS_nand_i64 1
#define TCG_TARGET_HAS_nor_i64 1
-#define TCG_TARGET_HAS_clz_i64 0
-#define TCG_TARGET_HAS_ctz_i64 0
-#define TCG_TARGET_HAS_ctpop_i64 0
+#define TCG_TARGET_HAS_clz_i64 1
+#define TCG_TARGET_HAS_ctz_i64 1
+#define TCG_TARGET_HAS_ctpop_i64 1
#define TCG_TARGET_HAS_neg_i64 1
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_orc_i64 1
diff --git a/tcg/tci.c b/tcg/tci.c
index d9a00f9f3a..c5ed80bc57 100644
--- a/tcg/tci.c
+++ b/tcg/tci.c
@@ -586,6 +586,26 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = (uint32_t)regs[r1] % (uint32_t)regs[r2];
break;
+#if TCG_TARGET_HAS_clz_i32
+ case INDEX_op_clz_i32:
+ tci_args_rrr(insn, &r0, &r1, &r2);
+ tmp32 = regs[r1];
+ regs[r0] = tmp32 ? clz32(tmp32) : regs[r2];
+ break;
+#endif
+#if TCG_TARGET_HAS_ctz_i32
+ case INDEX_op_ctz_i32:
+ tci_args_rrr(insn, &r0, &r1, &r2);
+ tmp32 = regs[r1];
+ regs[r0] = tmp32 ? ctz32(tmp32) : regs[r2];
+ break;
+#endif
+#if TCG_TARGET_HAS_ctpop_i32
+ case INDEX_op_ctpop_i32:
+ tci_args_rr(insn, &r0, &r1);
+ regs[r0] = ctpop32(regs[r1]);
+ break;
+#endif
/* Shift/rotate operations (32 bit). */
@@ -738,6 +758,24 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = (uint64_t)regs[r1] % (uint64_t)regs[r2];
break;
+#if TCG_TARGET_HAS_clz_i64
+ case INDEX_op_clz_i64:
+ tci_args_rrr(insn, &r0, &r1, &r2);
+ regs[r0] = regs[r1] ? clz64(regs[r1]) : regs[r2];
+ break;
+#endif
+#if TCG_TARGET_HAS_ctz_i64
+ case INDEX_op_ctz_i64:
+ tci_args_rrr(insn, &r0, &r1, &r2);
+ regs[r0] = regs[r1] ? ctz64(regs[r1]) : regs[r2];
+ break;
+#endif
+#if TCG_TARGET_HAS_ctpop_i64
+ case INDEX_op_ctpop_i64:
+ tci_args_rr(insn, &r0, &r1);
+ regs[r0] = ctpop64(regs[r1]);
+ break;
+#endif
/* Shift/rotate operations (64 bit). */
@@ -1164,6 +1202,8 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
case INDEX_op_not_i64:
case INDEX_op_neg_i32:
case INDEX_op_neg_i64:
+ case INDEX_op_ctpop_i32:
+ case INDEX_op_ctpop_i64:
tci_args_rr(insn, &r0, &r1);
info->fprintf_func(info->stream, "%-12s %s, %s",
op_name, str_r(r0), str_r(r1));
@@ -1209,6 +1249,10 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
case INDEX_op_rotl_i64:
case INDEX_op_rotr_i32:
case INDEX_op_rotr_i64:
+ case INDEX_op_clz_i32:
+ case INDEX_op_clz_i64:
+ case INDEX_op_ctz_i32:
+ case INDEX_op_ctz_i64:
tci_args_rrr(insn, &r0, &r1, &r2);
info->fprintf_func(info->stream, "%-12s %s, %s, %s",
op_name, str_r(r0), str_r(r1), str_r(r2));
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
index 677ae2dceb..748bc13d4e 100644
--- a/tcg/tci/tcg-target.c.inc
+++ b/tcg/tci/tcg-target.c.inc
@@ -67,6 +67,8 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_extract_i64:
case INDEX_op_sextract_i32:
case INDEX_op_sextract_i64:
+ case INDEX_op_ctpop_i32:
+ case INDEX_op_ctpop_i64:
return C_O1_I1(r, r);
case INDEX_op_st8_i32:
@@ -122,6 +124,10 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_setcond_i64:
case INDEX_op_deposit_i32:
case INDEX_op_deposit_i64:
+ case INDEX_op_clz_i32:
+ case INDEX_op_clz_i64:
+ case INDEX_op_ctz_i32:
+ case INDEX_op_ctz_i64:
return C_O1_I2(r, r, r);
case INDEX_op_brcond_i32:
@@ -655,6 +661,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
CASE_32_64(divu) /* Optional (TCG_TARGET_HAS_div_*). */
CASE_32_64(rem) /* Optional (TCG_TARGET_HAS_div_*). */
CASE_32_64(remu) /* Optional (TCG_TARGET_HAS_div_*). */
+ CASE_32_64(clz) /* Optional (TCG_TARGET_HAS_clz_*). */
+ CASE_32_64(ctz) /* Optional (TCG_TARGET_HAS_ctz_*). */
tcg_out_op_rrr(s, opc, args[0], args[1], args[2]);
break;
@@ -703,6 +711,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
CASE_32_64(bswap16) /* Optional (TCG_TARGET_HAS_bswap16_*). */
CASE_32_64(bswap32) /* Optional (TCG_TARGET_HAS_bswap32_*). */
CASE_64(bswap64) /* Optional (TCG_TARGET_HAS_bswap64_i64). */
+ CASE_32_64(ctpop) /* Optional (TCG_TARGET_HAS_ctpop_*). */
tcg_out_op_rr(s, opc, args[0], args[1]);
break;
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 21/26] tcg/tci: Implement mulu2, muls2
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (19 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 20/26] tcg/tci: Implement clz, ctz, ctpop Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-02 23:57 ` [PATCH v6 22/26] tcg/tci: Implement add2, sub2 Richard Henderson
` (6 subsequent siblings)
27 siblings, 0 replies; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé
We already had mulu2_i32 for a 32-bit host; expand this to 64-bit
hosts as well. The muls2_i32 and the 64-bit opcodes are new.
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/tci/tcg-target.h | 8 ++++----
tcg/tci.c | 35 +++++++++++++++++++++++++++++------
tcg/tci/tcg-target.c.inc | 16 ++++++++++------
3 files changed, 43 insertions(+), 16 deletions(-)
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index 59859bd8a6..71a44bbfb0 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -83,7 +83,7 @@
#define TCG_TARGET_HAS_orc_i32 1
#define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_movcond_i32 1
-#define TCG_TARGET_HAS_muls2_i32 0
+#define TCG_TARGET_HAS_muls2_i32 1
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
#define TCG_TARGET_HAS_goto_ptr 1
@@ -120,13 +120,13 @@
#define TCG_TARGET_HAS_orc_i64 1
#define TCG_TARGET_HAS_rot_i64 1
#define TCG_TARGET_HAS_movcond_i64 1
-#define TCG_TARGET_HAS_muls2_i64 0
+#define TCG_TARGET_HAS_muls2_i64 1
#define TCG_TARGET_HAS_add2_i32 0
#define TCG_TARGET_HAS_sub2_i32 0
-#define TCG_TARGET_HAS_mulu2_i32 0
+#define TCG_TARGET_HAS_mulu2_i32 1
#define TCG_TARGET_HAS_add2_i64 0
#define TCG_TARGET_HAS_sub2_i64 0
-#define TCG_TARGET_HAS_mulu2_i64 0
+#define TCG_TARGET_HAS_mulu2_i64 1
#define TCG_TARGET_HAS_muluh_i64 0
#define TCG_TARGET_HAS_mulsh_i64 0
#else
diff --git a/tcg/tci.c b/tcg/tci.c
index c5ed80bc57..7003a3dffe 100644
--- a/tcg/tci.c
+++ b/tcg/tci.c
@@ -39,7 +39,7 @@ __thread uintptr_t tci_tb_ptr;
static void tci_write_reg64(tcg_target_ulong *regs, uint32_t high_index,
uint32_t low_index, uint64_t value)
{
- regs[low_index] = value;
+ regs[low_index] = (uint32_t)value;
regs[high_index] = value >> 32;
}
@@ -171,7 +171,6 @@ static void tci_args_rrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
*r4 = extract32(insn, 24, 4);
}
-#if TCG_TARGET_REG_BITS == 32
static void tci_args_rrrr(uint32_t insn,
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGReg *r3)
{
@@ -180,7 +179,6 @@ static void tci_args_rrrr(uint32_t insn,
*r2 = extract32(insn, 16, 4);
*r3 = extract32(insn, 20, 4);
}
-#endif
static void tci_args_rrrrrc(uint32_t insn, TCGReg *r0, TCGReg *r1,
TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGCond *c5)
@@ -668,11 +666,21 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
T2 = tci_uint64(regs[r5], regs[r4]);
tci_write_reg64(regs, r1, r0, T1 - T2);
break;
+#endif /* TCG_TARGET_REG_BITS == 32 */
+#if TCG_TARGET_HAS_mulu2_i32
case INDEX_op_mulu2_i32:
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
- tci_write_reg64(regs, r1, r0, (uint64_t)regs[r2] * regs[r3]);
+ tmp64 = (uint64_t)(uint32_t)regs[r2] * (uint32_t)regs[r3];
+ tci_write_reg64(regs, r1, r0, tmp64);
break;
-#endif /* TCG_TARGET_REG_BITS == 32 */
+#endif
+#if TCG_TARGET_HAS_muls2_i32
+ case INDEX_op_muls2_i32:
+ tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
+ tmp64 = (int64_t)(int32_t)regs[r2] * (int32_t)regs[r3];
+ tci_write_reg64(regs, r1, r0, tmp64);
+ break;
+#endif
#if TCG_TARGET_HAS_ext8s_i32 || TCG_TARGET_HAS_ext8s_i64
CASE_32_64(ext8s)
tci_args_rr(insn, &r0, &r1);
@@ -776,6 +784,18 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
regs[r0] = ctpop64(regs[r1]);
break;
#endif
+#if TCG_TARGET_HAS_mulu2_i64
+ case INDEX_op_mulu2_i64:
+ tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
+ mulu64(®s[r0], ®s[r1], regs[r2], regs[r3]);
+ break;
+#endif
+#if TCG_TARGET_HAS_muls2_i64
+ case INDEX_op_muls2_i64:
+ tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
+ muls64(®s[r0], ®s[r1], regs[r2], regs[r3]);
+ break;
+#endif
/* Shift/rotate operations (64 bit). */
@@ -1283,14 +1303,17 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
str_r(r3), str_r(r4), str_c(c));
break;
-#if TCG_TARGET_REG_BITS == 32
case INDEX_op_mulu2_i32:
+ case INDEX_op_mulu2_i64:
+ case INDEX_op_muls2_i32:
+ case INDEX_op_muls2_i64:
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
op_name, str_r(r0), str_r(r1),
str_r(r2), str_r(r3));
break;
+#if TCG_TARGET_REG_BITS == 32
case INDEX_op_add2_i32:
case INDEX_op_sub2_i32:
tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
index 748bc13d4e..e617c46366 100644
--- a/tcg/tci/tcg-target.c.inc
+++ b/tcg/tci/tcg-target.c.inc
@@ -141,10 +141,14 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
return C_O2_I4(r, r, r, r, r, r);
case INDEX_op_brcond2_i32:
return C_O0_I4(r, r, r, r);
- case INDEX_op_mulu2_i32:
- return C_O2_I2(r, r, r, r);
#endif
+ case INDEX_op_mulu2_i32:
+ case INDEX_op_mulu2_i64:
+ case INDEX_op_muls2_i32:
+ case INDEX_op_muls2_i64:
+ return C_O2_I2(r, r, r, r);
+
case INDEX_op_movcond_i32:
case INDEX_op_movcond_i64:
case INDEX_op_setcond2_i32:
@@ -434,7 +438,6 @@ static void tcg_out_op_rrrrr(TCGContext *s, TCGOpcode op, TCGReg r0,
tcg_out32(s, insn);
}
-#if TCG_TARGET_REG_BITS == 32
static void tcg_out_op_rrrr(TCGContext *s, TCGOpcode op,
TCGReg r0, TCGReg r1, TCGReg r2, TCGReg r3)
{
@@ -447,7 +450,6 @@ static void tcg_out_op_rrrr(TCGContext *s, TCGOpcode op,
insn = deposit32(insn, 20, 4, r3);
tcg_out32(s, insn);
}
-#endif
static void tcg_out_op_rrrrrc(TCGContext *s, TCGOpcode op,
TCGReg r0, TCGReg r1, TCGReg r2,
@@ -726,10 +728,12 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
args[0], args[1], args[2], args[3], args[4]);
tcg_out_op_rl(s, INDEX_op_brcond_i32, TCG_REG_TMP, arg_label(args[5]));
break;
- case INDEX_op_mulu2_i32:
+#endif
+
+ CASE_32_64(mulu2)
+ CASE_32_64(muls2)
tcg_out_op_rrrr(s, opc, args[0], args[1], args[2], args[3]);
break;
-#endif
case INDEX_op_qemu_ld_i32:
case INDEX_op_qemu_st_i32:
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 22/26] tcg/tci: Implement add2, sub2
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (20 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 21/26] tcg/tci: Implement mulu2, muls2 Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-02 23:57 ` [PATCH v6 23/26] tcg/tci: Split out tci_qemu_ld, tci_qemu_st Richard Henderson
` (5 subsequent siblings)
27 siblings, 0 replies; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
We already had the 32-bit versions for a 32-bit host; expand this
to 64-bit hosts as well. The 64-bit opcodes are new.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/tci/tcg-target.h | 8 ++++----
tcg/tci.c | 40 ++++++++++++++++++++++++++--------------
tcg/tci/tcg-target.c.inc | 15 ++++++++-------
3 files changed, 38 insertions(+), 25 deletions(-)
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index 71a44bbfb0..515b3c7a56 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -121,11 +121,11 @@
#define TCG_TARGET_HAS_rot_i64 1
#define TCG_TARGET_HAS_movcond_i64 1
#define TCG_TARGET_HAS_muls2_i64 1
-#define TCG_TARGET_HAS_add2_i32 0
-#define TCG_TARGET_HAS_sub2_i32 0
+#define TCG_TARGET_HAS_add2_i32 1
+#define TCG_TARGET_HAS_sub2_i32 1
#define TCG_TARGET_HAS_mulu2_i32 1
-#define TCG_TARGET_HAS_add2_i64 0
-#define TCG_TARGET_HAS_sub2_i64 0
+#define TCG_TARGET_HAS_add2_i64 1
+#define TCG_TARGET_HAS_sub2_i64 1
#define TCG_TARGET_HAS_mulu2_i64 1
#define TCG_TARGET_HAS_muluh_i64 0
#define TCG_TARGET_HAS_mulsh_i64 0
diff --git a/tcg/tci.c b/tcg/tci.c
index 7003a3dffe..ff096e1e32 100644
--- a/tcg/tci.c
+++ b/tcg/tci.c
@@ -191,7 +191,6 @@ static void tci_args_rrrrrc(uint32_t insn, TCGReg *r0, TCGReg *r1,
*c5 = extract32(insn, 28, 4);
}
-#if TCG_TARGET_REG_BITS == 32
static void tci_args_rrrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGReg *r5)
{
@@ -202,7 +201,6 @@ static void tci_args_rrrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
*r4 = extract32(insn, 24, 4);
*r5 = extract32(insn, 28, 4);
}
-#endif
static bool tci_compare32(uint32_t u0, uint32_t u1, TCGCond condition)
{
@@ -352,17 +350,14 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
for (;;) {
uint32_t insn;
TCGOpcode opc;
- TCGReg r0, r1, r2, r3, r4;
+ TCGReg r0, r1, r2, r3, r4, r5;
tcg_target_ulong t1;
TCGCond condition;
target_ulong taddr;
uint8_t pos, len;
uint32_t tmp32;
uint64_t tmp64;
-#if TCG_TARGET_REG_BITS == 32
- TCGReg r5;
uint64_t T1, T2;
-#endif
TCGMemOpIdx oi;
int32_t ofs;
void *ptr;
@@ -653,20 +648,22 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
tb_ptr = ptr;
}
break;
-#if TCG_TARGET_REG_BITS == 32
+#if TCG_TARGET_REG_BITS == 32 || TCG_TARGET_HAS_add2_i32
case INDEX_op_add2_i32:
tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
T1 = tci_uint64(regs[r3], regs[r2]);
T2 = tci_uint64(regs[r5], regs[r4]);
tci_write_reg64(regs, r1, r0, T1 + T2);
break;
+#endif
+#if TCG_TARGET_REG_BITS == 32 || TCG_TARGET_HAS_sub2_i32
case INDEX_op_sub2_i32:
tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
T1 = tci_uint64(regs[r3], regs[r2]);
T2 = tci_uint64(regs[r5], regs[r4]);
tci_write_reg64(regs, r1, r0, T1 - T2);
break;
-#endif /* TCG_TARGET_REG_BITS == 32 */
+#endif
#if TCG_TARGET_HAS_mulu2_i32
case INDEX_op_mulu2_i32:
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
@@ -796,6 +793,24 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
muls64(®s[r0], ®s[r1], regs[r2], regs[r3]);
break;
#endif
+#if TCG_TARGET_HAS_add2_i64
+ case INDEX_op_add2_i64:
+ tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
+ T1 = regs[r2] + regs[r4];
+ T2 = regs[r3] + regs[r5] + (T1 < regs[r2]);
+ regs[r0] = T1;
+ regs[r1] = T2;
+ break;
+#endif
+#if TCG_TARGET_HAS_add2_i64
+ case INDEX_op_sub2_i64:
+ tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
+ T1 = regs[r2] - regs[r4];
+ T2 = regs[r3] - regs[r5] - (regs[r2] < regs[r4]);
+ regs[r0] = T1;
+ regs[r1] = T2;
+ break;
+#endif
/* Shift/rotate operations (64 bit). */
@@ -1112,10 +1127,7 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
const char *op_name;
uint32_t insn;
TCGOpcode op;
- TCGReg r0, r1, r2, r3, r4;
-#if TCG_TARGET_REG_BITS == 32
- TCGReg r5;
-#endif
+ TCGReg r0, r1, r2, r3, r4, r5;
tcg_target_ulong i1;
int32_t s2;
TCGCond c;
@@ -1313,15 +1325,15 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
str_r(r2), str_r(r3));
break;
-#if TCG_TARGET_REG_BITS == 32
case INDEX_op_add2_i32:
+ case INDEX_op_add2_i64:
case INDEX_op_sub2_i32:
+ case INDEX_op_sub2_i64:
tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %s",
op_name, str_r(r0), str_r(r1), str_r(r2),
str_r(r3), str_r(r4), str_r(r5));
break;
-#endif
case INDEX_op_qemu_ld_i64:
case INDEX_op_qemu_st_i64:
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
index e617c46366..bb04c326e8 100644
--- a/tcg/tci/tcg-target.c.inc
+++ b/tcg/tci/tcg-target.c.inc
@@ -134,11 +134,13 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_brcond_i64:
return C_O0_I2(r, r);
-#if TCG_TARGET_REG_BITS == 32
- /* TODO: Support R, R, R, R, RI, RI? Will it be faster? */
case INDEX_op_add2_i32:
+ case INDEX_op_add2_i64:
case INDEX_op_sub2_i32:
+ case INDEX_op_sub2_i64:
return C_O2_I4(r, r, r, r, r, r);
+
+#if TCG_TARGET_REG_BITS == 32
case INDEX_op_brcond2_i32:
return C_O0_I4(r, r, r, r);
#endif
@@ -467,7 +469,6 @@ static void tcg_out_op_rrrrrc(TCGContext *s, TCGOpcode op,
tcg_out32(s, insn);
}
-#if TCG_TARGET_REG_BITS == 32
static void tcg_out_op_rrrrrr(TCGContext *s, TCGOpcode op,
TCGReg r0, TCGReg r1, TCGReg r2,
TCGReg r3, TCGReg r4, TCGReg r5)
@@ -483,7 +484,6 @@ static void tcg_out_op_rrrrrr(TCGContext *s, TCGOpcode op,
insn = deposit32(insn, 28, 4, r5);
tcg_out32(s, insn);
}
-#endif
static void tcg_out_ldst(TCGContext *s, TCGOpcode op, TCGReg val,
TCGReg base, intptr_t offset)
@@ -717,12 +717,13 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
tcg_out_op_rr(s, opc, args[0], args[1]);
break;
-#if TCG_TARGET_REG_BITS == 32
- case INDEX_op_add2_i32:
- case INDEX_op_sub2_i32:
+ CASE_32_64(add2)
+ CASE_32_64(sub2)
tcg_out_op_rrrrrr(s, opc, args[0], args[1], args[2],
args[3], args[4], args[5]);
break;
+
+#if TCG_TARGET_REG_BITS == 32
case INDEX_op_brcond2_i32:
tcg_out_op_rrrrrc(s, INDEX_op_setcond2_i32, TCG_REG_TMP,
args[0], args[1], args[2], args[3], args[4]);
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 23/26] tcg/tci: Split out tci_qemu_ld, tci_qemu_st
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (21 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 22/26] tcg/tci: Implement add2, sub2 Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-15 8:56 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 24/26] tests/tcg: Increase timeout for TCI Richard Henderson
` (4 subsequent siblings)
27 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel
Expand the single-use macros into the new functions.
Use cpu_ldsb_mmuidx_ra and cpu_ldsw_le_mmuidx_ra so
that the trace event receives the correct sign flag.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/tci.c | 215 +++++++++++++++++++-----------------------------------
1 file changed, 75 insertions(+), 140 deletions(-)
diff --git a/tcg/tci.c b/tcg/tci.c
index ff096e1e32..a23f813305 100644
--- a/tcg/tci.c
+++ b/tcg/tci.c
@@ -286,34 +286,77 @@ static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
return result;
}
-#define qemu_ld_ub \
- cpu_ldub_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
-#define qemu_ld_leuw \
- cpu_lduw_le_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
-#define qemu_ld_leul \
- cpu_ldl_le_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
-#define qemu_ld_leq \
- cpu_ldq_le_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
-#define qemu_ld_beuw \
- cpu_lduw_be_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
-#define qemu_ld_beul \
- cpu_ldl_be_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
-#define qemu_ld_beq \
- cpu_ldq_be_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
-#define qemu_st_b(X) \
- cpu_stb_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
-#define qemu_st_lew(X) \
- cpu_stw_le_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
-#define qemu_st_lel(X) \
- cpu_stl_le_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
-#define qemu_st_leq(X) \
- cpu_stq_le_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
-#define qemu_st_bew(X) \
- cpu_stw_be_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
-#define qemu_st_bel(X) \
- cpu_stl_be_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
-#define qemu_st_beq(X) \
- cpu_stq_be_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
+static uint64_t tci_qemu_ld(CPUArchState *env, target_ulong taddr,
+ TCGMemOpIdx oi, const void *tb_ptr)
+{
+ uintptr_t ra = (uintptr_t)tb_ptr;
+ int mmu_idx = get_mmuidx(oi);
+ MemOp mop = get_memop(oi);
+
+ switch (mop & (MO_BSWAP | MO_SSIZE)) {
+ case MO_UB:
+ return cpu_ldub_mmuidx_ra(env, taddr, mmu_idx, ra);
+ case MO_SB:
+ return cpu_ldsb_mmuidx_ra(env, taddr, mmu_idx, ra);
+ case MO_LEUW:
+ return cpu_lduw_le_mmuidx_ra(env, taddr, mmu_idx, ra);
+ case MO_BEUW:
+ return cpu_lduw_be_mmuidx_ra(env, taddr, mmu_idx, ra);
+ case MO_LESW:
+ return cpu_ldsw_le_mmuidx_ra(env, taddr, mmu_idx, ra);
+ case MO_BESW:
+ return cpu_ldsw_be_mmuidx_ra(env, taddr, mmu_idx, ra);
+ case MO_LEUL:
+ return cpu_ldl_le_mmuidx_ra(env, taddr, mmu_idx, ra);
+ case MO_BEUL:
+ return cpu_ldl_be_mmuidx_ra(env, taddr, mmu_idx, ra);
+ case MO_LESL:
+ return (int32_t)cpu_ldl_le_mmuidx_ra(env, taddr, mmu_idx, ra);
+ case MO_BESL:
+ return (int32_t)cpu_ldl_be_mmuidx_ra(env, taddr, mmu_idx, ra);
+ case MO_LEQ:
+ return cpu_ldq_le_mmuidx_ra(env, taddr, mmu_idx, ra);
+ case MO_BEQ:
+ return cpu_ldq_be_mmuidx_ra(env, taddr, mmu_idx, ra);
+
+ default:
+ g_assert_not_reached();
+ }
+}
+
+static void tci_qemu_st(CPUArchState *env, target_ulong taddr, uint64_t val,
+ TCGMemOpIdx oi, const void *tb_ptr)
+{
+ uintptr_t ra = (uintptr_t)tb_ptr;
+ int mmu_idx = get_mmuidx(oi);
+ MemOp mop = get_memop(oi);
+
+ switch (mop & (MO_BSWAP | MO_SIZE)) {
+ case MO_UB:
+ cpu_stb_mmuidx_ra(env, taddr, val, mmu_idx, ra);
+ break;
+ case MO_LEUW:
+ cpu_stw_le_mmuidx_ra(env, taddr, val, mmu_idx, ra);
+ break;
+ case MO_BEUW:
+ cpu_stw_be_mmuidx_ra(env, taddr, val, mmu_idx, ra);
+ break;
+ case MO_LEUL:
+ cpu_stl_le_mmuidx_ra(env, taddr, val, mmu_idx, ra);
+ break;
+ case MO_BEUL:
+ cpu_stl_be_mmuidx_ra(env, taddr, val, mmu_idx, ra);
+ break;
+ case MO_LEQ:
+ cpu_stq_le_mmuidx_ra(env, taddr, val, mmu_idx, ra);
+ break;
+ case MO_BEQ:
+ cpu_stq_be_mmuidx_ra(env, taddr, val, mmu_idx, ra);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
#if TCG_TARGET_REG_BITS == 64
# define CASE_32_64(x) \
@@ -906,34 +949,7 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
taddr = tci_uint64(regs[r2], regs[r1]);
}
- switch (get_memop(oi) & (MO_BSWAP | MO_SSIZE)) {
- case MO_UB:
- tmp32 = qemu_ld_ub;
- break;
- case MO_SB:
- tmp32 = (int8_t)qemu_ld_ub;
- break;
- case MO_LEUW:
- tmp32 = qemu_ld_leuw;
- break;
- case MO_LESW:
- tmp32 = (int16_t)qemu_ld_leuw;
- break;
- case MO_LEUL:
- tmp32 = qemu_ld_leul;
- break;
- case MO_BEUW:
- tmp32 = qemu_ld_beuw;
- break;
- case MO_BESW:
- tmp32 = (int16_t)qemu_ld_beuw;
- break;
- case MO_BEUL:
- tmp32 = qemu_ld_beul;
- break;
- default:
- g_assert_not_reached();
- }
+ tmp32 = tci_qemu_ld(env, taddr, oi, tb_ptr);
regs[r0] = tmp32;
break;
@@ -949,46 +965,7 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
taddr = tci_uint64(regs[r3], regs[r2]);
oi = regs[r4];
}
- switch (get_memop(oi) & (MO_BSWAP | MO_SSIZE)) {
- case MO_UB:
- tmp64 = qemu_ld_ub;
- break;
- case MO_SB:
- tmp64 = (int8_t)qemu_ld_ub;
- break;
- case MO_LEUW:
- tmp64 = qemu_ld_leuw;
- break;
- case MO_LESW:
- tmp64 = (int16_t)qemu_ld_leuw;
- break;
- case MO_LEUL:
- tmp64 = qemu_ld_leul;
- break;
- case MO_LESL:
- tmp64 = (int32_t)qemu_ld_leul;
- break;
- case MO_LEQ:
- tmp64 = qemu_ld_leq;
- break;
- case MO_BEUW:
- tmp64 = qemu_ld_beuw;
- break;
- case MO_BESW:
- tmp64 = (int16_t)qemu_ld_beuw;
- break;
- case MO_BEUL:
- tmp64 = qemu_ld_beul;
- break;
- case MO_BESL:
- tmp64 = (int32_t)qemu_ld_beul;
- break;
- case MO_BEQ:
- tmp64 = qemu_ld_beq;
- break;
- default:
- g_assert_not_reached();
- }
+ tmp64 = tci_qemu_ld(env, taddr, oi, tb_ptr);
if (TCG_TARGET_REG_BITS == 32) {
tci_write_reg64(regs, r1, r0, tmp64);
} else {
@@ -1005,25 +982,7 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
taddr = tci_uint64(regs[r2], regs[r1]);
}
tmp32 = regs[r0];
- switch (get_memop(oi) & (MO_BSWAP | MO_SIZE)) {
- case MO_UB:
- qemu_st_b(tmp32);
- break;
- case MO_LEUW:
- qemu_st_lew(tmp32);
- break;
- case MO_LEUL:
- qemu_st_lel(tmp32);
- break;
- case MO_BEUW:
- qemu_st_bew(tmp32);
- break;
- case MO_BEUL:
- qemu_st_bel(tmp32);
- break;
- default:
- g_assert_not_reached();
- }
+ tci_qemu_st(env, taddr, tmp32, oi, tb_ptr);
break;
case INDEX_op_qemu_st_i64:
@@ -1042,31 +1001,7 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
}
tmp64 = tci_uint64(regs[r1], regs[r0]);
}
- switch (get_memop(oi) & (MO_BSWAP | MO_SIZE)) {
- case MO_UB:
- qemu_st_b(tmp64);
- break;
- case MO_LEUW:
- qemu_st_lew(tmp64);
- break;
- case MO_LEUL:
- qemu_st_lel(tmp64);
- break;
- case MO_LEQ:
- qemu_st_leq(tmp64);
- break;
- case MO_BEUW:
- qemu_st_bew(tmp64);
- break;
- case MO_BEUL:
- qemu_st_bel(tmp64);
- break;
- case MO_BEQ:
- qemu_st_beq(tmp64);
- break;
- default:
- g_assert_not_reached();
- }
+ tci_qemu_st(env, taddr, tmp64, oi, tb_ptr);
break;
case INDEX_op_mb:
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 24/26] tests/tcg: Increase timeout for TCI
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (22 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 23/26] tcg/tci: Split out tci_qemu_ld, tci_qemu_st Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-15 9:14 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 25/26] gitlab: Rename ACCEL_CONFIGURE_OPTS to EXTRA_CONFIGURE_OPTS Richard Henderson
` (3 subsequent siblings)
27 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Thomas Huth
The longest test at the moment seems to be a (slower)
aarch64 host, for which test-mmap takes 64 seconds.
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
configure | 3 +++
tests/tcg/Makefile.target | 6 ++++--
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/configure b/configure
index 4f374b4889..c0caa6f42d 100755
--- a/configure
+++ b/configure
@@ -5795,6 +5795,9 @@ fi
if test "$optreset" = "yes" ; then
echo "HAVE_OPTRESET=y" >> $config_host_mak
fi
+if test "$tcg" = "enabled" -a "$tcg_interpreter" = "true" ; then
+ echo "CONFIG_TCG_INTERPRETER=y" >> $config_host_mak
+fi
if test "$fdatasync" = "yes" ; then
echo "CONFIG_FDATASYNC=y" >> $config_host_mak
fi
diff --git a/tests/tcg/Makefile.target b/tests/tcg/Makefile.target
index cab8c6b3a2..29d2291016 100644
--- a/tests/tcg/Makefile.target
+++ b/tests/tcg/Makefile.target
@@ -80,8 +80,10 @@ LDFLAGS=
QEMU_OPTS=
-# If TCG debugging is enabled things are a lot slower
-ifeq ($(CONFIG_DEBUG_TCG),y)
+# If TCG debugging, or TCI is enabled things are a lot slower
+ifneq ($(CONFIG_TCG_INTERPRETER),)
+TIMEOUT=90
+else ifneq ($(CONFIG_DEBUG_TCG),)
TIMEOUT=60
else
TIMEOUT=15
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 25/26] gitlab: Rename ACCEL_CONFIGURE_OPTS to EXTRA_CONFIGURE_OPTS
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (23 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 24/26] tests/tcg: Increase timeout for TCI Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-03 16:21 ` Willian Rampazzo
2021-05-02 23:57 ` [PATCH v6 26/26] gitlab: Enable cross-i386 builds of TCI Richard Henderson
` (2 subsequent siblings)
27 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Thomas Huth
Suggested-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
.gitlab-ci.d/crossbuilds.yml | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/.gitlab-ci.d/crossbuilds.yml b/.gitlab-ci.d/crossbuilds.yml
index 2d95784ed5..fbf7b7a881 100644
--- a/.gitlab-ci.d/crossbuilds.yml
+++ b/.gitlab-ci.d/crossbuilds.yml
@@ -16,7 +16,7 @@
#
# Set the $ACCEL variable to select the specific accelerator (default to
# KVM), and set extra options (such disabling other accelerators) via the
-# $ACCEL_CONFIGURE_OPTS variable.
+# $EXTRA_CONFIGURE_OPTS variable.
.cross_accel_build_job:
stage: build
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:latest
@@ -26,7 +26,7 @@
- cd build
- PKG_CONFIG_PATH=$PKG_CONFIG_PATH
../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
- --disable-tools --enable-${ACCEL:-kvm} $ACCEL_CONFIGURE_OPTS
+ --disable-tools --enable-${ACCEL:-kvm} $EXTRA_CONFIGURE_OPTS
- make -j$(expr $(nproc) + 1) all check-build
.cross_user_build_job:
@@ -174,7 +174,7 @@ cross-s390x-kvm-only:
job: s390x-debian-cross-container
variables:
IMAGE: debian-s390x-cross
- ACCEL_CONFIGURE_OPTS: --disable-tcg
+ EXTRA_CONFIGURE_OPTS: --disable-tcg
cross-win32-system:
extends: .cross_system_build_job
@@ -197,7 +197,7 @@ cross-amd64-xen-only:
variables:
IMAGE: debian-amd64-cross
ACCEL: xen
- ACCEL_CONFIGURE_OPTS: --disable-tcg --disable-kvm
+ EXTRA_CONFIGURE_OPTS: --disable-tcg --disable-kvm
cross-arm64-xen-only:
extends: .cross_accel_build_job
@@ -206,4 +206,4 @@ cross-arm64-xen-only:
variables:
IMAGE: debian-arm64-cross
ACCEL: xen
- ACCEL_CONFIGURE_OPTS: --disable-tcg --disable-kvm
+ EXTRA_CONFIGURE_OPTS: --disable-tcg --disable-kvm
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [PATCH v6 26/26] gitlab: Enable cross-i386 builds of TCI
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (24 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 25/26] gitlab: Rename ACCEL_CONFIGURE_OPTS to EXTRA_CONFIGURE_OPTS Richard Henderson
@ 2021-05-02 23:57 ` Richard Henderson
2021-05-03 16:22 ` Willian Rampazzo
2021-05-03 0:30 ` [PATCH v6 00/26] TCI fixes and cleanups no-reply
2021-05-15 11:01 ` Philippe Mathieu-Daudé
27 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-05-02 23:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Thomas Huth, Philippe Mathieu-Daudé
We're currently only testing TCI with a 64-bit host -- also test
with a 32-bit host. Enable a selection of softmmu and user-only
targets, 32-bit LE, 64-bit LE, 32-bit BE, as there are ifdefs for each.
Acked-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
.gitlab-ci.d/crossbuilds.yml | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/.gitlab-ci.d/crossbuilds.yml b/.gitlab-ci.d/crossbuilds.yml
index fbf7b7a881..bbf3cccf6d 100644
--- a/.gitlab-ci.d/crossbuilds.yml
+++ b/.gitlab-ci.d/crossbuilds.yml
@@ -27,7 +27,7 @@
- PKG_CONFIG_PATH=$PKG_CONFIG_PATH
../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
--disable-tools --enable-${ACCEL:-kvm} $EXTRA_CONFIGURE_OPTS
- - make -j$(expr $(nproc) + 1) all check-build
+ - make -j$(expr $(nproc) + 1) all check-build $MAKE_CHECK_ARGS
.cross_user_build_job:
stage: build
@@ -98,6 +98,15 @@ cross-i386-user:
IMAGE: fedora-i386-cross
MAKE_CHECK_ARGS: check
+cross-i386-tci:
+ extends: .cross_accel_build_job
+ timeout: 60m
+ variables:
+ IMAGE: fedora-i386-cross
+ ACCEL: tcg-interpreter
+ EXTRA_CONFIGURE_OPTS: --target-list=i386-softmmu,i386-linux-user,aarch64-softmmu,aarch64-linux-user,ppc-softmmu,ppc-linux-user
+ MAKE_CHECK_ARGS: check check-tcg
+
cross-mips-system:
extends: .cross_system_build_job
needs:
--
2.25.1
^ permalink raw reply related [flat|nested] 53+ messages in thread
* Re: [PATCH v6 00/26] TCI fixes and cleanups
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (25 preceding siblings ...)
2021-05-02 23:57 ` [PATCH v6 26/26] gitlab: Enable cross-i386 builds of TCI Richard Henderson
@ 2021-05-03 0:30 ` no-reply
2021-05-15 11:01 ` Philippe Mathieu-Daudé
27 siblings, 0 replies; 53+ messages in thread
From: no-reply @ 2021-05-03 0:30 UTC (permalink / raw)
To: richard.henderson; +Cc: qemu-devel
Patchew URL: https://patchew.org/QEMU/20210502235727.1979457-1-richard.henderson@linaro.org/
Hi,
This series seems to have some coding style problems. See output below for
more information:
Type: series
Message-id: 20210502235727.1979457-1-richard.henderson@linaro.org
Subject: [PATCH v6 00/26] TCI fixes and cleanups
=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
* [new tag] patchew/20210502235727.1979457-1-richard.henderson@linaro.org -> patchew/20210502235727.1979457-1-richard.henderson@linaro.org
Switched to a new branch 'test'
01e0405 gitlab: Enable cross-i386 builds of TCI
1882510 gitlab: Rename ACCEL_CONFIGURE_OPTS to EXTRA_CONFIGURE_OPTS
b56eadf tests/tcg: Increase timeout for TCI
fdb1066 tcg/tci: Split out tci_qemu_ld, tci_qemu_st
d6605fd tcg/tci: Implement add2, sub2
f04d4f3 tcg/tci: Implement mulu2, muls2
69fad15 tcg/tci: Implement clz, ctz, ctpop
2fbf686 tcg/tci: Implement extract, sextract
efab217 tcg/tci: Implement andc, orc, eqv, nand, nor
d9aa439 tcg/tci: Implement movcond
2de969d tcg/tci: Implement goto_ptr
64e5e70 tcg/tci: Change encoding to uint32_t units
b1796e1 tcg/tci: Remove tci_write_reg
0e6573e tcg/tci: Emit setcond before brcond
950bc0a tcg/tci: Reserve r13 for a temporary
08cbe1b tcg/tci: Use ffi for calls
53c1179 tcg/tci: Move call-return regs to end of tcg_target_reg_alloc_order
d92a4d6 tcg/tci: Improve tcg_target_call_clobber_regs
e8011a7 tcg: Build ffi data structures for helpers
d93a2d9 tcg: Add tcg_call_func
5667907 tcg: Store the TCGHelperInfo in the TCGOp for call
1d862ba accel/tcg: Add tcg call flags to plugins helpers
b48239a plugins: Drop tcg_flags from struct qemu_plugin_dyn_cb
12c1809 accel/tcg/plugin-gen: Drop inline markers
193076d tcg: Add tcg_call_flags
fb7be00 tcg: Combine dh_is_64bit and dh_is_signed to dh_typecode
=== OUTPUT BEGIN ===
1/26 Checking commit fb7be0073c11 (tcg: Combine dh_is_64bit and dh_is_signed to dh_typecode)
2/26 Checking commit 193076de086e (tcg: Add tcg_call_flags)
Use of uninitialized value $acpi_testexpected in string eq at ./scripts/checkpatch.pl line 1529.
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#19:
new file mode 100644
total: 0 errors, 1 warnings, 106 lines checked
Patch 2/26 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
3/26 Checking commit 12c18093b594 (accel/tcg/plugin-gen: Drop inline markers)
4/26 Checking commit b48239a1927f (plugins: Drop tcg_flags from struct qemu_plugin_dyn_cb)
5/26 Checking commit 1d862ba71caf (accel/tcg: Add tcg call flags to plugins helpers)
WARNING: line over 80 characters
#25: FILE: accel/tcg/plugin-helpers.h:3:
+DEF_HELPER_FLAGS_4(plugin_vcpu_mem_cb, TCG_CALL_NO_RWG, void, i32, i32, i64, ptr)
total: 0 errors, 1 warnings, 6 lines checked
Patch 5/26 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
6/26 Checking commit 56679077d311 (tcg: Store the TCGHelperInfo in the TCGOp for call)
7/26 Checking commit d93a2d98c62c (tcg: Add tcg_call_func)
8/26 Checking commit e8011a77992c (tcg: Build ffi data structures for helpers)
9/26 Checking commit d92a4d6f27e0 (tcg/tci: Improve tcg_target_call_clobber_regs)
10/26 Checking commit 53c117942812 (tcg/tci: Move call-return regs to end of tcg_target_reg_alloc_order)
11/26 Checking commit 08cbe1bb1ba1 (tcg/tci: Use ffi for calls)
ERROR: suspect code indent for conditional statements (8, 11)
#72: FILE: tcg/tcg.c:2150:
if (TCG_TARGET_REG_BITS < 64 && is_64bit) {
+ /*
total: 1 errors, 0 warnings, 391 lines checked
Patch 11/26 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
12/26 Checking commit 950bc0a4007a (tcg/tci: Reserve r13 for a temporary)
13/26 Checking commit 0e6573ef0b75 (tcg/tci: Emit setcond before brcond)
14/26 Checking commit b1796e1da907 (tcg/tci: Remove tci_write_reg)
15/26 Checking commit 64e5e709764e (tcg/tci: Change encoding to uint32_t units)
16/26 Checking commit 2de969d06521 (tcg/tci: Implement goto_ptr)
17/26 Checking commit d9aa4393024b (tcg/tci: Implement movcond)
18/26 Checking commit efab21772da5 (tcg/tci: Implement andc, orc, eqv, nand, nor)
19/26 Checking commit 2fbf6868c5d3 (tcg/tci: Implement extract, sextract)
20/26 Checking commit 69fad1503f75 (tcg/tci: Implement clz, ctz, ctpop)
21/26 Checking commit f04d4f3e8da6 (tcg/tci: Implement mulu2, muls2)
22/26 Checking commit d6605fd6acb8 (tcg/tci: Implement add2, sub2)
23/26 Checking commit fdb1066aa804 (tcg/tci: Split out tci_qemu_ld, tci_qemu_st)
24/26 Checking commit b56eadf97378 (tests/tcg: Increase timeout for TCI)
25/26 Checking commit 188251027a70 (gitlab: Rename ACCEL_CONFIGURE_OPTS to EXTRA_CONFIGURE_OPTS)
26/26 Checking commit 01e0405a5819 (gitlab: Enable cross-i386 builds of TCI)
=== OUTPUT END ===
Test command exited with code: 1
The full log is available at
http://patchew.org/logs/20210502235727.1979457-1-richard.henderson@linaro.org/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 25/26] gitlab: Rename ACCEL_CONFIGURE_OPTS to EXTRA_CONFIGURE_OPTS
2021-05-02 23:57 ` [PATCH v6 25/26] gitlab: Rename ACCEL_CONFIGURE_OPTS to EXTRA_CONFIGURE_OPTS Richard Henderson
@ 2021-05-03 16:21 ` Willian Rampazzo
0 siblings, 0 replies; 53+ messages in thread
From: Willian Rampazzo @ 2021-05-03 16:21 UTC (permalink / raw)
To: Richard Henderson; +Cc: Thomas Huth, qemu-devel
On Sun, May 2, 2021 at 9:24 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Suggested-by: Thomas Huth <thuth@redhat.com>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> .gitlab-ci.d/crossbuilds.yml | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
> diff --git a/.gitlab-ci.d/crossbuilds.yml b/.gitlab-ci.d/crossbuilds.yml
> index 2d95784ed5..fbf7b7a881 100644
> --- a/.gitlab-ci.d/crossbuilds.yml
> +++ b/.gitlab-ci.d/crossbuilds.yml
> @@ -16,7 +16,7 @@
> #
> # Set the $ACCEL variable to select the specific accelerator (default to
> # KVM), and set extra options (such disabling other accelerators) via the
> -# $ACCEL_CONFIGURE_OPTS variable.
> +# $EXTRA_CONFIGURE_OPTS variable.
> .cross_accel_build_job:
> stage: build
> image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:latest
> @@ -26,7 +26,7 @@
> - cd build
> - PKG_CONFIG_PATH=$PKG_CONFIG_PATH
> ../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
> - --disable-tools --enable-${ACCEL:-kvm} $ACCEL_CONFIGURE_OPTS
> + --disable-tools --enable-${ACCEL:-kvm} $EXTRA_CONFIGURE_OPTS
> - make -j$(expr $(nproc) + 1) all check-build
>
> .cross_user_build_job:
> @@ -174,7 +174,7 @@ cross-s390x-kvm-only:
> job: s390x-debian-cross-container
> variables:
> IMAGE: debian-s390x-cross
> - ACCEL_CONFIGURE_OPTS: --disable-tcg
> + EXTRA_CONFIGURE_OPTS: --disable-tcg
>
> cross-win32-system:
> extends: .cross_system_build_job
> @@ -197,7 +197,7 @@ cross-amd64-xen-only:
> variables:
> IMAGE: debian-amd64-cross
> ACCEL: xen
> - ACCEL_CONFIGURE_OPTS: --disable-tcg --disable-kvm
> + EXTRA_CONFIGURE_OPTS: --disable-tcg --disable-kvm
>
> cross-arm64-xen-only:
> extends: .cross_accel_build_job
> @@ -206,4 +206,4 @@ cross-arm64-xen-only:
> variables:
> IMAGE: debian-arm64-cross
> ACCEL: xen
> - ACCEL_CONFIGURE_OPTS: --disable-tcg --disable-kvm
> + EXTRA_CONFIGURE_OPTS: --disable-tcg --disable-kvm
> --
> 2.25.1
>
>
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 26/26] gitlab: Enable cross-i386 builds of TCI
2021-05-02 23:57 ` [PATCH v6 26/26] gitlab: Enable cross-i386 builds of TCI Richard Henderson
@ 2021-05-03 16:22 ` Willian Rampazzo
0 siblings, 0 replies; 53+ messages in thread
From: Willian Rampazzo @ 2021-05-03 16:22 UTC (permalink / raw)
To: Richard Henderson; +Cc: Thomas Huth, qemu-devel, Philippe Mathieu-Daudé
On Sun, May 2, 2021 at 9:14 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> We're currently only testing TCI with a 64-bit host -- also test
> with a 32-bit host. Enable a selection of softmmu and user-only
> targets, 32-bit LE, 64-bit LE, 32-bit BE, as there are ifdefs for each.
>
> Acked-by: Thomas Huth <thuth@redhat.com>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> .gitlab-ci.d/crossbuilds.yml | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 02/26] tcg: Add tcg_call_flags
2021-05-02 23:57 ` [PATCH v6 02/26] tcg: Add tcg_call_flags Richard Henderson
@ 2021-05-03 21:39 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-05-03 21:39 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/21 1:57 AM, Richard Henderson wrote:
> We're going to change how to look up the call flags from a TCGop,
> so extract it as a helper.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> tcg/internal.h | 33 +++++++++++++++++++++++++++++++++
> tcg/optimize.c | 3 ++-
> tcg/tcg.c | 15 +++++++--------
> 3 files changed, 42 insertions(+), 9 deletions(-)
> create mode 100644 tcg/internal.h
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 03/26] accel/tcg/plugin-gen: Drop inline markers
2021-05-02 23:57 ` [PATCH v6 03/26] accel/tcg/plugin-gen: Drop inline markers Richard Henderson
@ 2021-05-03 21:40 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-05-03 21:40 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/21 1:57 AM, Richard Henderson wrote:
> Let the compiler decide on inlining.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> accel/tcg/plugin-gen.c | 12 +++++-------
> 1 file changed, 5 insertions(+), 7 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 07/26] tcg: Add tcg_call_func
2021-05-02 23:57 ` [PATCH v6 07/26] tcg: Add tcg_call_func Richard Henderson
@ 2021-05-03 21:50 ` Philippe Mathieu-Daudé
2021-05-16 1:21 ` Richard Henderson
0 siblings, 1 reply; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-05-03 21:50 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
Hi Richard,
On 5/3/21 1:57 AM, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> tcg/internal.h | 5 +++++
> tcg/tcg.c | 5 ++---
> 2 files changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/tcg/internal.h b/tcg/internal.h
> index c2d5e9c42f..cd128e2a83 100644
> --- a/tcg/internal.h
> +++ b/tcg/internal.h
> @@ -32,6 +32,11 @@ typedef struct TCGHelperInfo {
> unsigned typemask;
> } TCGHelperInfo;
>
> +static inline void *tcg_call_func(TCGOp *op)
> +{
> + return (void *)(uintptr_t)op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op)];
Why not return tcg_insn_unit* type?
> +}
> +
> static inline const TCGHelperInfo *tcg_call_info(TCGOp *op)
> {
> return (void *)(uintptr_t)op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op) + 1];
> diff --git a/tcg/tcg.c b/tcg/tcg.c
> index d42fa6c956..1e5e165bff 100644
> --- a/tcg/tcg.c
> +++ b/tcg/tcg.c
> @@ -2310,7 +2310,7 @@ static void tcg_dump_ops(TCGContext *s, bool have_prefs)
> }
> } else if (c == INDEX_op_call) {
> const TCGHelperInfo *info = tcg_call_info(op);
> - void *func;
> + void *func = tcg_call_func(op);
>
> /* variable number of arguments */
> nb_oargs = TCGOP_CALLO(op);
> @@ -2324,7 +2324,6 @@ static void tcg_dump_ops(TCGContext *s, bool have_prefs)
> * Note that plugins have a template function for the info,
> * but the actual function pointer comes from the plugin.
> */
> - func = (void *)(uintptr_t)op->args[nb_oargs + nb_iargs];
> if (func == info->func) {
> col += qemu_log("%s", info->name);
> } else {
> @@ -4346,7 +4345,7 @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
> int allocate_args;
> TCGRegSet allocated_regs;
>
> - func_addr = (tcg_insn_unit *)(intptr_t)op->args[nb_oargs + nb_iargs];
> + func_addr = tcg_call_func(op);
> flags = tcg_call_flags(op);
>
> nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
>
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 14/26] tcg/tci: Remove tci_write_reg
2021-05-02 23:57 ` [PATCH v6 14/26] tcg/tci: Remove tci_write_reg Richard Henderson
@ 2021-05-03 21:53 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-05-03 21:53 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/21 1:57 AM, Richard Henderson wrote:
> Inline it into its one caller, tci_write_reg64.
> Drop the asserts that are redundant with tcg_read_r.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> tcg/tci.c | 13 ++-----------
> 1 file changed, 2 insertions(+), 11 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 19/26] tcg/tci: Implement extract, sextract
2021-05-02 23:57 ` [PATCH v6 19/26] tcg/tci: Implement extract, sextract Richard Henderson
@ 2021-05-03 22:04 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-05-03 22:04 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/21 1:57 AM, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> tcg/tci/tcg-target.h | 8 ++++----
> tcg/tci.c | 42 ++++++++++++++++++++++++++++++++++++++++
> tcg/tci/tcg-target.c.inc | 32 ++++++++++++++++++++++++++++++
> 3 files changed, 78 insertions(+), 4 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 20/26] tcg/tci: Implement clz, ctz, ctpop
2021-05-02 23:57 ` [PATCH v6 20/26] tcg/tci: Implement clz, ctz, ctpop Richard Henderson
@ 2021-05-03 22:10 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-05-03 22:10 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/21 1:57 AM, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> tcg/tci/tcg-target.h | 12 +++++------
> tcg/tci.c | 44 ++++++++++++++++++++++++++++++++++++++++
> tcg/tci/tcg-target.c.inc | 9 ++++++++
> 3 files changed, 59 insertions(+), 6 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 18/26] tcg/tci: Implement andc, orc, eqv, nand, nor
2021-05-02 23:57 ` [PATCH v6 18/26] tcg/tci: Implement andc, orc, eqv, nand, nor Richard Henderson
@ 2021-05-03 22:13 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-05-03 22:13 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/21 1:57 AM, Richard Henderson wrote:
> These were already present in tcg-target.c.inc,
> but not in the interpreter.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> tcg/tci/tcg-target.h | 20 ++++++++++----------
> tcg/tci.c | 40 ++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 50 insertions(+), 10 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 23/26] tcg/tci: Split out tci_qemu_ld, tci_qemu_st
2021-05-02 23:57 ` [PATCH v6 23/26] tcg/tci: Split out tci_qemu_ld, tci_qemu_st Richard Henderson
@ 2021-05-15 8:56 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-05-15 8:56 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/21 1:57 AM, Richard Henderson wrote:
> Expand the single-use macros into the new functions.
> Use cpu_ldsb_mmuidx_ra and cpu_ldsw_le_mmuidx_ra so
> that the trace event receives the correct sign flag.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> tcg/tci.c | 215 +++++++++++++++++++-----------------------------------
> 1 file changed, 75 insertions(+), 140 deletions(-)
Nice simplification.
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 06/26] tcg: Store the TCGHelperInfo in the TCGOp for call
2021-05-02 23:57 ` [PATCH v6 06/26] tcg: Store the TCGHelperInfo in the TCGOp for call Richard Henderson
@ 2021-05-15 9:00 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-05-15 9:00 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/21 1:57 AM, Richard Henderson wrote:
> This will give us both flags and typemask for use later.
>
> We also fix a dumping bug, wherein calls generated for plugins
> fail tcg_find_helper and print (null) instead of either a name
> or the raw function pointer.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> tcg/internal.h | 14 +++++++++++++-
> tcg/tcg.c | 49 +++++++++++++++++++++----------------------------
> 2 files changed, 34 insertions(+), 29 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 10/26] tcg/tci: Move call-return regs to end of tcg_target_reg_alloc_order
2021-05-02 23:57 ` [PATCH v6 10/26] tcg/tci: Move call-return regs to end of tcg_target_reg_alloc_order Richard Henderson
@ 2021-05-15 9:01 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-05-15 9:01 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/21 1:57 AM, Richard Henderson wrote:
> As the only call-clobbered regs for TCI, these should
> receive the least priority.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> tcg/tci/tcg-target.c.inc | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 05/26] accel/tcg: Add tcg call flags to plugins helpers
2021-05-02 23:57 ` [PATCH v6 05/26] accel/tcg: Add tcg call flags to plugins helpers Richard Henderson
@ 2021-05-15 9:02 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-05-15 9:02 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: Alex Bennée
On 5/3/21 1:57 AM, Richard Henderson wrote:
> As noted by qemu-plugins.h, plugins can neither read nor write
> guest registers.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> accel/tcg/plugin-helpers.h | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/accel/tcg/plugin-helpers.h b/accel/tcg/plugin-helpers.h
> index 853bd21677..9829abe4a9 100644
> --- a/accel/tcg/plugin-helpers.h
> +++ b/accel/tcg/plugin-helpers.h
> @@ -1,4 +1,4 @@
> #ifdef CONFIG_PLUGIN
> -DEF_HELPER_2(plugin_vcpu_udata_cb, void, i32, ptr)
> -DEF_HELPER_4(plugin_vcpu_mem_cb, void, i32, i32, i64, ptr)
> +DEF_HELPER_FLAGS_2(plugin_vcpu_udata_cb, TCG_CALL_NO_RWG, void, i32, ptr)
> +DEF_HELPER_FLAGS_4(plugin_vcpu_mem_cb, TCG_CALL_NO_RWG, void, i32, i32, i64, ptr)
> #endif
>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 01/26] tcg: Combine dh_is_64bit and dh_is_signed to dh_typecode
2021-05-02 23:57 ` [PATCH v6 01/26] tcg: Combine dh_is_64bit and dh_is_signed to dh_typecode Richard Henderson
@ 2021-05-15 9:10 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-05-15 9:10 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/21 1:57 AM, Richard Henderson wrote:
> We will shortly be interested in distinguishing pointers
> from integers in the helper's declaration, as well as a
> true void return. We currently have two parallel 1 bit
> fields; merge them and expand to a 3 bit field.
>
> Our current maximum is 7 helper arguments, plus the return
> makes 8 * 3 = 24 bits used within the uint32_t typemask.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> include/exec/helper-head.h | 37 +++++--------------
> include/exec/helper-tcg.h | 34 ++++++++---------
> target/hppa/helper.h | 3 --
> target/i386/ops_sse_header.h | 3 --
> target/m68k/helper.h | 1 -
> target/ppc/helper.h | 3 --
> tcg/tcg.c | 71 +++++++++++++++++++++---------------
> 7 files changed, 67 insertions(+), 85 deletions(-)
Nice. I've been looking for a definition name for the heavily
used magic '3', but using such definitions doesn't really
help in the code review, so we are better without it.
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 24/26] tests/tcg: Increase timeout for TCI
2021-05-02 23:57 ` [PATCH v6 24/26] tests/tcg: Increase timeout for TCI Richard Henderson
@ 2021-05-15 9:14 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-05-15 9:14 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: Thomas Huth
On 5/3/21 1:57 AM, Richard Henderson wrote:
> The longest test at the moment seems to be a (slower)
> aarch64 host, for which test-mmap takes 64 seconds.
>
> Reviewed-by: Thomas Huth <thuth@redhat.com>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> configure | 3 +++
> tests/tcg/Makefile.target | 6 ++++--
> 2 files changed, 7 insertions(+), 2 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 17/26] tcg/tci: Implement movcond
2021-05-02 23:57 ` [PATCH v6 17/26] tcg/tci: Implement movcond Richard Henderson
@ 2021-05-15 9:34 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-05-15 9:34 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/21 1:57 AM, Richard Henderson wrote:
> When this opcode is not available in the backend, tcg middle-end
> will expand this as a series of 5 opcodes. So implementing this
> saves bytecode space.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> tcg/tci/tcg-target.h | 4 ++--
> tcg/tci.c | 16 +++++++++++++++-
> tcg/tci/tcg-target.c.inc | 10 +++++++---
> 3 files changed, 24 insertions(+), 6 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 00/26] TCI fixes and cleanups
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
` (26 preceding siblings ...)
2021-05-03 0:30 ` [PATCH v6 00/26] TCI fixes and cleanups no-reply
@ 2021-05-15 11:01 ` Philippe Mathieu-Daudé
27 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-05-15 11:01 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/21 1:57 AM, Richard Henderson wrote:
> Richard Henderson (26):
> tcg: Combine dh_is_64bit and dh_is_signed to dh_typecode
> tcg: Add tcg_call_flags
> accel/tcg/plugin-gen: Drop inline markers
> plugins: Drop tcg_flags from struct qemu_plugin_dyn_cb
> accel/tcg: Add tcg call flags to plugins helpers
> tcg: Store the TCGHelperInfo in the TCGOp for call
> tcg: Add tcg_call_func
> tcg: Build ffi data structures for helpers
> tcg/tci: Improve tcg_target_call_clobber_regs
> tcg/tci: Move call-return regs to end of tcg_target_reg_alloc_order
> tcg/tci: Use ffi for calls
> tcg/tci: Reserve r13 for a temporary
> tcg/tci: Emit setcond before brcond
> tcg/tci: Remove tci_write_reg
> tcg/tci: Change encoding to uint32_t units
> tcg/tci: Implement goto_ptr
> tcg/tci: Implement movcond
> tcg/tci: Implement andc, orc, eqv, nand, nor
> tcg/tci: Implement extract, sextract
> tcg/tci: Implement clz, ctz, ctpop
> tcg/tci: Implement mulu2, muls2
> tcg/tci: Implement add2, sub2
> tcg/tci: Split out tci_qemu_ld, tci_qemu_st
Patches 1 to 23:
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
(using parisc host).
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 07/26] tcg: Add tcg_call_func
2021-05-03 21:50 ` Philippe Mathieu-Daudé
@ 2021-05-16 1:21 ` Richard Henderson
2021-05-16 12:48 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 53+ messages in thread
From: Richard Henderson @ 2021-05-16 1:21 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
On 5/3/21 4:50 PM, Philippe Mathieu-Daudé wrote:
> Hi Richard,
>
> On 5/3/21 1:57 AM, Richard Henderson wrote:
>> Signed-off-by: Richard Henderson<richard.henderson@linaro.org>
>> ---
>> tcg/internal.h | 5 +++++
>> tcg/tcg.c | 5 ++---
>> 2 files changed, 7 insertions(+), 3 deletions(-)
>>
>> diff --git a/tcg/internal.h b/tcg/internal.h
>> index c2d5e9c42f..cd128e2a83 100644
>> --- a/tcg/internal.h
>> +++ b/tcg/internal.h
>> @@ -32,6 +32,11 @@ typedef struct TCGHelperInfo {
>> unsigned typemask;
>> } TCGHelperInfo;
>>
>> +static inline void *tcg_call_func(TCGOp *op)
>> +{
>> + return (void *)(uintptr_t)op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op)];
> Why not return tcg_insn_unit* type?
That's a fairly tcg code generation type -- this is used for more than that. I
think it's more natural to use void* when we don't know what the real type.
r~
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 07/26] tcg: Add tcg_call_func
2021-05-16 1:21 ` Richard Henderson
@ 2021-05-16 12:48 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-05-16 12:48 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/16/21 3:21 AM, Richard Henderson wrote:
> On 5/3/21 4:50 PM, Philippe Mathieu-Daudé wrote:
>> Hi Richard,
>>
>> On 5/3/21 1:57 AM, Richard Henderson wrote:
>>> Signed-off-by: Richard Henderson<richard.henderson@linaro.org>
>>> ---
>>> tcg/internal.h | 5 +++++
>>> tcg/tcg.c | 5 ++---
>>> 2 files changed, 7 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/tcg/internal.h b/tcg/internal.h
>>> index c2d5e9c42f..cd128e2a83 100644
>>> --- a/tcg/internal.h
>>> +++ b/tcg/internal.h
>>> @@ -32,6 +32,11 @@ typedef struct TCGHelperInfo {
>>> unsigned typemask;
>>> } TCGHelperInfo;
>>> +static inline void *tcg_call_func(TCGOp *op)
>>> +{
>>> + return (void *)(uintptr_t)op->args[TCGOP_CALLO(op) +
>>> TCGOP_CALLI(op)];
>> Why not return tcg_insn_unit* type?
>
> That's a fairly tcg code generation type -- this is used for more than
> that. I think it's more natural to use void* when we don't know what
> the real type.
OK.
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 04/26] plugins: Drop tcg_flags from struct qemu_plugin_dyn_cb
2021-05-02 23:57 ` [PATCH v6 04/26] plugins: Drop tcg_flags from struct qemu_plugin_dyn_cb Richard Henderson
@ 2021-05-16 12:53 ` Philippe Mathieu-Daudé
2021-05-17 16:13 ` Richard Henderson
0 siblings, 1 reply; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-05-16 12:53 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
Hi Richard,
On 5/3/21 1:57 AM, Richard Henderson wrote:
> As noted by qemu-plugins.h, enum qemu_plugin_cb_flags is
> currently unused -- plugins can neither read nor write
> guest registers.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> accel/tcg/plugin-helpers.h | 1 -
> include/qemu/plugin.h | 1 -
> accel/tcg/plugin-gen.c | 8 ++++----
> plugins/core.c | 30 ++++++------------------------
> 4 files changed, 10 insertions(+), 30 deletions(-)
>
> diff --git a/accel/tcg/plugin-helpers.h b/accel/tcg/plugin-helpers.h
> index 1916ee7920..853bd21677 100644
> --- a/accel/tcg/plugin-helpers.h
> +++ b/accel/tcg/plugin-helpers.h
> @@ -1,5 +1,4 @@
> #ifdef CONFIG_PLUGIN
> -/* Note: no TCG flags because those are overwritten later */
> DEF_HELPER_2(plugin_vcpu_udata_cb, void, i32, ptr)
> DEF_HELPER_4(plugin_vcpu_mem_cb, void, i32, i32, i64, ptr)
> #endif
> diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
> index c5a79a89f0..0fefbc6084 100644
> --- a/include/qemu/plugin.h
> +++ b/include/qemu/plugin.h
> @@ -79,7 +79,6 @@ enum plugin_dyn_cb_subtype {
> struct qemu_plugin_dyn_cb {
> union qemu_plugin_cb_sig f;
> void *userp;
> - unsigned tcg_flags;
> enum plugin_dyn_cb_subtype type;
> /* @rw applies to mem callbacks only (both regular and inline) */
> enum qemu_plugin_mem_rw rw;
> diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
> index eb99be52d0..1e7f201cd2 100644
> --- a/accel/tcg/plugin-gen.c
> +++ b/accel/tcg/plugin-gen.c
> @@ -385,7 +385,7 @@ static TCGOp *copy_st_ptr(TCGOp **begin_op, TCGOp *op)
> }
>
> static TCGOp *copy_call(TCGOp **begin_op, TCGOp *op, void *empty_func,
> - void *func, unsigned tcg_flags, int *cb_idx)
> + void *func, int *cb_idx)
> {
> /* copy all ops until the call */
> do {
> @@ -412,7 +412,7 @@ static TCGOp *copy_call(TCGOp **begin_op, TCGOp *op, void *empty_func,
> tcg_debug_assert(i < MAX_OPC_PARAM_ARGS);
> }
> op->args[*cb_idx] = (uintptr_t)func;
> - op->args[*cb_idx + 1] = tcg_flags;
> + op->args[*cb_idx + 1] = (*begin_op)->args[*cb_idx + 1];
I don't understand this change, can you explain?
>
> return op;
> }
> @@ -439,7 +439,7 @@ static TCGOp *append_udata_cb(const struct qemu_plugin_dyn_cb *cb,
>
> /* call */
> op = copy_call(&begin_op, op, HELPER(plugin_vcpu_udata_cb),
> - cb->f.vcpu_udata, cb->tcg_flags, cb_idx);
> + cb->f.vcpu_udata, cb_idx);
>
> return op;
> }
> @@ -490,7 +490,7 @@ static TCGOp *append_mem_cb(const struct qemu_plugin_dyn_cb *cb,
> if (type == PLUGIN_GEN_CB_MEM) {
> /* call */
> op = copy_call(&begin_op, op, HELPER(plugin_vcpu_mem_cb),
> - cb->f.vcpu_udata, cb->tcg_flags, cb_idx);
> + cb->f.vcpu_udata, cb_idx);
> }
>
> return op;
> diff --git a/plugins/core.c b/plugins/core.c
> index 87b823bbc4..03e0a4c806 100644
> --- a/plugins/core.c
> +++ b/plugins/core.c
> @@ -297,33 +297,15 @@ void plugin_register_inline_op(GArray **arr,
> dyn_cb->inline_insn.imm = imm;
> }
>
> -static inline uint32_t cb_to_tcg_flags(enum qemu_plugin_cb_flags flags)
> -{
> - uint32_t ret;
> -
> - switch (flags) {
> - case QEMU_PLUGIN_CB_RW_REGS:
> - ret = 0;
> - break;
> - case QEMU_PLUGIN_CB_R_REGS:
> - ret = TCG_CALL_NO_WG;
> - break;
> - case QEMU_PLUGIN_CB_NO_REGS:
> - default:
> - ret = TCG_CALL_NO_RWG;
> - }
> - return ret;
> -}
> -
> -inline void
> -plugin_register_dyn_cb__udata(GArray **arr,
> - qemu_plugin_vcpu_udata_cb_t cb,
> - enum qemu_plugin_cb_flags flags, void *udata)
> +void plugin_register_dyn_cb__udata(GArray **arr,
> + qemu_plugin_vcpu_udata_cb_t cb,
> + enum qemu_plugin_cb_flags flags,
> + void *udata)
> {
> struct qemu_plugin_dyn_cb *dyn_cb = plugin_get_dyn_cb(arr);
>
> dyn_cb->userp = udata;
> - dyn_cb->tcg_flags = cb_to_tcg_flags(flags);
> + /* Note flags are discarded as unused. */
> dyn_cb->f.vcpu_udata = cb;
> dyn_cb->type = PLUGIN_CB_REGULAR;
> }
> @@ -338,7 +320,7 @@ void plugin_register_vcpu_mem_cb(GArray **arr,
>
> dyn_cb = plugin_get_dyn_cb(arr);
> dyn_cb->userp = udata;
> - dyn_cb->tcg_flags = cb_to_tcg_flags(flags);
> + /* Note flags are discarded as unused. */
> dyn_cb->type = PLUGIN_CB_REGULAR;
> dyn_cb->rw = rw;
> dyn_cb->f.generic = cb;
>
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 04/26] plugins: Drop tcg_flags from struct qemu_plugin_dyn_cb
2021-05-16 12:53 ` Philippe Mathieu-Daudé
@ 2021-05-17 16:13 ` Richard Henderson
0 siblings, 0 replies; 53+ messages in thread
From: Richard Henderson @ 2021-05-17 16:13 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
On 5/16/21 7:53 AM, Philippe Mathieu-Daudé wrote:
>> - op->args[*cb_idx + 1] = tcg_flags;
>> + op->args[*cb_idx + 1] = (*begin_op)->args[*cb_idx + 1];
>
> I don't understand this change, can you explain?
This patch drops a mostly-unimplemented feature from plugins, where in theory
the registration of the plugin would specify the TCG_CALL_* flags.
Instead, take the flags from the plugin template function -- i.e. copy them
across from the original begin_op.
>> -static inline uint32_t cb_to_tcg_flags(enum qemu_plugin_cb_flags flags)
>> -{
>> - uint32_t ret;
>> -
>> - switch (flags) {
>> - case QEMU_PLUGIN_CB_RW_REGS:
>> - ret = 0;
>> - break;
>> - case QEMU_PLUGIN_CB_R_REGS:
>> - ret = TCG_CALL_NO_WG;
>> - break;
>> - case QEMU_PLUGIN_CB_NO_REGS:
>> - default:
>> - ret = TCG_CALL_NO_RWG;
>> - }
>> - return ret;
>> -}
This is where the plugin interface was supposed to convert flags from one form
to another. This got stored in a structure and then passed along as an
argument to the function containing that first hunk above.
r~
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 08/26] tcg: Build ffi data structures for helpers
2021-05-02 23:57 ` [PATCH v6 08/26] tcg: Build ffi data structures for helpers Richard Henderson
@ 2021-05-31 18:55 ` Philippe Mathieu-Daudé
2021-06-01 14:33 ` Richard Henderson
0 siblings, 1 reply; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-05-31 18:55 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
Hi Richard,
On 5/3/21 1:57 AM, Richard Henderson wrote:
> Add libffi as a build requirement for TCI.
> Add libffi to the dockerfiles to satisfy that requirement.
>
> Construct an ffi_cif structure for each unique typemask.
> Record the result in a separate hash table for later lookup;
> this allows helper_table to stay const.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> meson.build | 9 ++-
> tcg/tcg.c | 58 +++++++++++++++++++
> tests/docker/dockerfiles/alpine.docker | 1 +
> tests/docker/dockerfiles/centos7.docker | 1 +
> tests/docker/dockerfiles/centos8.docker | 1 +
> tests/docker/dockerfiles/debian10.docker | 1 +
> .../dockerfiles/fedora-i386-cross.docker | 1 +
> .../dockerfiles/fedora-win32-cross.docker | 1 +
> .../dockerfiles/fedora-win64-cross.docker | 1 +
> tests/docker/dockerfiles/fedora.docker | 1 +
> tests/docker/dockerfiles/ubuntu.docker | 1 +
> tests/docker/dockerfiles/ubuntu1804.docker | 1 +
> tests/docker/dockerfiles/ubuntu2004.docker | 1 +
> 13 files changed, 77 insertions(+), 1 deletion(-)
> @@ -1135,6 +1152,47 @@ void tcg_context_init(TCGContext *s)
> (gpointer)&all_helpers[i]);
> }
>
> +#ifdef CONFIG_TCG_INTERPRETER
> + /* g_direct_hash/equal for direct comparisons on uint32_t. */
Why not use g_int_hash() then?
Otherwise,
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> + ffi_table = g_hash_table_new(NULL, NULL);
> + for (i = 0; i < ARRAY_SIZE(all_helpers); ++i) {
> + struct {
> + ffi_cif cif;
> + ffi_type *args[];
> + } *ca;
> + uint32_t typemask = all_helpers[i].typemask;
> + gpointer hash = (gpointer)(uintptr_t)typemask;
> + ffi_status status;
> + int nargs;
> +
> + if (g_hash_table_lookup(ffi_table, hash)) {
> + continue;
> + }
> +
> + /* Ignoring the return type, find the last non-zero field. */
> + nargs = 32 - clz32(typemask >> 3);
> + nargs = DIV_ROUND_UP(nargs, 3);
> +
> + ca = g_malloc0(sizeof(*ca) + nargs * sizeof(ffi_type *));
> + ca->cif.rtype = typecode_to_ffi[typemask & 7];
> + ca->cif.nargs = nargs;
> +
> + if (nargs != 0) {
> + ca->cif.arg_types = ca->args;
> + for (i = 0; i < nargs; ++i) {
> + int typecode = extract32(typemask, (i + 1) * 3, 3);
> + ca->args[i] = typecode_to_ffi[typecode];
> + }
> + }
> +
> + status = ffi_prep_cif(&ca->cif, FFI_DEFAULT_ABI, nargs,
> + ca->cif.rtype, ca->cif.arg_types);
> + assert(status == FFI_OK);
> +
> + g_hash_table_insert(ffi_table, hash, (gpointer)&ca->cif);
> + }
> +#endif
> +
> tcg_target_init(s);
> process_op_defs(s);
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 11/26] tcg/tci: Use ffi for calls
2021-05-02 23:57 ` [PATCH v6 11/26] tcg/tci: Use ffi for calls Richard Henderson
@ 2021-06-01 5:18 ` Philippe Mathieu-Daudé
2021-06-01 14:38 ` Richard Henderson
0 siblings, 1 reply; 53+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-01 5:18 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 5/3/21 1:57 AM, Richard Henderson wrote:
> This requires adjusting where arguments are stored.
> Place them on the stack at left-aligned positions.
> Adjust the stack frame to be at entirely positive offsets.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> include/tcg/tcg.h | 1 +
> tcg/tci/tcg-target.h | 2 +-
> tcg/tcg.c | 64 +++++++++++++------
> tcg/tci.c | 135 ++++++++++++++++++++++-----------------
> tcg/tci/tcg-target.c.inc | 50 +++++++--------
> 5 files changed, 148 insertions(+), 104 deletions(-)
>
> diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
> index 0f0695e90d..e5573a9877 100644
> --- a/include/tcg/tcg.h
> +++ b/include/tcg/tcg.h
> @@ -53,6 +53,7 @@
> #define MAX_OPC_PARAM (4 + (MAX_OPC_PARAM_PER_ARG * MAX_OPC_PARAM_ARGS))
>
> #define CPU_TEMP_BUF_NLONGS 128
> +#define TCG_STATIC_FRAME_SIZE (CPU_TEMP_BUF_NLONGS * sizeof(long))
>
> /* Default target word size to pointer size. */
> #ifndef TCG_TARGET_REG_BITS
> diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
> index 52af6d8bc5..4df10e2e83 100644
> --- a/tcg/tci/tcg-target.h
> +++ b/tcg/tci/tcg-target.h
> @@ -161,7 +161,7 @@ typedef enum {
>
> /* Used for function call generation. */
> #define TCG_TARGET_CALL_STACK_OFFSET 0
> -#define TCG_TARGET_STACK_ALIGN 16
> +#define TCG_TARGET_STACK_ALIGN 8
Is this FFI_SIZEOF_ARG?
>
> #define HAVE_TCG_QEMU_TB_EXEC
...
> static void tci_args_rr(const uint8_t **tb_ptr,
> TCGReg *r0, TCGReg *r1)
> {
> @@ -487,11 +479,13 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
> {
> const uint8_t *tb_ptr = v_tb_ptr;
> tcg_target_ulong regs[TCG_TARGET_NB_REGS];
> - long tcg_temps[CPU_TEMP_BUF_NLONGS];
> - uintptr_t sp_value = (uintptr_t)(tcg_temps + CPU_TEMP_BUF_NLONGS);
> + uint64_t stack[(TCG_STATIC_CALL_ARGS_SIZE + TCG_STATIC_FRAME_SIZE)
> + / sizeof(uint64_t)];
Why not simply use a char* array? Ah I see later "call_slots[i] =
&stack[i];", OK.
> + void *call_slots[TCG_STATIC_CALL_ARGS_SIZE / sizeof(uint64_t)];
>
> regs[TCG_AREG0] = (tcg_target_ulong)env;
> - regs[TCG_REG_CALL_STACK] = sp_value;
> + regs[TCG_REG_CALL_STACK] = (uintptr_t)stack;
> + call_slots[0] = NULL;
Maybe add a comment "Other slots initialization delayed (see below)"?
> tci_assert(tb_ptr);
>
> for (;;) {
> @@ -509,40 +503,58 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
> #endif
> TCGMemOpIdx oi;
> int32_t ofs;
> - void *ptr;
> + void *ptr, *cif;
>
> /* Skip opcode and size entry. */
> tb_ptr += 2;
>
> switch (opc) {
> case INDEX_op_call:
> - tci_args_l(&tb_ptr, &ptr);
> + /*
> + * Set up the ffi_avalue array once, delayed until now
> + * because many TB's do not make any calls. In tcg_gen_callN,
> + * we arranged for every real argument to be "left-aligned"
> + * in each 64-bit slot.
> + */
> + if (unlikely(call_slots[0] == NULL)) {
> + for (int i = 0; i < ARRAY_SIZE(call_slots); ++i) {
> + call_slots[i] = &stack[i];
> + }
> + }
> +
> + tci_args_nll(&tb_ptr, &len, &ptr, &cif);
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 08/26] tcg: Build ffi data structures for helpers
2021-05-31 18:55 ` Philippe Mathieu-Daudé
@ 2021-06-01 14:33 ` Richard Henderson
0 siblings, 0 replies; 53+ messages in thread
From: Richard Henderson @ 2021-06-01 14:33 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
On 5/31/21 11:55 AM, Philippe Mathieu-Daudé wrote:
> Hi Richard,
>
> On 5/3/21 1:57 AM, Richard Henderson wrote:
>> Add libffi as a build requirement for TCI.
>> Add libffi to the dockerfiles to satisfy that requirement.
>>
>> Construct an ffi_cif structure for each unique typemask.
>> Record the result in a separate hash table for later lookup;
>> this allows helper_table to stay const.
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>> meson.build | 9 ++-
>> tcg/tcg.c | 58 +++++++++++++++++++
>> tests/docker/dockerfiles/alpine.docker | 1 +
>> tests/docker/dockerfiles/centos7.docker | 1 +
>> tests/docker/dockerfiles/centos8.docker | 1 +
>> tests/docker/dockerfiles/debian10.docker | 1 +
>> .../dockerfiles/fedora-i386-cross.docker | 1 +
>> .../dockerfiles/fedora-win32-cross.docker | 1 +
>> .../dockerfiles/fedora-win64-cross.docker | 1 +
>> tests/docker/dockerfiles/fedora.docker | 1 +
>> tests/docker/dockerfiles/ubuntu.docker | 1 +
>> tests/docker/dockerfiles/ubuntu1804.docker | 1 +
>> tests/docker/dockerfiles/ubuntu2004.docker | 1 +
>> 13 files changed, 77 insertions(+), 1 deletion(-)
>
>> @@ -1135,6 +1152,47 @@ void tcg_context_init(TCGContext *s)
>> (gpointer)&all_helpers[i]);
>> }
>>
>> +#ifdef CONFIG_TCG_INTERPRETER
>> + /* g_direct_hash/equal for direct comparisons on uint32_t. */
>
> Why not use g_int_hash() then?
g_int_hash takes a pointer to an int; this stores the int directly as the hash key.
r~
>
> Otherwise,
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
>
>> + ffi_table = g_hash_table_new(NULL, NULL);
>> + for (i = 0; i < ARRAY_SIZE(all_helpers); ++i) {
>> + struct {
>> + ffi_cif cif;
>> + ffi_type *args[];
>> + } *ca;
>> + uint32_t typemask = all_helpers[i].typemask;
>> + gpointer hash = (gpointer)(uintptr_t)typemask;
>> + ffi_status status;
>> + int nargs;
>> +
>> + if (g_hash_table_lookup(ffi_table, hash)) {
>> + continue;
>> + }
>> +
>> + /* Ignoring the return type, find the last non-zero field. */
>> + nargs = 32 - clz32(typemask >> 3);
>> + nargs = DIV_ROUND_UP(nargs, 3);
>> +
>> + ca = g_malloc0(sizeof(*ca) + nargs * sizeof(ffi_type *));
>> + ca->cif.rtype = typecode_to_ffi[typemask & 7];
>> + ca->cif.nargs = nargs;
>> +
>> + if (nargs != 0) {
>> + ca->cif.arg_types = ca->args;
>> + for (i = 0; i < nargs; ++i) {
>> + int typecode = extract32(typemask, (i + 1) * 3, 3);
>> + ca->args[i] = typecode_to_ffi[typecode];
>> + }
>> + }
>> +
>> + status = ffi_prep_cif(&ca->cif, FFI_DEFAULT_ABI, nargs,
>> + ca->cif.rtype, ca->cif.arg_types);
>> + assert(status == FFI_OK);
>> +
>> + g_hash_table_insert(ffi_table, hash, (gpointer)&ca->cif);
>> + }
>> +#endif
>> +
>> tcg_target_init(s);
>> process_op_defs(s);
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [PATCH v6 11/26] tcg/tci: Use ffi for calls
2021-06-01 5:18 ` Philippe Mathieu-Daudé
@ 2021-06-01 14:38 ` Richard Henderson
0 siblings, 0 replies; 53+ messages in thread
From: Richard Henderson @ 2021-06-01 14:38 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
On 5/31/21 10:18 PM, Philippe Mathieu-Daudé wrote:
>> /* Used for function call generation. */
>> #define TCG_TARGET_CALL_STACK_OFFSET 0
>> -#define TCG_TARGET_STACK_ALIGN 16
>> +#define TCG_TARGET_STACK_ALIGN 8
>
> Is this FFI_SIZEOF_ARG?
No, just uint64_t.
>> + call_slots[0] = NULL;
>
> Maybe add a comment "Other slots initialization delayed (see below)"?
Sure.
r~
^ permalink raw reply [flat|nested] 53+ messages in thread
end of thread, other threads:[~2021-06-01 14:39 UTC | newest]
Thread overview: 53+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-02 23:57 [PATCH v6 00/26] TCI fixes and cleanups Richard Henderson
2021-05-02 23:57 ` [PATCH v6 01/26] tcg: Combine dh_is_64bit and dh_is_signed to dh_typecode Richard Henderson
2021-05-15 9:10 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 02/26] tcg: Add tcg_call_flags Richard Henderson
2021-05-03 21:39 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 03/26] accel/tcg/plugin-gen: Drop inline markers Richard Henderson
2021-05-03 21:40 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 04/26] plugins: Drop tcg_flags from struct qemu_plugin_dyn_cb Richard Henderson
2021-05-16 12:53 ` Philippe Mathieu-Daudé
2021-05-17 16:13 ` Richard Henderson
2021-05-02 23:57 ` [PATCH v6 05/26] accel/tcg: Add tcg call flags to plugins helpers Richard Henderson
2021-05-15 9:02 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 06/26] tcg: Store the TCGHelperInfo in the TCGOp for call Richard Henderson
2021-05-15 9:00 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 07/26] tcg: Add tcg_call_func Richard Henderson
2021-05-03 21:50 ` Philippe Mathieu-Daudé
2021-05-16 1:21 ` Richard Henderson
2021-05-16 12:48 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 08/26] tcg: Build ffi data structures for helpers Richard Henderson
2021-05-31 18:55 ` Philippe Mathieu-Daudé
2021-06-01 14:33 ` Richard Henderson
2021-05-02 23:57 ` [PATCH v6 09/26] tcg/tci: Improve tcg_target_call_clobber_regs Richard Henderson
2021-05-02 23:57 ` [PATCH v6 10/26] tcg/tci: Move call-return regs to end of tcg_target_reg_alloc_order Richard Henderson
2021-05-15 9:01 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 11/26] tcg/tci: Use ffi for calls Richard Henderson
2021-06-01 5:18 ` Philippe Mathieu-Daudé
2021-06-01 14:38 ` Richard Henderson
2021-05-02 23:57 ` [PATCH v6 12/26] tcg/tci: Reserve r13 for a temporary Richard Henderson
2021-05-02 23:57 ` [PATCH v6 13/26] tcg/tci: Emit setcond before brcond Richard Henderson
2021-05-02 23:57 ` [PATCH v6 14/26] tcg/tci: Remove tci_write_reg Richard Henderson
2021-05-03 21:53 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 15/26] tcg/tci: Change encoding to uint32_t units Richard Henderson
2021-05-02 23:57 ` [PATCH v6 16/26] tcg/tci: Implement goto_ptr Richard Henderson
2021-05-02 23:57 ` [PATCH v6 17/26] tcg/tci: Implement movcond Richard Henderson
2021-05-15 9:34 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 18/26] tcg/tci: Implement andc, orc, eqv, nand, nor Richard Henderson
2021-05-03 22:13 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 19/26] tcg/tci: Implement extract, sextract Richard Henderson
2021-05-03 22:04 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 20/26] tcg/tci: Implement clz, ctz, ctpop Richard Henderson
2021-05-03 22:10 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 21/26] tcg/tci: Implement mulu2, muls2 Richard Henderson
2021-05-02 23:57 ` [PATCH v6 22/26] tcg/tci: Implement add2, sub2 Richard Henderson
2021-05-02 23:57 ` [PATCH v6 23/26] tcg/tci: Split out tci_qemu_ld, tci_qemu_st Richard Henderson
2021-05-15 8:56 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 24/26] tests/tcg: Increase timeout for TCI Richard Henderson
2021-05-15 9:14 ` Philippe Mathieu-Daudé
2021-05-02 23:57 ` [PATCH v6 25/26] gitlab: Rename ACCEL_CONFIGURE_OPTS to EXTRA_CONFIGURE_OPTS Richard Henderson
2021-05-03 16:21 ` Willian Rampazzo
2021-05-02 23:57 ` [PATCH v6 26/26] gitlab: Enable cross-i386 builds of TCI Richard Henderson
2021-05-03 16:22 ` Willian Rampazzo
2021-05-03 0:30 ` [PATCH v6 00/26] TCI fixes and cleanups no-reply
2021-05-15 11:01 ` Philippe Mathieu-Daudé
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.