diff options
| author | Stefan Hajnoczi <stefanha@redhat.com> | 2025-01-21 08:27:20 -0500 |
|---|---|---|
| committer | Stefan Hajnoczi <stefanha@redhat.com> | 2025-01-21 08:28:33 -0500 |
| commit | 32a97c5d05c5deb54a42315d48cecf86cbeadaf4 (patch) | |
| tree | ca5d478d79623fb765d27d186e2640b224676141 /tcg/i386/tcg-target.c.inc | |
| parent | d6430c17d7113d3c38480dc34e59d00b0504e2f7 (diff) | |
| parent | db1649823d4f27b924a5aa5f9e0111457accb798 (diff) | |
| download | focaccia-qemu-32a97c5d05c5deb54a42315d48cecf86cbeadaf4.tar.gz focaccia-qemu-32a97c5d05c5deb54a42315d48cecf86cbeadaf4.zip | |
Merge tag 'pull-tcg-20250117' of https://gitlab.com/rth7680/qemu into staging
tcg:
- Add TCGOP_TYPE, TCGOP_FLAGS.
- Pass type and flags to tcg_op_supported, tcg_target_op_def.
- Split out tcg-target-has.h and unexport from tcg.h.
- Reorg constraint processing; constify TCGOpDef.
- Make extract, sextract, deposit opcodes mandatory.
- Merge ext{8,16,32}{s,u} opcodes into {s}extract.
tcg/mips: Expand bswap unconditionally
tcg/riscv: Use SRAIW, SRLIW for {s}extract_i64
tcg/riscv: Use BEXTI for single-bit extractions
tcg/sparc64: Use SRA, SRL for {s}extract_i64
disas/riscv: Guard dec->cfg dereference for host disassemble
util/cpuinfo-riscv: Detect Zbs
accel/tcg: Call tcg_tb_insert() for one-insn TBs
linux-user: Add missing /proc/cpuinfo fields for sparc
# -----BEGIN PGP SIGNATURE-----
#
# iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmeKnzUdHHJpY2hhcmQu
# aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV+Kvgf+LG9UjXlWF9GK923E
# TllBL2rLf1OOdtTXWO15VcvGMoWDwB3tVBdhihdvXmnWju+WbfMk6mct5NhzsKn9
# LmuugMIZs+hMROj+bgMK8x47jRIh5N2rDYxcEgmyfIpYb2o9qvyqKecGVRlSJTCE
# bmt5UFbvPThBb8upoMfq3F6evuMx0szBP7wrOwSR/VGpmzIr20UTEWo6I1ALp4uj
# paFaysYol4em3dIhkiuV9cL7E0EIObaNa7l9RUci/BmTq+JaVxUnW1Y2i0PEwKwG
# FJSfYTJk3wBgAVxC2zC2g3ZM7uKuecSXMpiFopTiuyQLp7Q61i9kCNvEq0qY5tdb
# DaqR/g==
# =cv4O
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 17 Jan 2025 13:19:33 EST
# 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-20250117' of https://gitlab.com/rth7680/qemu: (68 commits)
softfloat: Constify helpers returning float_status field
accel/tcg: Call tcg_tb_insert() for one-insn TBs
tcg: Document tb_lookup() and tcg_tb_lookup()
linux-user: Add missing /proc/cpuinfo fields for sparc
tcg/riscv: Use BEXTI for single-bit extractions
util/cpuinfo-riscv: Detect Zbs
tcg: Remove TCG_TARGET_HAS_deposit_{i32,i64}
tcg: Remove TCG_TARGET_HAS_{s}extract_{i32,i64}
tcg/tci: Remove assertions for deposit and extract
tcg/tci: Provide TCG_TARGET_{s}extract_valid
tcg/sparc64: Use SRA, SRL for {s}extract_i64
tcg/s390x: Fold the ext{8,16,32}[us] cases into {s}extract
tcg/riscv: Use SRAIW, SRLIW for {s}extract_i64
tcg/riscv64: Fold the ext{8,16,32}[us] cases into {s}extract
tcg/ppc: Fold the ext{8,16,32}[us] cases into {s}extract
tcg/mips: Fold the ext{8,16,32}[us] cases into {s}extract
tcg/loongarch64: Fold the ext{8,16,32}[us] cases into {s}extract
tcg/arm: Add full [US]XT[BH] into {s}extract
tcg/aarch64: Expand extract with offset 0 with andi
tcg/aarch64: Provide TCG_TARGET_{s}extract_valid
...
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'tcg/i386/tcg-target.c.inc')
| -rw-r--r-- | tcg/i386/tcg-target.c.inc | 121 |
1 files changed, 92 insertions, 29 deletions
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc index 1bf50f1f62..2cac151331 100644 --- a/tcg/i386/tcg-target.c.inc +++ b/tcg/i386/tcg-target.c.inc @@ -22,8 +22,25 @@ * THE SOFTWARE. */ -#include "../tcg-ldst.c.inc" -#include "../tcg-pool.c.inc" +/* Used for function call generation. */ +#define TCG_TARGET_STACK_ALIGN 16 +#if defined(_WIN64) +#define TCG_TARGET_CALL_STACK_OFFSET 32 +#else +#define TCG_TARGET_CALL_STACK_OFFSET 0 +#endif +#define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_NORMAL +#define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL +#if defined(_WIN64) +# define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_BY_REF +# define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_BY_VEC +#elif TCG_TARGET_REG_BITS == 64 +# define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL +# define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL +#else +# define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL +# define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_BY_REF +#endif #ifdef CONFIG_DEBUG_TCG static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { @@ -1312,16 +1329,31 @@ static inline void tcg_out_rolw_8(TCGContext *s, int reg) static void tcg_out_ext8u(TCGContext *s, TCGReg dest, TCGReg src) { - /* movzbl */ - tcg_debug_assert(src < 4 || TCG_TARGET_REG_BITS == 64); + if (TCG_TARGET_REG_BITS == 32 && src >= 4) { + tcg_out_mov(s, TCG_TYPE_I32, dest, src); + if (dest >= 4) { + tcg_out_modrm(s, OPC_ARITH_EvIz, ARITH_AND, dest); + tcg_out32(s, 0xff); + return; + } + src = dest; + } tcg_out_modrm(s, OPC_MOVZBL + P_REXB_RM, dest, src); } static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src) { int rexw = type == TCG_TYPE_I32 ? 0 : P_REXW; - /* movsbl */ - tcg_debug_assert(src < 4 || TCG_TARGET_REG_BITS == 64); + + if (TCG_TARGET_REG_BITS == 32 && src >= 4) { + tcg_out_mov(s, TCG_TYPE_I32, dest, src); + if (dest >= 4) { + tcg_out_shifti(s, SHIFT_SHL, dest, 24); + tcg_out_shifti(s, SHIFT_SAR, dest, 24); + return; + } + src = dest; + } tcg_out_modrm(s, OPC_MOVSBL + P_REXB_RM + rexw, dest, src); } @@ -2595,17 +2627,16 @@ void tb_target_set_jmp_target(const TranslationBlock *tb, int n, /* no need to flush icache explicitly */ } -static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, - const TCGArg args[TCG_MAX_OP_ARGS], - const int const_args[TCG_MAX_OP_ARGS]) +static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type, + const TCGArg args[TCG_MAX_OP_ARGS], + const int const_args[TCG_MAX_OP_ARGS]) { TCGArg a0, a1, a2; - int c, const_a2, vexop, rexw = 0; + int c, const_a2, vexop, rexw; #if TCG_TARGET_REG_BITS == 64 # define OP_32_64(x) \ case glue(glue(INDEX_op_, x), _i64): \ - rexw = P_REXW; /* FALLTHRU */ \ case glue(glue(INDEX_op_, x), _i32) #else # define OP_32_64(x) \ @@ -2617,6 +2648,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, a1 = args[1]; a2 = args[2]; const_a2 = const_args[2]; + rexw = type == TCG_TYPE_I32 ? 0 : P_REXW; switch (opc) { case INDEX_op_goto_ptr: @@ -3003,6 +3035,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_extract_i64: if (a2 + args[3] == 32) { + if (a2 == 0) { + tcg_out_ext32u(s, a0, a1); + break; + } /* This is a 32-bit zero-extending right shift. */ tcg_out_mov(s, TCG_TYPE_I32, a0, a1); tcg_out_shifti(s, SHIFT_SHR, a0, a2); @@ -3010,28 +3046,53 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, } /* FALLTHRU */ case INDEX_op_extract_i32: - /* On the off-chance that we can use the high-byte registers. - Otherwise we emit the same ext16 + shift pattern that we - would have gotten from the normal tcg-op.c expansion. */ - tcg_debug_assert(a2 == 8 && args[3] == 8); - if (a1 < 4 && a0 < 8) { - tcg_out_modrm(s, OPC_MOVZBL, a0, a1 + 4); - } else { + if (a2 == 0 && args[3] == 8) { + tcg_out_ext8u(s, a0, a1); + } else if (a2 == 0 && args[3] == 16) { tcg_out_ext16u(s, a0, a1); - tcg_out_shifti(s, SHIFT_SHR, a0, 8); + } else if (a2 == 8 && args[3] == 8) { + /* + * On the off-chance that we can use the high-byte registers. + * Otherwise we emit the same ext16 + shift pattern that we + * would have gotten from the normal tcg-op.c expansion. + */ + if (a1 < 4 && a0 < 8) { + tcg_out_modrm(s, OPC_MOVZBL, a0, a1 + 4); + } else { + tcg_out_ext16u(s, a0, a1); + tcg_out_shifti(s, SHIFT_SHR, a0, 8); + } + } else { + g_assert_not_reached(); } break; - case INDEX_op_sextract_i32: - /* We don't implement sextract_i64, as we cannot sign-extend to - 64-bits without using the REX prefix that explicitly excludes - access to the high-byte registers. */ - tcg_debug_assert(a2 == 8 && args[3] == 8); - if (a1 < 4 && a0 < 8) { - tcg_out_modrm(s, OPC_MOVSBL, a0, a1 + 4); + case INDEX_op_sextract_i64: + if (a2 == 0 && args[3] == 8) { + tcg_out_ext8s(s, TCG_TYPE_I64, a0, a1); + } else if (a2 == 0 && args[3] == 16) { + tcg_out_ext16s(s, TCG_TYPE_I64, a0, a1); + } else if (a2 == 0 && args[3] == 32) { + tcg_out_ext32s(s, a0, a1); } else { + g_assert_not_reached(); + } + break; + + case INDEX_op_sextract_i32: + if (a2 == 0 && args[3] == 8) { + tcg_out_ext8s(s, TCG_TYPE_I32, a0, a1); + } else if (a2 == 0 && args[3] == 16) { tcg_out_ext16s(s, TCG_TYPE_I32, a0, a1); - tcg_out_shifti(s, SHIFT_SAR, a0, 8); + } else if (a2 == 8 && args[3] == 8) { + if (a1 < 4 && a0 < 8) { + tcg_out_modrm(s, OPC_MOVSBL, a0, a1 + 4); + } else { + tcg_out_ext16s(s, TCG_TYPE_I32, a0, a1); + tcg_out_shifti(s, SHIFT_SAR, a0, 8); + } + } else { + g_assert_not_reached(); } break; @@ -3610,7 +3671,8 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, } } -static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op) +static TCGConstraintSetIndex +tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags) { switch (op) { case INDEX_op_goto_ptr: @@ -3713,6 +3775,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op) case INDEX_op_extract_i32: 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); @@ -3868,7 +3931,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op) return C_O1_I4(x, x, x, xO, x); default: - g_assert_not_reached(); + return C_NotImplemented; } } |