1
Pretty small still, but there are two patches that ought
1
v2: Fix rebase error in patch 38 (tcg/s390x: Support TCG_COND_TST{EQ,NE}).
2
to get backported to stable, so no point in delaying.
2
3
3
4
r~
4
r~
5
5
6
The following changes since commit a5ba0a7e4e150d1350a041f0d0ef9ca6c8d7c307:
7
6
8
Merge tag 'pull-aspeed-20241211' of https://github.com/legoater/qemu into staging (2024-12-11 15:16:47 +0000)
7
The following changes since commit 39a6e4f87e7b75a45b08d6dc8b8b7c2954c87440:
8
9
Merge tag 'pull-qapi-2024-02-03' of https://repo.or.cz/qemu/armbru into staging (2024-02-03 13:31:58 +0000)
9
10
10
are available in the Git repository at:
11
are available in the Git repository at:
11
12
12
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20241212
13
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20240205-2
13
14
14
for you to fetch changes up to 7ac87b14a92234b6a89b701b4043ad6cf8bdcccf:
15
for you to fetch changes up to 23c5692abc3917151dee36c00d751cf5bc46ef19:
15
16
16
target/sparc: Use memcpy() and remove memcpy32() (2024-12-12 14:28:38 -0600)
17
tcg/tci: Support TCG_COND_TST{EQ,NE} (2024-02-05 22:45:41 +0000)
17
18
18
----------------------------------------------------------------
19
----------------------------------------------------------------
19
tcg: Reset free_temps before tcg_optimize
20
tcg: Introduce TCG_COND_TST{EQ,NE}
20
tcg/riscv: Fix StoreStore barrier generation
21
target/alpha: Use TCG_COND_TST{EQ,NE}
21
include/exec: Introduce fpst alias in helper-head.h.inc
22
target/m68k: Use TCG_COND_TST{EQ,NE} in gen_fcc_cond
22
target/sparc: Use memcpy() and remove memcpy32()
23
target/sparc: Use TCG_COND_TSTEQ in gen_op_mulscc
24
target/s390x: Use TCG_COND_TSTNE for CC_OP_{TM,ICM}
25
target/s390x: Improve general case of disas_jcc
23
26
24
----------------------------------------------------------------
27
----------------------------------------------------------------
28
Paolo Bonzini (1):
29
tcg/i386: Use TEST r,r to test 8/16/32 bits
30
25
Philippe Mathieu-Daudé (1):
31
Philippe Mathieu-Daudé (1):
26
target/sparc: Use memcpy() and remove memcpy32()
32
tcg/aarch64: Massage tcg_out_brcond()
27
33
28
Richard Henderson (2):
34
Richard Henderson (37):
29
tcg: Reset free_temps before tcg_optimize
35
tcg: Introduce TCG_COND_TST{EQ,NE}
30
include/exec: Introduce fpst alias in helper-head.h.inc
36
tcg: Introduce TCG_TARGET_HAS_tst
37
tcg/optimize: Split out arg_is_const_val
38
tcg/optimize: Split out do_constant_folding_cond1
39
tcg/optimize: Do swap_commutative2 in do_constant_folding_cond2
40
tcg/optimize: Handle TCG_COND_TST{EQ,NE}
41
tcg/optimize: Lower TCG_COND_TST{EQ,NE} if unsupported
42
target/alpha: Pass immediate value to gen_bcond_internal()
43
target/alpha: Use TCG_COND_TST{EQ,NE} for BLB{C,S}
44
target/alpha: Use TCG_COND_TST{EQ,NE} for CMOVLB{C,S}
45
target/alpha: Use TCG_COND_TSTNE for gen_fold_mzero
46
target/m68k: Use TCG_COND_TST{EQ,NE} in gen_fcc_cond
47
target/sparc: Use TCG_COND_TSTEQ in gen_op_mulscc
48
target/s390x: Use TCG_COND_TSTNE for CC_OP_{TM,ICM}
49
target/s390x: Improve general case of disas_jcc
50
tcg: Add TCGConst argument to tcg_target_const_match
51
tcg/aarch64: Support TCG_COND_TST{EQ,NE}
52
tcg/aarch64: Generate TBZ, TBNZ
53
tcg/aarch64: Generate CBNZ for TSTNE of UINT32_MAX
54
tcg/arm: Split out tcg_out_cmp()
55
tcg/arm: Support TCG_COND_TST{EQ,NE}
56
tcg/i386: Pass x86 condition codes to tcg_out_cmov
57
tcg/i386: Move tcg_cond_to_jcc[] into tcg_out_cmp
58
tcg/i386: Support TCG_COND_TST{EQ,NE}
59
tcg/i386: Improve TSTNE/TESTEQ vs powers of two
60
tcg/sparc64: Hoist read of tcg_cond_to_rcond
61
tcg/sparc64: Pass TCGCond to tcg_out_cmp
62
tcg/sparc64: Support TCG_COND_TST{EQ,NE}
63
tcg/ppc: Sink tcg_to_bc usage into tcg_out_bc
64
tcg/ppc: Use cr0 in tcg_to_bc and tcg_to_isel
65
tcg/ppc: Tidy up tcg_target_const_match
66
tcg/ppc: Add TCG_CT_CONST_CMP
67
tcg/ppc: Support TCG_COND_TST{EQ,NE}
68
tcg/s390x: Split constraint A into J+U
69
tcg/s390x: Add TCG_CT_CONST_CMP
70
tcg/s390x: Support TCG_COND_TST{EQ,NE}
71
tcg/tci: Support TCG_COND_TST{EQ,NE}
31
72
32
Roman Artemev (1):
73
docs/devel/tcg-ops.rst | 2 +
33
tcg/riscv: Fix StoreStore barrier generation
74
include/tcg/tcg-cond.h | 74 ++++--
75
tcg/aarch64/tcg-target-con-set.h | 5 +-
76
tcg/aarch64/tcg-target-con-str.h | 1 +
77
tcg/aarch64/tcg-target.h | 2 +
78
tcg/arm/tcg-target.h | 2 +
79
tcg/i386/tcg-target-con-set.h | 6 +-
80
tcg/i386/tcg-target-con-str.h | 1 +
81
tcg/i386/tcg-target.h | 2 +
82
tcg/loongarch64/tcg-target.h | 2 +
83
tcg/mips/tcg-target.h | 2 +
84
tcg/ppc/tcg-target-con-set.h | 5 +-
85
tcg/ppc/tcg-target-con-str.h | 1 +
86
tcg/ppc/tcg-target.h | 2 +
87
tcg/riscv/tcg-target.h | 2 +
88
tcg/s390x/tcg-target-con-set.h | 8 +-
89
tcg/s390x/tcg-target-con-str.h | 3 +-
90
tcg/s390x/tcg-target.h | 2 +
91
tcg/sparc64/tcg-target.h | 2 +
92
tcg/tcg-internal.h | 2 +
93
tcg/tci/tcg-target.h | 2 +
94
target/alpha/translate.c | 94 ++++----
95
target/m68k/translate.c | 74 +++---
96
target/s390x/tcg/translate.c | 100 +++------
97
target/sparc/translate.c | 4 +-
98
tcg/optimize.c | 474 ++++++++++++++++++++++++++++++---------
99
tcg/tcg.c | 40 +++-
100
tcg/tci.c | 14 ++
101
tcg/aarch64/tcg-target.c.inc | 166 +++++++++++---
102
tcg/arm/tcg-target.c.inc | 62 +++--
103
tcg/i386/tcg-target.c.inc | 201 ++++++++++++-----
104
tcg/loongarch64/tcg-target.c.inc | 3 +-
105
tcg/mips/tcg-target.c.inc | 3 +-
106
tcg/ppc/tcg-target.c.inc | 294 ++++++++++++++++++------
107
tcg/riscv/tcg-target.c.inc | 3 +-
108
tcg/s390x/tcg-target.c.inc | 246 +++++++++++++-------
109
tcg/sparc64/tcg-target.c.inc | 65 ++++--
110
tcg/tci/tcg-target.c.inc | 3 +-
111
38 files changed, 1379 insertions(+), 595 deletions(-)
34
112
35
include/tcg/tcg-temp-internal.h | 6 ++++++
36
accel/tcg/plugin-gen.c | 2 +-
37
target/sparc/win_helper.c | 26 ++++++++------------------
38
tcg/tcg.c | 5 ++++-
39
include/exec/helper-head.h.inc | 3 +++
40
tcg/riscv/tcg-target.c.inc | 2 +-
41
6 files changed, 23 insertions(+), 21 deletions(-)
42
diff view generated by jsdifflib
Deleted patch
1
When allocating new temps during tcg_optmize, do not re-use
2
any EBB temps that were used within the TB. We do not have
3
any idea what span of the TB in which the temp was live.
4
1
5
Introduce tcg_temp_ebb_reset_freed and use before tcg_optimize,
6
as well as replacing the equivalent in plugin_gen_inject and
7
tcg_func_start.
8
9
Cc: qemu-stable@nongnu.org
10
Fixes: fb04ab7ddd8 ("tcg/optimize: Lower TCG_COND_TST{EQ,NE} if unsupported")
11
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2711
12
Reported-by: wannacu <wannacu2049@gmail.com>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
16
---
17
include/tcg/tcg-temp-internal.h | 6 ++++++
18
accel/tcg/plugin-gen.c | 2 +-
19
tcg/tcg.c | 5 ++++-
20
3 files changed, 11 insertions(+), 2 deletions(-)
21
22
diff --git a/include/tcg/tcg-temp-internal.h b/include/tcg/tcg-temp-internal.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/tcg/tcg-temp-internal.h
25
+++ b/include/tcg/tcg-temp-internal.h
26
@@ -XXX,XX +XXX,XX @@ TCGv_i64 tcg_temp_ebb_new_i64(void);
27
TCGv_ptr tcg_temp_ebb_new_ptr(void);
28
TCGv_i128 tcg_temp_ebb_new_i128(void);
29
30
+/* Forget all freed EBB temps, so that new allocations produce new temps. */
31
+static inline void tcg_temp_ebb_reset_freed(TCGContext *s)
32
+{
33
+ memset(s->free_temps, 0, sizeof(s->free_temps));
34
+}
35
+
36
#endif /* TCG_TEMP_FREE_H */
37
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/accel/tcg/plugin-gen.c
40
+++ b/accel/tcg/plugin-gen.c
41
@@ -XXX,XX +XXX,XX @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
42
* that might be live within the existing opcode stream.
43
* The simplest solution is to release them all and create new.
44
*/
45
- memset(tcg_ctx->free_temps, 0, sizeof(tcg_ctx->free_temps));
46
+ tcg_temp_ebb_reset_freed(tcg_ctx);
47
48
QTAILQ_FOREACH_SAFE(op, &tcg_ctx->ops, link, next) {
49
switch (op->opc) {
50
diff --git a/tcg/tcg.c b/tcg/tcg.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/tcg/tcg.c
53
+++ b/tcg/tcg.c
54
@@ -XXX,XX +XXX,XX @@ void tcg_func_start(TCGContext *s)
55
s->nb_temps = s->nb_globals;
56
57
/* No temps have been previously allocated for size or locality. */
58
- memset(s->free_temps, 0, sizeof(s->free_temps));
59
+ tcg_temp_ebb_reset_freed(s);
60
61
/* No constant temps have been previously allocated. */
62
for (int i = 0; i < TCG_TYPE_COUNT; ++i) {
63
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
64
}
65
#endif
66
67
+ /* Do not reuse any EBB that may be allocated within the TB. */
68
+ tcg_temp_ebb_reset_freed(s);
69
+
70
tcg_optimize(s);
71
72
reachable_code_pass(s);
73
--
74
2.43.0
75
76
diff view generated by jsdifflib
Deleted patch
1
From: Roman Artemev <roman.artemev@syntacore.com>
2
1
3
On RISC-V to StoreStore barrier corresponds
4
`fence w, w` not `fence r, r`
5
6
Cc: qemu-stable@nongnu.org
7
Fixes: efbea94c76b ("tcg/riscv: Add slowpath load and store instructions")
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Denis Tomashev <denis.tomashev@syntacore.com>
10
Signed-off-by: Roman Artemev <roman.artemev@syntacore.com>
11
Message-ID: <e2f2131e294a49e79959d4fa9ec02cf4@syntacore.com>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
---
14
tcg/riscv/tcg-target.c.inc | 2 +-
15
1 file changed, 1 insertion(+), 1 deletion(-)
16
17
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
18
index XXXXXXX..XXXXXXX 100644
19
--- a/tcg/riscv/tcg-target.c.inc
20
+++ b/tcg/riscv/tcg-target.c.inc
21
@@ -XXX,XX +XXX,XX @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
22
insn |= 0x02100000;
23
}
24
if (a0 & TCG_MO_ST_ST) {
25
- insn |= 0x02200000;
26
+ insn |= 0x01100000;
27
}
28
tcg_out32(s, insn);
29
}
30
--
31
2.43.0
diff view generated by jsdifflib
Deleted patch
1
This allows targets to declare that the helper requires a
2
float_status pointer and instead of a generic void pointer.
3
1
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
include/exec/helper-head.h.inc | 3 +++
8
1 file changed, 3 insertions(+)
9
10
diff --git a/include/exec/helper-head.h.inc b/include/exec/helper-head.h.inc
11
index XXXXXXX..XXXXXXX 100644
12
--- a/include/exec/helper-head.h.inc
13
+++ b/include/exec/helper-head.h.inc
14
@@ -XXX,XX +XXX,XX @@
15
#define dh_alias_ptr ptr
16
#define dh_alias_cptr ptr
17
#define dh_alias_env ptr
18
+#define dh_alias_fpst ptr
19
#define dh_alias_void void
20
#define dh_alias_noreturn noreturn
21
#define dh_alias(t) glue(dh_alias_, t)
22
@@ -XXX,XX +XXX,XX @@
23
#define dh_ctype_ptr void *
24
#define dh_ctype_cptr const void *
25
#define dh_ctype_env CPUArchState *
26
+#define dh_ctype_fpst float_status *
27
#define dh_ctype_void void
28
#define dh_ctype_noreturn G_NORETURN void
29
#define dh_ctype(t) dh_ctype_##t
30
@@ -XXX,XX +XXX,XX @@
31
#define dh_typecode_f64 dh_typecode_i64
32
#define dh_typecode_cptr dh_typecode_ptr
33
#define dh_typecode_env dh_typecode_ptr
34
+#define dh_typecode_fpst dh_typecode_ptr
35
#define dh_typecode(t) dh_typecode_##t
36
37
#define dh_callflag_i32 0
38
--
39
2.43.0
40
41
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
3
Rather than manually copying each register, use
4
the libc memcpy(), which is well optimized nowadays.
5
6
Suggested-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
7
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-ID: <20241205205418.67613-1-philmd@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
1
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
---
2
---
13
target/sparc/win_helper.c | 26 ++++++++------------------
3
tcg/s390x/tcg-target.h | 2 +-
14
1 file changed, 8 insertions(+), 18 deletions(-)
4
tcg/s390x/tcg-target.c.inc | 139 +++++++++++++++++++++++++------------
5
2 files changed, 97 insertions(+), 44 deletions(-)
15
6
16
diff --git a/target/sparc/win_helper.c b/target/sparc/win_helper.c
7
diff --git a/tcg/s390x/tcg-target.h b/tcg/s390x/tcg-target.h
17
index XXXXXXX..XXXXXXX 100644
8
index XXXXXXX..XXXXXXX 100644
18
--- a/target/sparc/win_helper.c
9
--- a/tcg/s390x/tcg-target.h
19
+++ b/target/sparc/win_helper.c
10
+++ b/tcg/s390x/tcg-target.h
20
@@ -XXX,XX +XXX,XX @@
11
@@ -XXX,XX +XXX,XX @@ extern uint64_t s390_facilities[3];
21
#include "exec/helper-proto.h"
12
22
#include "trace.h"
13
#define TCG_TARGET_HAS_qemu_ldst_i128 1
23
14
24
-static inline void memcpy32(target_ulong *dst, const target_ulong *src)
15
-#define TCG_TARGET_HAS_tst 0
25
-{
16
+#define TCG_TARGET_HAS_tst 1
26
- dst[0] = src[0];
17
27
- dst[1] = src[1];
18
#define TCG_TARGET_HAS_v64 HAVE_FACILITY(VECTOR)
28
- dst[2] = src[2];
19
#define TCG_TARGET_HAS_v128 HAVE_FACILITY(VECTOR)
29
- dst[3] = src[3];
20
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
30
- dst[4] = src[4];
21
index XXXXXXX..XXXXXXX 100644
31
- dst[5] = src[5];
22
--- a/tcg/s390x/tcg-target.c.inc
32
- dst[6] = src[6];
23
+++ b/tcg/s390x/tcg-target.c.inc
33
- dst[7] = src[7];
24
@@ -XXX,XX +XXX,XX @@ typedef enum S390Opcode {
34
-}
25
RI_OILH = 0xa50a,
35
-
26
RI_OILL = 0xa50b,
36
void cpu_set_cwp(CPUSPARCState *env, int new_cwp)
27
RI_TMLL = 0xa701,
28
+ RI_TMLH = 0xa700,
29
+ RI_TMHL = 0xa703,
30
+ RI_TMHH = 0xa702,
31
32
RIEb_CGRJ = 0xec64,
33
RIEb_CLGRJ = 0xec65,
34
@@ -XXX,XX +XXX,XX @@ static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
35
#define S390_CC_NEVER 0
36
#define S390_CC_ALWAYS 15
37
38
+#define S390_TM_EQ 8 /* CC == 0 */
39
+#define S390_TM_NE 7 /* CC in {1,2,3} */
40
+
41
/* Condition codes that result from a COMPARE and COMPARE LOGICAL. */
42
-static const uint8_t tcg_cond_to_s390_cond[] = {
43
+static const uint8_t tcg_cond_to_s390_cond[16] = {
44
[TCG_COND_EQ] = S390_CC_EQ,
45
[TCG_COND_NE] = S390_CC_NE,
46
+ [TCG_COND_TSTEQ] = S390_CC_EQ,
47
+ [TCG_COND_TSTNE] = S390_CC_NE,
48
[TCG_COND_LT] = S390_CC_LT,
49
[TCG_COND_LE] = S390_CC_LE,
50
[TCG_COND_GT] = S390_CC_GT,
51
@@ -XXX,XX +XXX,XX @@ static const uint8_t tcg_cond_to_s390_cond[] = {
52
/* Condition codes that result from a LOAD AND TEST. Here, we have no
53
unsigned instruction variation, however since the test is vs zero we
54
can re-map the outcomes appropriately. */
55
-static const uint8_t tcg_cond_to_ltr_cond[] = {
56
+static const uint8_t tcg_cond_to_ltr_cond[16] = {
57
[TCG_COND_EQ] = S390_CC_EQ,
58
[TCG_COND_NE] = S390_CC_NE,
59
+ [TCG_COND_TSTEQ] = S390_CC_ALWAYS,
60
+ [TCG_COND_TSTNE] = S390_CC_NEVER,
61
[TCG_COND_LT] = S390_CC_LT,
62
[TCG_COND_LE] = S390_CC_LE,
63
[TCG_COND_GT] = S390_CC_GT,
64
@@ -XXX,XX +XXX,XX @@ static bool risbg_mask(uint64_t c)
65
static bool tcg_target_const_match(int64_t val, int ct,
66
TCGType type, TCGCond cond, int vece)
37
{
67
{
38
/* put the modified wrap registers at their proper location */
68
+ uint64_t uval = val;
39
if (env->cwp == env->nwindows - 1) {
69
+
40
- memcpy32(env->regbase, env->regbase + env->nwindows * 16);
70
if (ct & TCG_CT_CONST) {
41
+ memcpy(env->regbase, env->regbase + env->nwindows * 16,
71
return true;
42
+ sizeof(env->gregs));
72
}
43
}
73
if (type == TCG_TYPE_I32) {
44
env->cwp = new_cwp;
74
+ uval = (uint32_t)val;
45
75
val = (int32_t)val;
46
/* put the wrap registers at their temporary location */
76
}
47
if (new_cwp == env->nwindows - 1) {
77
48
- memcpy32(env->regbase + env->nwindows * 16, env->regbase);
78
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, int ct,
49
+ memcpy(env->regbase + env->nwindows * 16, env->regbase,
79
case TCG_COND_GTU:
50
+ sizeof(env->gregs));
80
ct |= TCG_CT_CONST_U32; /* CLGFI */
51
}
81
break;
52
env->regwptr = env->regbase + (new_cwp * 16);
82
+ case TCG_COND_TSTNE:
53
}
83
+ case TCG_COND_TSTEQ:
54
@@ -XXX,XX +XXX,XX @@ void cpu_gl_switch_gregs(CPUSPARCState *env, uint32_t new_gl)
84
+ if (is_const_p16(uval) >= 0) {
55
dst = get_gl_gregset(env, env->gl);
85
+ return true; /* TMxx */
56
86
+ }
57
if (src != dst) {
87
+ if (risbg_mask(uval)) {
58
- memcpy32(dst, env->gregs);
88
+ return true; /* RISBG */
59
- memcpy32(env->gregs, src);
89
+ }
60
+ memcpy(dst, env->gregs, sizeof(env->gregs));
90
+ break;
61
+ memcpy(env->gregs, src, sizeof(env->gregs));
91
default:
62
}
92
g_assert_not_reached();
63
}
93
}
64
94
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, int ct,
65
@@ -XXX,XX +XXX,XX @@ void cpu_change_pstate(CPUSPARCState *env, uint32_t new_pstate)
95
if (ct & TCG_CT_CONST_INV) {
66
/* Switch global register bank */
96
val = ~val;
67
src = get_gregset(env, new_pstate_regs);
97
}
68
dst = get_gregset(env, pstate_regs);
98
- /*
69
- memcpy32(dst, env->gregs);
99
- * Note that is_const_p16 is a subset of is_const_p32,
70
- memcpy32(env->gregs, src);
100
- * so we don't need both constraints.
71
+ memcpy(dst, env->gregs, sizeof(env->gregs));
101
- */
72
+ memcpy(env->gregs, src, sizeof(env->gregs));
102
if ((ct & TCG_CT_CONST_P32) && is_const_p32(val) >= 0) {
73
} else {
103
return true;
74
trace_win_helper_no_switch_pstate(new_pstate_regs);
104
}
75
}
105
@@ -XXX,XX +XXX,XX @@ static const S390Opcode oi_insns[4] = {
106
static const S390Opcode lif_insns[2] = {
107
RIL_LLILF, RIL_LLIHF,
108
};
109
+static const S390Opcode tm_insns[4] = {
110
+ RI_TMLL, RI_TMLH, RI_TMHL, RI_TMHH
111
+};
112
113
/* load a register with an immediate value */
114
static void tcg_out_movi(TCGContext *s, TCGType type,
115
@@ -XXX,XX +XXX,XX @@ static int tgen_cmp2(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
116
TCGCond inv_c = tcg_invert_cond(c);
117
S390Opcode op;
118
119
+ if (is_tst_cond(c)) {
120
+ tcg_debug_assert(!need_carry);
121
+
122
+ if (!c2const) {
123
+ if (type == TCG_TYPE_I32) {
124
+ tcg_out_insn(s, RRFa, NRK, TCG_REG_R0, r1, c2);
125
+ } else {
126
+ tcg_out_insn(s, RRFa, NGRK, TCG_REG_R0, r1, c2);
127
+ }
128
+ goto exit;
129
+ }
130
+
131
+ if (type == TCG_TYPE_I32) {
132
+ c2 = (uint32_t)c2;
133
+ }
134
+
135
+ int i = is_const_p16(c2);
136
+ if (i >= 0) {
137
+ tcg_out_insn_RI(s, tm_insns[i], r1, c2 >> (i * 16));
138
+ *inv_cc = c == TCG_COND_TSTEQ ? S390_TM_NE : S390_TM_EQ;
139
+ return *inv_cc ^ 15;
140
+ }
141
+
142
+ if (risbg_mask(c2)) {
143
+ tgen_andi_risbg(s, TCG_REG_R0, r1, c2);
144
+ goto exit;
145
+ }
146
+ g_assert_not_reached();
147
+ }
148
+
149
if (c2const) {
150
if (c2 == 0) {
151
if (!(is_unsigned && need_carry)) {
152
@@ -XXX,XX +XXX,XX @@ static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
153
TCGReg r1, TCGArg c2, int c2const, TCGLabel *l)
154
{
155
int cc;
156
- bool is_unsigned = is_unsigned_cond(c);
157
- bool in_range;
158
- S390Opcode opc;
159
160
- cc = tcg_cond_to_s390_cond[c];
161
+ if (!is_tst_cond(c)) {
162
+ bool is_unsigned = is_unsigned_cond(c);
163
+ bool in_range;
164
+ S390Opcode opc;
165
166
- if (!c2const) {
167
- opc = (type == TCG_TYPE_I32
168
- ? (is_unsigned ? RIEb_CLRJ : RIEb_CRJ)
169
- : (is_unsigned ? RIEb_CLGRJ : RIEb_CGRJ));
170
- tgen_compare_branch(s, opc, cc, r1, c2, l);
171
- return;
172
- }
173
+ cc = tcg_cond_to_s390_cond[c];
174
175
- /*
176
- * COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
177
- * If the immediate we've been given does not fit that range, we'll
178
- * fall back to separate compare and branch instructions using the
179
- * larger comparison range afforded by COMPARE IMMEDIATE.
180
- */
181
- if (type == TCG_TYPE_I32) {
182
- if (is_unsigned) {
183
- opc = RIEc_CLIJ;
184
- in_range = (uint32_t)c2 == (uint8_t)c2;
185
- } else {
186
- opc = RIEc_CIJ;
187
- in_range = (int32_t)c2 == (int8_t)c2;
188
+ if (!c2const) {
189
+ opc = (type == TCG_TYPE_I32
190
+ ? (is_unsigned ? RIEb_CLRJ : RIEb_CRJ)
191
+ : (is_unsigned ? RIEb_CLGRJ : RIEb_CGRJ));
192
+ tgen_compare_branch(s, opc, cc, r1, c2, l);
193
+ return;
194
}
195
- } else {
196
- if (is_unsigned) {
197
- opc = RIEc_CLGIJ;
198
- in_range = (uint64_t)c2 == (uint8_t)c2;
199
+
200
+ /*
201
+ * COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
202
+ * If the immediate we've been given does not fit that range, we'll
203
+ * fall back to separate compare and branch instructions using the
204
+ * larger comparison range afforded by COMPARE IMMEDIATE.
205
+ */
206
+ if (type == TCG_TYPE_I32) {
207
+ if (is_unsigned) {
208
+ opc = RIEc_CLIJ;
209
+ in_range = (uint32_t)c2 == (uint8_t)c2;
210
+ } else {
211
+ opc = RIEc_CIJ;
212
+ in_range = (int32_t)c2 == (int8_t)c2;
213
+ }
214
} else {
215
- opc = RIEc_CGIJ;
216
- in_range = (int64_t)c2 == (int8_t)c2;
217
+ if (is_unsigned) {
218
+ opc = RIEc_CLGIJ;
219
+ in_range = (uint64_t)c2 == (uint8_t)c2;
220
+ } else {
221
+ opc = RIEc_CGIJ;
222
+ in_range = (int64_t)c2 == (int8_t)c2;
223
+ }
224
+ }
225
+ if (in_range) {
226
+ tgen_compare_imm_branch(s, opc, cc, r1, c2, l);
227
+ return;
228
}
229
- }
230
- if (in_range) {
231
- tgen_compare_imm_branch(s, opc, cc, r1, c2, l);
232
- return;
233
}
234
235
cc = tgen_cmp(s, type, c, r1, c2, c2const, false);
236
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
237
ldst->oi = oi;
238
ldst->addrlo_reg = addr_reg;
239
240
- /* We are expecting a_bits to max out at 7, much lower than TMLL. */
241
tcg_debug_assert(a_mask <= 0xffff);
242
tcg_out_insn(s, RI, TMLL, addr_reg, a_mask);
243
244
- tcg_out16(s, RI_BRC | (7 << 4)); /* CC in {1,2,3} */
245
+ tcg_out16(s, RI_BRC | (S390_TM_NE << 4));
246
ldst->label_ptr[0] = s->code_ptr++;
247
}
248
249
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ldst_i128(TCGContext *s, TCGReg datalo, TCGReg datahi,
250
l2 = gen_new_label();
251
252
tcg_out_insn(s, RI, TMLL, addr_reg, 15);
253
- tgen_branch(s, 7, l1); /* CC in {1,2,3} */
254
+ tgen_branch(s, S390_TM_NE, l1);
255
}
256
257
tcg_debug_assert(!need_bswap);
76
--
258
--
77
2.43.0
259
2.34.1
78
79
diff view generated by jsdifflib