diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2023-01-06 15:40:37 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2023-01-06 15:40:37 +0000 |
commit | aaa90fede5d10e2a3c3fc7f2df608128d2cba761 (patch) | |
tree | 71bcd9f886192d6e2e15397f4c2ca7f22913833a /include | |
parent | 171033e8dbac356f9a84c2e7cc8556a4eb0a1359 (diff) | |
parent | d4846c33ebe04d2141dcc613b5558d2f1d8077af (diff) |
Merge tag 'pull-tcg-20230105' of https://gitlab.com/rth7680/qemu into staging
Fix race conditions in new user-only vma tracking.
Add tcg backend paired register allocation.
Cleanup tcg backend function call abi.
# gpg: Signature made Fri 06 Jan 2023 03:12:17 GMT
# gpg: using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg: issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full]
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A 05C0 64DF 38E8 AF7E 215F
* tag 'pull-tcg-20230105' of https://gitlab.com/rth7680/qemu: (47 commits)
tests/tcg/multiarch: add vma-pthread.c
accel/tcg: Handle false negative lookup in page_check_range
accel/tcg: Use g_free_rcu for user-exec interval trees
accel/tcg: Fix tb_invalidate_phys_page_unwind
tcg: Add TCGHelperInfo argument to tcg_out_call
tcg/aarch64: Merge tcg_out_callr into tcg_out_call
tcg: Move ffi_cif pointer into TCGHelperInfo
tcg: Factor init_ffi_layouts() out of tcg_context_init()
tcg: Convert typecode_to_ffi from array to function
tcg: Reorg function calls
tcg: Use output_pref wrapper function
tcg: Vary the allocation size for TCGOp
tcg: Pass number of arguments to tcg_emit_op() / tcg_op_insert_*()
accel/tcg/plugin: Use copy_op in append_{udata,mem}_cb
accel/tcg/plugin: Avoid duplicate copy in copy_call
accel/tcg/plugin: Don't search for the function pointer index
tcg: Use TCG_CALL_ARG_EVEN for TCI special case
tcg: Replace TCG_TARGET_EXTEND_ARGS with TCG_TARGET_CALL_ARG_I32
tcg: Replace TCG_TARGET_CALL_ALIGN_ARGS with TCG_TARGET_CALL_ARG_I64
tcg: Introduce TCGCallReturnKind and TCGCallArgumentKind
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/exec/helper-head.h | 2 | ||||
-rw-r--r-- | include/qemu/main-loop.h | 29 | ||||
-rw-r--r-- | include/tcg/tcg-op.h | 35 | ||||
-rw-r--r-- | include/tcg/tcg.h | 96 |
4 files changed, 84 insertions, 78 deletions
diff --git a/include/exec/helper-head.h b/include/exec/helper-head.h index e242fed46e..bc6698b19f 100644 --- a/include/exec/helper-head.h +++ b/include/exec/helper-head.h @@ -133,6 +133,6 @@ #define DEF_HELPER_7(name, ret, t1, t2, t3, t4, t5, t6, t7) \ DEF_HELPER_FLAGS_7(name, 0, ret, t1, t2, t3, t4, t5, t6, t7) -/* MAX_OPC_PARAM_IARGS must be set to n if last entry is DEF_HELPER_FLAGS_n. */ +/* MAX_CALL_IARGS must be set to n if last entry is DEF_HELPER_FLAGS_n. */ #endif /* EXEC_HELPER_HEAD_H */ diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h index 3c9a9a982d..c25f390696 100644 --- a/include/qemu/main-loop.h +++ b/include/qemu/main-loop.h @@ -343,6 +343,35 @@ void qemu_mutex_lock_iothread_impl(const char *file, int line); */ void qemu_mutex_unlock_iothread(void); +/** + * QEMU_IOTHREAD_LOCK_GUARD + * + * Wrap a block of code in a conditional qemu_mutex_{lock,unlock}_iothread. + */ +typedef struct IOThreadLockAuto IOThreadLockAuto; + +static inline IOThreadLockAuto *qemu_iothread_auto_lock(const char *file, + int line) +{ + if (qemu_mutex_iothread_locked()) { + return NULL; + } + qemu_mutex_lock_iothread_impl(file, line); + /* Anything non-NULL causes the cleanup function to be called */ + return (IOThreadLockAuto *)(uintptr_t)1; +} + +static inline void qemu_iothread_auto_unlock(IOThreadLockAuto *l) +{ + qemu_mutex_unlock_iothread(); +} + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(IOThreadLockAuto, qemu_iothread_auto_unlock) + +#define QEMU_IOTHREAD_LOCK_GUARD() \ + g_autoptr(IOThreadLockAuto) _iothread_lock_auto __attribute__((unused)) \ + = qemu_iothread_auto_lock(__FILE__, __LINE__) + /* * qemu_cond_wait_iothread: Wait on condition for the main loop mutex * diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h index 209e168305..79b1cf786f 100644 --- a/include/tcg/tcg-op.h +++ b/include/tcg/tcg-op.h @@ -667,35 +667,12 @@ static inline void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) tcg_gen_op3_i64(INDEX_op_mul_i64, ret, arg1, arg2); } #else /* TCG_TARGET_REG_BITS == 32 */ -static inline void tcg_gen_st8_i64(TCGv_i64 arg1, TCGv_ptr arg2, - tcg_target_long offset) -{ - tcg_gen_st8_i32(TCGV_LOW(arg1), arg2, offset); -} +void tcg_gen_st8_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset); +void tcg_gen_st16_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset); +void tcg_gen_st32_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset); -static inline void tcg_gen_st16_i64(TCGv_i64 arg1, TCGv_ptr arg2, - tcg_target_long offset) -{ - tcg_gen_st16_i32(TCGV_LOW(arg1), arg2, offset); -} - -static inline void tcg_gen_st32_i64(TCGv_i64 arg1, TCGv_ptr arg2, - tcg_target_long offset) -{ - tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset); -} - -static inline void tcg_gen_add_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) -{ - tcg_gen_add2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), TCGV_LOW(arg1), - TCGV_HIGH(arg1), TCGV_LOW(arg2), TCGV_HIGH(arg2)); -} - -static inline void tcg_gen_sub_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) -{ - tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), TCGV_LOW(arg1), - TCGV_HIGH(arg1), TCGV_LOW(arg2), TCGV_HIGH(arg2)); -} +void tcg_gen_add_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2); +void tcg_gen_sub_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2); void tcg_gen_discard_i64(TCGv_i64 arg); void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg); @@ -841,7 +818,7 @@ static inline void tcg_gen_plugin_cb_start(unsigned from, unsigned type, static inline void tcg_gen_plugin_cb_end(void) { - tcg_emit_op(INDEX_op_plugin_cb_end); + tcg_emit_op(INDEX_op_plugin_cb_end, 0); } #if TARGET_LONG_BITS == 32 diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h index d84bae6e3f..b949d75fdd 100644 --- a/include/tcg/tcg.h +++ b/include/tcg/tcg.h @@ -38,19 +38,7 @@ /* XXX: make safe guess about sizes */ #define MAX_OP_PER_INSTR 266 -#if HOST_LONG_BITS == 32 -#define MAX_OPC_PARAM_PER_ARG 2 -#else -#define MAX_OPC_PARAM_PER_ARG 1 -#endif -#define MAX_OPC_PARAM_IARGS 7 -#define MAX_OPC_PARAM_OARGS 1 -#define MAX_OPC_PARAM_ARGS (MAX_OPC_PARAM_IARGS + MAX_OPC_PARAM_OARGS) - -/* A Call op needs up to 4 + 2N parameters on 32-bit archs, - * and up to 4 + N parameters on 64-bit archs - * (N = number of input arguments + output arguments). */ -#define MAX_OPC_PARAM (4 + (MAX_OPC_PARAM_PER_ARG * MAX_OPC_PARAM_ARGS)) +#define MAX_CALL_IARGS 7 #define CPU_TEMP_BUF_NLONGS 128 #define TCG_STATIC_FRAME_SIZE (CPU_TEMP_BUF_NLONGS * sizeof(long)) @@ -294,7 +282,8 @@ typedef enum TCGType { TCG_TYPE_V128, TCG_TYPE_V256, - TCG_TYPE_COUNT, /* number of different types */ + /* Number of different types (integer not enum) */ +#define TCG_TYPE_COUNT (TCG_TYPE_V256 + 1) /* An alias for the size of the host register. */ #if TCG_TARGET_REG_BITS == 32 @@ -319,6 +308,22 @@ typedef enum TCGType { } TCGType; /** + * tcg_type_size + * @t: type + * + * Return the size of the type in bytes. + */ +static inline int tcg_type_size(TCGType t) +{ + unsigned i = t; + if (i >= TCG_TYPE_V64) { + tcg_debug_assert(i < TCG_TYPE_COUNT); + i -= TCG_TYPE_V64 - 1; + } + return 4 << i; +} + +/** * get_alignment_bits * @memop: MemOp value * @@ -408,9 +413,6 @@ typedef TCGv_ptr TCGv_env; #define TCG_CALL_NO_RWG_SE (TCG_CALL_NO_RWG | TCG_CALL_NO_SE) #define TCG_CALL_NO_WG_SE (TCG_CALL_NO_WG | TCG_CALL_NO_SE) -/* Used to align parameters. See the comment before tcgv_i32_temp. */ -#define TCG_CALL_DUMMY_ARG ((TCGArg)0) - /* * Flags for the bswap opcodes. * If IZ, the input is zero-extended, otherwise unknown. @@ -456,6 +458,7 @@ typedef struct TCGTemp { unsigned int mem_coherent:1; unsigned int mem_allocated:1; unsigned int temp_allocated:1; + unsigned int temp_subindex:1; int64_t val; struct TCGTemp *mem_base; @@ -475,34 +478,34 @@ typedef struct TCGTempSet { unsigned long l[BITS_TO_LONGS(TCG_MAX_TEMPS)]; } TCGTempSet; -/* While we limit helpers to 6 arguments, for 32-bit hosts, with padding, - this imples a max of 6*2 (64-bit in) + 2 (64-bit out) = 14 operands. - There are never more than 2 outputs, which means that we can store all - dead + sync data within 16 bits. */ -#define DEAD_ARG 4 -#define SYNC_ARG 1 -typedef uint16_t TCGLifeData; +/* + * With 1 128-bit output, a 32-bit host requires 4 output parameters, + * which leaves a maximum of 28 other slots. Which is enough for 7 + * 128-bit operands. + */ +#define DEAD_ARG (1 << 4) +#define SYNC_ARG (1 << 0) +typedef uint32_t TCGLifeData; -/* The layout here is designed to avoid a bitfield crossing of - a 32-bit boundary, which would cause GCC to add extra padding. */ typedef struct TCGOp { - TCGOpcode opc : 8; /* 8 */ + TCGOpcode opc : 8; + unsigned nargs : 8; /* Parameters for this opcode. See below. */ - unsigned param1 : 4; /* 12 */ - unsigned param2 : 4; /* 16 */ + unsigned param1 : 8; + unsigned param2 : 8; /* Lifetime data of the operands. */ - unsigned life : 16; /* 32 */ + TCGLifeData life; /* Next and previous opcodes. */ QTAILQ_ENTRY(TCGOp) link; - /* Arguments for the opcode. */ - TCGArg args[MAX_OPC_PARAM]; - /* Register preferences for the output(s). */ TCGRegSet output_pref[2]; + + /* Arguments for the opcode. */ + TCGArg args[]; } TCGOp; #define TCGOP_CALLI(X) (X)->param1 @@ -514,6 +517,11 @@ typedef struct TCGOp { /* Make sure operands fit in the bitfields above. */ QEMU_BUILD_BUG_ON(NB_OPS > (1 << 8)); +static inline TCGRegSet output_pref(const TCGOp *op, unsigned i) +{ + return i < ARRAY_SIZE(op->output_pref) ? op->output_pref[i] : 0; +} + typedef struct TCGProfile { int64_t cpu_exec_time; int64_t tb_count1; @@ -737,18 +745,6 @@ static inline TCGv_vec temp_tcgv_vec(TCGTemp *t) return (TCGv_vec)temp_tcgv_i32(t); } -#if TCG_TARGET_REG_BITS == 32 -static inline TCGv_i32 TCGV_LOW(TCGv_i64 t) -{ - return temp_tcgv_i32(tcgv_i64_temp(t)); -} - -static inline TCGv_i32 TCGV_HIGH(TCGv_i64 t) -{ - return temp_tcgv_i32(tcgv_i64_temp(t) + 1); -} -#endif - static inline TCGArg tcg_get_insn_param(TCGOp *op, int arg) { return op->args[arg]; @@ -951,6 +947,8 @@ typedef struct TCGArgConstraint { unsigned ct : 16; unsigned alias_index : 4; unsigned sort_index : 4; + unsigned pair_index : 4; + unsigned pair : 2; /* 0: none, 1: first, 2: second, 3: second alias */ bool oalias : 1; bool ialias : 1; bool newreg : 1; @@ -1006,10 +1004,12 @@ bool tcg_op_supported(TCGOpcode op); void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args); -TCGOp *tcg_emit_op(TCGOpcode opc); +TCGOp *tcg_emit_op(TCGOpcode opc, unsigned nargs); void tcg_op_remove(TCGContext *s, TCGOp *op); -TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *op, TCGOpcode opc); -TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *op, TCGOpcode opc); +TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *op, + TCGOpcode opc, unsigned nargs); +TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *op, + TCGOpcode opc, unsigned nargs); /** * tcg_remove_ops_after: |