1
The following changes since commit 39a6e4f87e7b75a45b08d6dc8b8b7c2954c87440:
1
Pretty small still, but there are two patches that ought
2
to get backported to stable, so no point in delaying.
2
3
3
Merge tag 'pull-qapi-2024-02-03' of https://repo.or.cz/qemu/armbru into staging (2024-02-03 13:31:58 +0000)
4
r~
5
6
The following changes since commit a5ba0a7e4e150d1350a041f0d0ef9ca6c8d7c307:
7
8
Merge tag 'pull-aspeed-20241211' of https://github.com/legoater/qemu into staging (2024-12-11 15:16:47 +0000)
4
9
5
are available in the Git repository at:
10
are available in the Git repository at:
6
11
7
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20240205
12
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20241212
8
13
9
for you to fetch changes up to 867db6870a6f5d4e0915822d6a84e665bec1f22e:
14
for you to fetch changes up to 7ac87b14a92234b6a89b701b4043ad6cf8bdcccf:
10
15
11
tcg/tci: Support TCG_COND_TST{EQ,NE} (2024-02-03 23:53:49 +0000)
16
target/sparc: Use memcpy() and remove memcpy32() (2024-12-12 14:28:38 -0600)
12
17
13
----------------------------------------------------------------
18
----------------------------------------------------------------
14
tcg: Introduce TCG_COND_TST{EQ,NE}
19
tcg: Reset free_temps before tcg_optimize
15
target/alpha: Use TCG_COND_TST{EQ,NE}
20
tcg/riscv: Fix StoreStore barrier generation
16
target/m68k: Use TCG_COND_TST{EQ,NE} in gen_fcc_cond
21
include/exec: Introduce fpst alias in helper-head.h.inc
17
target/sparc: Use TCG_COND_TSTEQ in gen_op_mulscc
22
target/sparc: Use memcpy() and remove memcpy32()
18
target/s390x: Use TCG_COND_TSTNE for CC_OP_{TM,ICM}
19
target/s390x: Improve general case of disas_jcc
20
23
21
----------------------------------------------------------------
24
----------------------------------------------------------------
22
Paolo Bonzini (1):
25
Philippe Mathieu-Daudé (1):
23
tcg/i386: Use TEST r,r to test 8/16/32 bits
26
target/sparc: Use memcpy() and remove memcpy32()
24
27
25
Philippe Mathieu-Daudé (1):
28
Richard Henderson (2):
26
tcg/aarch64: Massage tcg_out_brcond()
29
tcg: Reset free_temps before tcg_optimize
30
include/exec: Introduce fpst alias in helper-head.h.inc
27
31
28
Richard Henderson (37):
32
Roman Artemev (1):
29
tcg: Introduce TCG_COND_TST{EQ,NE}
33
tcg/riscv: Fix StoreStore barrier generation
30
tcg: Introduce TCG_TARGET_HAS_tst
31
tcg/optimize: Split out arg_is_const_val
32
tcg/optimize: Split out do_constant_folding_cond1
33
tcg/optimize: Do swap_commutative2 in do_constant_folding_cond2
34
tcg/optimize: Handle TCG_COND_TST{EQ,NE}
35
tcg/optimize: Lower TCG_COND_TST{EQ,NE} if unsupported
36
target/alpha: Pass immediate value to gen_bcond_internal()
37
target/alpha: Use TCG_COND_TST{EQ,NE} for BLB{C,S}
38
target/alpha: Use TCG_COND_TST{EQ,NE} for CMOVLB{C,S}
39
target/alpha: Use TCG_COND_TSTNE for gen_fold_mzero
40
target/m68k: Use TCG_COND_TST{EQ,NE} in gen_fcc_cond
41
target/sparc: Use TCG_COND_TSTEQ in gen_op_mulscc
42
target/s390x: Use TCG_COND_TSTNE for CC_OP_{TM,ICM}
43
target/s390x: Improve general case of disas_jcc
44
tcg: Add TCGConst argument to tcg_target_const_match
45
tcg/aarch64: Support TCG_COND_TST{EQ,NE}
46
tcg/aarch64: Generate TBZ, TBNZ
47
tcg/aarch64: Generate CBNZ for TSTNE of UINT32_MAX
48
tcg/arm: Split out tcg_out_cmp()
49
tcg/arm: Support TCG_COND_TST{EQ,NE}
50
tcg/i386: Pass x86 condition codes to tcg_out_cmov
51
tcg/i386: Move tcg_cond_to_jcc[] into tcg_out_cmp
52
tcg/i386: Support TCG_COND_TST{EQ,NE}
53
tcg/i386: Improve TSTNE/TESTEQ vs powers of two
54
tcg/sparc64: Hoist read of tcg_cond_to_rcond
55
tcg/sparc64: Pass TCGCond to tcg_out_cmp
56
tcg/sparc64: Support TCG_COND_TST{EQ,NE}
57
tcg/ppc: Sink tcg_to_bc usage into tcg_out_bc
58
tcg/ppc: Use cr0 in tcg_to_bc and tcg_to_isel
59
tcg/ppc: Tidy up tcg_target_const_match
60
tcg/ppc: Add TCG_CT_CONST_CMP
61
tcg/ppc: Support TCG_COND_TST{EQ,NE}
62
tcg/s390x: Split constraint A into J+U
63
tcg/s390x: Add TCG_CT_CONST_CMP
64
tcg/s390x: Support TCG_COND_TST{EQ,NE}
65
tcg/tci: Support TCG_COND_TST{EQ,NE}
66
34
67
include/tcg/tcg-cond.h | 74 ++++--
35
include/tcg/tcg-temp-internal.h | 6 ++++++
68
tcg/aarch64/tcg-target-con-set.h | 5 +-
36
accel/tcg/plugin-gen.c | 2 +-
69
tcg/aarch64/tcg-target-con-str.h | 1 +
37
target/sparc/win_helper.c | 26 ++++++++------------------
70
tcg/aarch64/tcg-target.h | 2 +
38
tcg/tcg.c | 5 ++++-
71
tcg/arm/tcg-target.h | 2 +
39
include/exec/helper-head.h.inc | 3 +++
72
tcg/i386/tcg-target-con-set.h | 6 +-
40
tcg/riscv/tcg-target.c.inc | 2 +-
73
tcg/i386/tcg-target-con-str.h | 1 +
41
6 files changed, 23 insertions(+), 21 deletions(-)
74
tcg/i386/tcg-target.h | 2 +
75
tcg/loongarch64/tcg-target.h | 2 +
76
tcg/mips/tcg-target.h | 2 +
77
tcg/ppc/tcg-target-con-set.h | 5 +-
78
tcg/ppc/tcg-target-con-str.h | 1 +
79
tcg/ppc/tcg-target.h | 2 +
80
tcg/riscv/tcg-target.h | 2 +
81
tcg/s390x/tcg-target-con-set.h | 8 +-
82
tcg/s390x/tcg-target-con-str.h | 3 +-
83
tcg/s390x/tcg-target.h | 2 +
84
tcg/sparc64/tcg-target.h | 2 +
85
tcg/tcg-internal.h | 2 +
86
tcg/tci/tcg-target.h | 2 +
87
target/alpha/translate.c | 94 ++++----
88
target/m68k/translate.c | 74 +++---
89
target/s390x/tcg/translate.c | 100 +++------
90
target/sparc/translate.c | 4 +-
91
tcg/optimize.c | 474 ++++++++++++++++++++++++++++++---------
92
tcg/tcg.c | 40 +++-
93
tcg/tci.c | 14 ++
94
docs/devel/tcg-ops.rst | 2 +
95
tcg/aarch64/tcg-target.c.inc | 166 +++++++++++---
96
tcg/arm/tcg-target.c.inc | 62 +++--
97
tcg/i386/tcg-target.c.inc | 201 ++++++++++++-----
98
tcg/loongarch64/tcg-target.c.inc | 3 +-
99
tcg/mips/tcg-target.c.inc | 3 +-
100
tcg/ppc/tcg-target.c.inc | 294 ++++++++++++++++++------
101
tcg/riscv/tcg-target.c.inc | 3 +-
102
tcg/s390x/tcg-target.c.inc | 246 +++++++++++++-------
103
tcg/sparc64/tcg-target.c.inc | 65 ++++--
104
tcg/tci/tcg-target.c.inc | 3 +-
105
38 files changed, 1379 insertions(+), 595 deletions(-)
106
42
diff view generated by jsdifflib
1
Add the enumerators, adjust the helpers to match, and dump.
1
When allocating new temps during tcg_optmize, do not re-use
2
Not supported anywhere else just yet.
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.
3
4
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>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
16
---
7
include/tcg/tcg-cond.h | 74 ++++++++++++++++++++++++++++++------------
17
include/tcg/tcg-temp-internal.h | 6 ++++++
8
tcg/tcg.c | 4 ++-
18
accel/tcg/plugin-gen.c | 2 +-
9
docs/devel/tcg-ops.rst | 2 ++
19
tcg/tcg.c | 5 ++++-
10
3 files changed, 58 insertions(+), 22 deletions(-)
20
3 files changed, 11 insertions(+), 2 deletions(-)
11
21
12
diff --git a/include/tcg/tcg-cond.h b/include/tcg/tcg-cond.h
22
diff --git a/include/tcg/tcg-temp-internal.h b/include/tcg/tcg-temp-internal.h
13
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
14
--- a/include/tcg/tcg-cond.h
24
--- a/include/tcg/tcg-temp-internal.h
15
+++ b/include/tcg/tcg-cond.h
25
+++ b/include/tcg/tcg-temp-internal.h
16
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@ TCGv_i64 tcg_temp_ebb_new_i64(void);
17
* Conditions. Note that these are laid out for easy manipulation by
27
TCGv_ptr tcg_temp_ebb_new_ptr(void);
18
* the functions below:
28
TCGv_i128 tcg_temp_ebb_new_i128(void);
19
* bit 0 is used for inverting;
29
20
- * bit 1 is signed,
30
+/* Forget all freed EBB temps, so that new allocations produce new temps. */
21
- * bit 2 is unsigned,
31
+static inline void tcg_temp_ebb_reset_freed(TCGContext *s)
22
- * bit 3 is used with bit 0 for swapping signed/unsigned.
32
+{
23
+ * bit 1 is used for conditions that need swapping (signed/unsigned).
33
+ memset(s->free_temps, 0, sizeof(s->free_temps));
24
+ * bit 2 is used with bit 1 for swapping.
25
+ * bit 3 is used for unsigned conditions.
26
*/
27
typedef enum {
28
/* non-signed */
29
TCG_COND_NEVER = 0 | 0 | 0 | 0,
30
TCG_COND_ALWAYS = 0 | 0 | 0 | 1,
31
+
32
+ /* equality */
33
TCG_COND_EQ = 8 | 0 | 0 | 0,
34
TCG_COND_NE = 8 | 0 | 0 | 1,
35
+
36
+ /* "test" i.e. and then compare vs 0 */
37
+ TCG_COND_TSTEQ = 8 | 4 | 0 | 0,
38
+ TCG_COND_TSTNE = 8 | 4 | 0 | 1,
39
+
40
/* signed */
41
TCG_COND_LT = 0 | 0 | 2 | 0,
42
TCG_COND_GE = 0 | 0 | 2 | 1,
43
- TCG_COND_LE = 8 | 0 | 2 | 0,
44
- TCG_COND_GT = 8 | 0 | 2 | 1,
45
+ TCG_COND_GT = 0 | 4 | 2 | 0,
46
+ TCG_COND_LE = 0 | 4 | 2 | 1,
47
+
48
/* unsigned */
49
- TCG_COND_LTU = 0 | 4 | 0 | 0,
50
- TCG_COND_GEU = 0 | 4 | 0 | 1,
51
- TCG_COND_LEU = 8 | 4 | 0 | 0,
52
- TCG_COND_GTU = 8 | 4 | 0 | 1,
53
+ TCG_COND_LTU = 8 | 0 | 2 | 0,
54
+ TCG_COND_GEU = 8 | 0 | 2 | 1,
55
+ TCG_COND_GTU = 8 | 4 | 2 | 0,
56
+ TCG_COND_LEU = 8 | 4 | 2 | 1,
57
} TCGCond;
58
59
/* Invert the sense of the comparison. */
60
@@ -XXX,XX +XXX,XX @@ static inline TCGCond tcg_invert_cond(TCGCond c)
61
/* Swap the operands in a comparison. */
62
static inline TCGCond tcg_swap_cond(TCGCond c)
63
{
64
- return c & 6 ? (TCGCond)(c ^ 9) : c;
65
+ return (TCGCond)(c ^ ((c & 2) << 1));
66
}
67
68
-/* Create an "unsigned" version of a "signed" comparison. */
69
-static inline TCGCond tcg_unsigned_cond(TCGCond c)
70
+/* Must a comparison be considered signed? */
71
+static inline bool is_signed_cond(TCGCond c)
72
{
73
- return c & 2 ? (TCGCond)(c ^ 6) : c;
74
-}
75
-
76
-/* Create a "signed" version of an "unsigned" comparison. */
77
-static inline TCGCond tcg_signed_cond(TCGCond c)
78
-{
79
- return c & 4 ? (TCGCond)(c ^ 6) : c;
80
+ return (c & (8 | 2)) == 2;
81
}
82
83
/* Must a comparison be considered unsigned? */
84
static inline bool is_unsigned_cond(TCGCond c)
85
{
86
- return (c & 4) != 0;
87
+ return (c & (8 | 2)) == (8 | 2);
88
+}
34
+}
89
+
35
+
90
+/* Must a comparison be considered a test? */
36
#endif /* TCG_TEMP_FREE_H */
91
+static inline bool is_tst_cond(TCGCond c)
37
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
92
+{
38
index XXXXXXX..XXXXXXX 100644
93
+ return (c | 1) == TCG_COND_TSTNE;
39
--- a/accel/tcg/plugin-gen.c
94
+}
40
+++ b/accel/tcg/plugin-gen.c
95
+
41
@@ -XXX,XX +XXX,XX @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
96
+/* Create an "unsigned" version of a "signed" comparison. */
42
* that might be live within the existing opcode stream.
97
+static inline TCGCond tcg_unsigned_cond(TCGCond c)
43
* The simplest solution is to release them all and create new.
98
+{
44
*/
99
+ return is_signed_cond(c) ? (TCGCond)(c + 8) : c;
45
- memset(tcg_ctx->free_temps, 0, sizeof(tcg_ctx->free_temps));
100
+}
46
+ tcg_temp_ebb_reset_freed(tcg_ctx);
101
+
47
102
+/* Create a "signed" version of an "unsigned" comparison. */
48
QTAILQ_FOREACH_SAFE(op, &tcg_ctx->ops, link, next) {
103
+static inline TCGCond tcg_signed_cond(TCGCond c)
49
switch (op->opc) {
104
+{
105
+ return is_unsigned_cond(c) ? (TCGCond)(c - 8) : c;
106
+}
107
+
108
+/* Create the eq/ne version of a tsteq/tstne comparison. */
109
+static inline TCGCond tcg_tst_eqne_cond(TCGCond c)
110
+{
111
+ return is_tst_cond(c) ? (TCGCond)(c - 4) : c;
112
+}
113
+
114
+/* Create the lt/ge version of a tstne/tsteq comparison of the sign. */
115
+static inline TCGCond tcg_tst_ltge_cond(TCGCond c)
116
+{
117
+ return is_tst_cond(c) ? (TCGCond)(c ^ 0xf) : c;
118
}
119
120
/*
121
@@ -XXX,XX +XXX,XX @@ static inline TCGCond tcg_high_cond(TCGCond c)
122
case TCG_COND_LE:
123
case TCG_COND_GEU:
124
case TCG_COND_LEU:
125
- return (TCGCond)(c ^ 8);
126
+ return (TCGCond)(c ^ (4 | 1));
127
default:
128
return c;
129
}
130
diff --git a/tcg/tcg.c b/tcg/tcg.c
50
diff --git a/tcg/tcg.c b/tcg/tcg.c
131
index XXXXXXX..XXXXXXX 100644
51
index XXXXXXX..XXXXXXX 100644
132
--- a/tcg/tcg.c
52
--- a/tcg/tcg.c
133
+++ b/tcg/tcg.c
53
+++ b/tcg/tcg.c
134
@@ -XXX,XX +XXX,XX @@ static const char * const cond_name[] =
54
@@ -XXX,XX +XXX,XX @@ void tcg_func_start(TCGContext *s)
135
[TCG_COND_LTU] = "ltu",
55
s->nb_temps = s->nb_globals;
136
[TCG_COND_GEU] = "geu",
56
137
[TCG_COND_LEU] = "leu",
57
/* No temps have been previously allocated for size or locality. */
138
- [TCG_COND_GTU] = "gtu"
58
- memset(s->free_temps, 0, sizeof(s->free_temps));
139
+ [TCG_COND_GTU] = "gtu",
59
+ tcg_temp_ebb_reset_freed(s);
140
+ [TCG_COND_TSTEQ] = "tsteq",
60
141
+ [TCG_COND_TSTNE] = "tstne",
61
/* No constant temps have been previously allocated. */
142
};
62
for (int i = 0; i < TCG_TYPE_COUNT; ++i) {
143
63
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
144
static const char * const ldst_name[(MO_BSWAP | MO_SSIZE) + 1] =
64
}
145
diff --git a/docs/devel/tcg-ops.rst b/docs/devel/tcg-ops.rst
65
#endif
146
index XXXXXXX..XXXXXXX 100644
66
147
--- a/docs/devel/tcg-ops.rst
67
+ /* Do not reuse any EBB that may be allocated within the TB. */
148
+++ b/docs/devel/tcg-ops.rst
68
+ tcg_temp_ebb_reset_freed(s);
149
@@ -XXX,XX +XXX,XX @@ Jumps/Labels
69
+
150
| ``TCG_COND_GEU /* unsigned */``
70
tcg_optimize(s);
151
| ``TCG_COND_LEU /* unsigned */``
71
152
| ``TCG_COND_GTU /* unsigned */``
72
reachable_code_pass(s);
153
+ | ``TCG_COND_TSTEQ /* t1 & t2 == 0 */``
154
+ | ``TCG_COND_TSTNE /* t1 & t2 != 0 */``
155
156
Arithmetic
157
----------
158
--
73
--
159
2.34.1
74
2.43.0
160
75
161
76
diff view generated by jsdifflib
Deleted patch
1
Define as 0 for all tcg backends.
2
1
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/aarch64/tcg-target.h | 2 ++
7
tcg/arm/tcg-target.h | 2 ++
8
tcg/i386/tcg-target.h | 2 ++
9
tcg/loongarch64/tcg-target.h | 2 ++
10
tcg/mips/tcg-target.h | 2 ++
11
tcg/ppc/tcg-target.h | 2 ++
12
tcg/riscv/tcg-target.h | 2 ++
13
tcg/s390x/tcg-target.h | 2 ++
14
tcg/sparc64/tcg-target.h | 2 ++
15
tcg/tci/tcg-target.h | 2 ++
16
10 files changed, 20 insertions(+)
17
18
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/tcg/aarch64/tcg-target.h
21
+++ b/tcg/aarch64/tcg-target.h
22
@@ -XXX,XX +XXX,XX @@ typedef enum {
23
#define TCG_TARGET_HAS_qemu_ldst_i128 1
24
#endif
25
26
+#define TCG_TARGET_HAS_tst 0
27
+
28
#define TCG_TARGET_HAS_v64 1
29
#define TCG_TARGET_HAS_v128 1
30
#define TCG_TARGET_HAS_v256 0
31
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/tcg/arm/tcg-target.h
34
+++ b/tcg/arm/tcg-target.h
35
@@ -XXX,XX +XXX,XX @@ extern bool use_neon_instructions;
36
37
#define TCG_TARGET_HAS_qemu_ldst_i128 0
38
39
+#define TCG_TARGET_HAS_tst 0
40
+
41
#define TCG_TARGET_HAS_v64 use_neon_instructions
42
#define TCG_TARGET_HAS_v128 use_neon_instructions
43
#define TCG_TARGET_HAS_v256 0
44
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
45
index XXXXXXX..XXXXXXX 100644
46
--- a/tcg/i386/tcg-target.h
47
+++ b/tcg/i386/tcg-target.h
48
@@ -XXX,XX +XXX,XX @@ typedef enum {
49
#define TCG_TARGET_HAS_qemu_ldst_i128 \
50
(TCG_TARGET_REG_BITS == 64 && (cpuinfo & CPUINFO_ATOMIC_VMOVDQA))
51
52
+#define TCG_TARGET_HAS_tst 0
53
+
54
/* We do not support older SSE systems, only beginning with AVX1. */
55
#define TCG_TARGET_HAS_v64 have_avx1
56
#define TCG_TARGET_HAS_v128 have_avx1
57
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
58
index XXXXXXX..XXXXXXX 100644
59
--- a/tcg/loongarch64/tcg-target.h
60
+++ b/tcg/loongarch64/tcg-target.h
61
@@ -XXX,XX +XXX,XX @@ typedef enum {
62
63
#define TCG_TARGET_HAS_qemu_ldst_i128 (cpuinfo & CPUINFO_LSX)
64
65
+#define TCG_TARGET_HAS_tst 0
66
+
67
#define TCG_TARGET_HAS_v64 0
68
#define TCG_TARGET_HAS_v128 (cpuinfo & CPUINFO_LSX)
69
#define TCG_TARGET_HAS_v256 0
70
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
71
index XXXXXXX..XXXXXXX 100644
72
--- a/tcg/mips/tcg-target.h
73
+++ b/tcg/mips/tcg-target.h
74
@@ -XXX,XX +XXX,XX @@ extern bool use_mips32r2_instructions;
75
76
#define TCG_TARGET_HAS_qemu_ldst_i128 0
77
78
+#define TCG_TARGET_HAS_tst 0
79
+
80
#define TCG_TARGET_DEFAULT_MO 0
81
#define TCG_TARGET_NEED_LDST_LABELS
82
#define TCG_TARGET_NEED_POOL_LABELS
83
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
84
index XXXXXXX..XXXXXXX 100644
85
--- a/tcg/ppc/tcg-target.h
86
+++ b/tcg/ppc/tcg-target.h
87
@@ -XXX,XX +XXX,XX @@ typedef enum {
88
#define TCG_TARGET_HAS_qemu_ldst_i128 \
89
(TCG_TARGET_REG_BITS == 64 && have_isa_2_07)
90
91
+#define TCG_TARGET_HAS_tst 0
92
+
93
/*
94
* While technically Altivec could support V64, it has no 64-bit store
95
* instruction and substituting two 32-bit stores makes the generated
96
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
97
index XXXXXXX..XXXXXXX 100644
98
--- a/tcg/riscv/tcg-target.h
99
+++ b/tcg/riscv/tcg-target.h
100
@@ -XXX,XX +XXX,XX @@ extern bool have_zbb;
101
102
#define TCG_TARGET_HAS_qemu_ldst_i128 0
103
104
+#define TCG_TARGET_HAS_tst 0
105
+
106
#define TCG_TARGET_DEFAULT_MO (0)
107
108
#define TCG_TARGET_NEED_LDST_LABELS
109
diff --git a/tcg/s390x/tcg-target.h b/tcg/s390x/tcg-target.h
110
index XXXXXXX..XXXXXXX 100644
111
--- a/tcg/s390x/tcg-target.h
112
+++ b/tcg/s390x/tcg-target.h
113
@@ -XXX,XX +XXX,XX @@ extern uint64_t s390_facilities[3];
114
115
#define TCG_TARGET_HAS_qemu_ldst_i128 1
116
117
+#define TCG_TARGET_HAS_tst 0
118
+
119
#define TCG_TARGET_HAS_v64 HAVE_FACILITY(VECTOR)
120
#define TCG_TARGET_HAS_v128 HAVE_FACILITY(VECTOR)
121
#define TCG_TARGET_HAS_v256 0
122
diff --git a/tcg/sparc64/tcg-target.h b/tcg/sparc64/tcg-target.h
123
index XXXXXXX..XXXXXXX 100644
124
--- a/tcg/sparc64/tcg-target.h
125
+++ b/tcg/sparc64/tcg-target.h
126
@@ -XXX,XX +XXX,XX @@ extern bool use_vis3_instructions;
127
128
#define TCG_TARGET_HAS_qemu_ldst_i128 0
129
130
+#define TCG_TARGET_HAS_tst 0
131
+
132
#define TCG_AREG0 TCG_REG_I0
133
134
#define TCG_TARGET_DEFAULT_MO (0)
135
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
136
index XXXXXXX..XXXXXXX 100644
137
--- a/tcg/tci/tcg-target.h
138
+++ b/tcg/tci/tcg-target.h
139
@@ -XXX,XX +XXX,XX @@
140
141
#define TCG_TARGET_HAS_qemu_ldst_i128 0
142
143
+#define TCG_TARGET_HAS_tst 0
144
+
145
/* Number of registers available. */
146
#define TCG_TARGET_NB_REGS 16
147
148
--
149
2.34.1
150
151
diff view generated by jsdifflib
Deleted patch
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
tcg/optimize.c | 38 +++++++++++++++++++++++---------------
5
1 file changed, 23 insertions(+), 15 deletions(-)
6
1
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/optimize.c
10
+++ b/tcg/optimize.c
11
@@ -XXX,XX +XXX,XX @@ static inline bool ts_is_const(TCGTemp *ts)
12
return ts_info(ts)->is_const;
13
}
14
15
+static inline bool ts_is_const_val(TCGTemp *ts, uint64_t val)
16
+{
17
+ TempOptInfo *ti = ts_info(ts);
18
+ return ti->is_const && ti->val == val;
19
+}
20
+
21
static inline bool arg_is_const(TCGArg arg)
22
{
23
return ts_is_const(arg_temp(arg));
24
}
25
26
+static inline bool arg_is_const_val(TCGArg arg, uint64_t val)
27
+{
28
+ return ts_is_const_val(arg_temp(arg), val);
29
+}
30
+
31
static inline bool ts_is_copy(TCGTemp *ts)
32
{
33
return ts_info(ts)->next_copy != ts;
34
@@ -XXX,XX +XXX,XX @@ static int do_constant_folding_cond(TCGType type, TCGArg x,
35
}
36
} else if (args_are_copies(x, y)) {
37
return do_constant_folding_cond_eq(c);
38
- } else if (arg_is_const(y) && arg_info(y)->val == 0) {
39
+ } else if (arg_is_const_val(y, 0)) {
40
switch (c) {
41
case TCG_COND_LTU:
42
return 0;
43
@@ -XXX,XX +XXX,XX @@ static bool fold_to_not(OptContext *ctx, TCGOp *op, int idx)
44
/* If the binary operation has first argument @i, fold to @i. */
45
static bool fold_ix_to_i(OptContext *ctx, TCGOp *op, uint64_t i)
46
{
47
- if (arg_is_const(op->args[1]) && arg_info(op->args[1])->val == i) {
48
+ if (arg_is_const_val(op->args[1], i)) {
49
return tcg_opt_gen_movi(ctx, op, op->args[0], i);
50
}
51
return false;
52
@@ -XXX,XX +XXX,XX @@ static bool fold_ix_to_i(OptContext *ctx, TCGOp *op, uint64_t i)
53
/* If the binary operation has first argument @i, fold to NOT. */
54
static bool fold_ix_to_not(OptContext *ctx, TCGOp *op, uint64_t i)
55
{
56
- if (arg_is_const(op->args[1]) && arg_info(op->args[1])->val == i) {
57
+ if (arg_is_const_val(op->args[1], i)) {
58
return fold_to_not(ctx, op, 2);
59
}
60
return false;
61
@@ -XXX,XX +XXX,XX @@ static bool fold_ix_to_not(OptContext *ctx, TCGOp *op, uint64_t i)
62
/* If the binary operation has second argument @i, fold to @i. */
63
static bool fold_xi_to_i(OptContext *ctx, TCGOp *op, uint64_t i)
64
{
65
- if (arg_is_const(op->args[2]) && arg_info(op->args[2])->val == i) {
66
+ if (arg_is_const_val(op->args[2], i)) {
67
return tcg_opt_gen_movi(ctx, op, op->args[0], i);
68
}
69
return false;
70
@@ -XXX,XX +XXX,XX @@ static bool fold_xi_to_i(OptContext *ctx, TCGOp *op, uint64_t i)
71
/* If the binary operation has second argument @i, fold to identity. */
72
static bool fold_xi_to_x(OptContext *ctx, TCGOp *op, uint64_t i)
73
{
74
- if (arg_is_const(op->args[2]) && arg_info(op->args[2])->val == i) {
75
+ if (arg_is_const_val(op->args[2], i)) {
76
return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[1]);
77
}
78
return false;
79
@@ -XXX,XX +XXX,XX @@ static bool fold_xi_to_x(OptContext *ctx, TCGOp *op, uint64_t i)
80
/* If the binary operation has second argument @i, fold to NOT. */
81
static bool fold_xi_to_not(OptContext *ctx, TCGOp *op, uint64_t i)
82
{
83
- if (arg_is_const(op->args[2]) && arg_info(op->args[2])->val == i) {
84
+ if (arg_is_const_val(op->args[2], i)) {
85
return fold_to_not(ctx, op, 1);
86
}
87
return false;
88
@@ -XXX,XX +XXX,XX @@ static bool fold_brcond2(OptContext *ctx, TCGOp *op)
89
* Simplify LT/GE comparisons vs zero to a single compare
90
* vs the high word of the input.
91
*/
92
- if (arg_is_const(op->args[2]) && arg_info(op->args[2])->val == 0 &&
93
- arg_is_const(op->args[3]) && arg_info(op->args[3])->val == 0) {
94
+ if (arg_is_const_val(op->args[2], 0) &&
95
+ arg_is_const_val(op->args[3], 0)) {
96
goto do_brcond_high;
97
}
98
break;
99
@@ -XXX,XX +XXX,XX @@ static bool fold_deposit(OptContext *ctx, TCGOp *op)
100
}
101
102
/* Inserting a value into zero at offset 0. */
103
- if (arg_is_const(op->args[1])
104
- && arg_info(op->args[1])->val == 0
105
- && op->args[3] == 0) {
106
+ if (arg_is_const_val(op->args[1], 0) && op->args[3] == 0) {
107
uint64_t mask = MAKE_64BIT_MASK(0, op->args[4]);
108
109
op->opc = and_opc;
110
@@ -XXX,XX +XXX,XX @@ static bool fold_deposit(OptContext *ctx, TCGOp *op)
111
}
112
113
/* Inserting zero into a value. */
114
- if (arg_is_const(op->args[2])
115
- && arg_info(op->args[2])->val == 0) {
116
+ if (arg_is_const_val(op->args[2], 0)) {
117
uint64_t mask = deposit64(-1, op->args[3], op->args[4], 0);
118
119
op->opc = and_opc;
120
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond2(OptContext *ctx, TCGOp *op)
121
* Simplify LT/GE comparisons vs zero to a single compare
122
* vs the high word of the input.
123
*/
124
- if (arg_is_const(op->args[3]) && arg_info(op->args[3])->val == 0 &&
125
- arg_is_const(op->args[4]) && arg_info(op->args[4])->val == 0) {
126
+ if (arg_is_const_val(op->args[3], 0) &&
127
+ arg_is_const_val(op->args[4], 0)) {
128
goto do_setcond_high;
129
}
130
break;
131
--
132
2.34.1
133
134
diff view generated by jsdifflib
Deleted patch
1
Handle modifications to the arguments and condition
2
in a single place.
3
1
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
tcg/optimize.c | 57 ++++++++++++++++++++++++--------------------------
8
1 file changed, 27 insertions(+), 30 deletions(-)
9
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/optimize.c
13
+++ b/tcg/optimize.c
14
@@ -XXX,XX +XXX,XX @@ static bool swap_commutative2(TCGArg *p1, TCGArg *p2)
15
return false;
16
}
17
18
+static int do_constant_folding_cond1(OptContext *ctx, TCGArg dest,
19
+ TCGArg *p1, TCGArg *p2, TCGArg *pcond)
20
+{
21
+ TCGCond cond;
22
+ bool swap;
23
+ int r;
24
+
25
+ swap = swap_commutative(dest, p1, p2);
26
+ cond = *pcond;
27
+ if (swap) {
28
+ *pcond = cond = tcg_swap_cond(cond);
29
+ }
30
+
31
+ r = do_constant_folding_cond(ctx->type, *p1, *p2, cond);
32
+ return r;
33
+}
34
+
35
static void init_arguments(OptContext *ctx, TCGOp *op, int nb_args)
36
{
37
for (int i = 0; i < nb_args; i++) {
38
@@ -XXX,XX +XXX,XX @@ static bool fold_andc(OptContext *ctx, TCGOp *op)
39
40
static bool fold_brcond(OptContext *ctx, TCGOp *op)
41
{
42
- TCGCond cond = op->args[2];
43
- int i;
44
-
45
- if (swap_commutative(NO_DEST, &op->args[0], &op->args[1])) {
46
- op->args[2] = cond = tcg_swap_cond(cond);
47
- }
48
-
49
- i = do_constant_folding_cond(ctx->type, op->args[0], op->args[1], cond);
50
+ int i = do_constant_folding_cond1(ctx, NO_DEST, &op->args[0],
51
+ &op->args[1], &op->args[2]);
52
if (i == 0) {
53
tcg_op_remove(ctx->tcg, op);
54
return true;
55
@@ -XXX,XX +XXX,XX @@ static bool fold_mov(OptContext *ctx, TCGOp *op)
56
57
static bool fold_movcond(OptContext *ctx, TCGOp *op)
58
{
59
- TCGCond cond = op->args[5];
60
int i;
61
62
- if (swap_commutative(NO_DEST, &op->args[1], &op->args[2])) {
63
- op->args[5] = cond = tcg_swap_cond(cond);
64
- }
65
/*
66
* Canonicalize the "false" input reg to match the destination reg so
67
* that the tcg backend can implement a "move if true" operation.
68
*/
69
if (swap_commutative(op->args[0], &op->args[4], &op->args[3])) {
70
- op->args[5] = cond = tcg_invert_cond(cond);
71
+ op->args[5] = tcg_invert_cond(op->args[5]);
72
}
73
74
- i = do_constant_folding_cond(ctx->type, op->args[1], op->args[2], cond);
75
+ i = do_constant_folding_cond1(ctx, NO_DEST, &op->args[1],
76
+ &op->args[2], &op->args[5]);
77
if (i >= 0) {
78
return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[4 - i]);
79
}
80
@@ -XXX,XX +XXX,XX @@ static bool fold_movcond(OptContext *ctx, TCGOp *op)
81
uint64_t tv = arg_info(op->args[3])->val;
82
uint64_t fv = arg_info(op->args[4])->val;
83
TCGOpcode opc, negopc = 0;
84
+ TCGCond cond = op->args[5];
85
86
switch (ctx->type) {
87
case TCG_TYPE_I32:
88
@@ -XXX,XX +XXX,XX @@ static bool fold_remainder(OptContext *ctx, TCGOp *op)
89
90
static bool fold_setcond(OptContext *ctx, TCGOp *op)
91
{
92
- TCGCond cond = op->args[3];
93
- int i;
94
-
95
- if (swap_commutative(op->args[0], &op->args[1], &op->args[2])) {
96
- op->args[3] = cond = tcg_swap_cond(cond);
97
- }
98
-
99
- i = do_constant_folding_cond(ctx->type, op->args[1], op->args[2], cond);
100
+ int i = do_constant_folding_cond1(ctx, op->args[0], &op->args[1],
101
+ &op->args[2], &op->args[3]);
102
if (i >= 0) {
103
return tcg_opt_gen_movi(ctx, op, op->args[0], i);
104
}
105
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond(OptContext *ctx, TCGOp *op)
106
107
static bool fold_negsetcond(OptContext *ctx, TCGOp *op)
108
{
109
- TCGCond cond = op->args[3];
110
- int i;
111
-
112
- if (swap_commutative(op->args[0], &op->args[1], &op->args[2])) {
113
- op->args[3] = cond = tcg_swap_cond(cond);
114
- }
115
-
116
- i = do_constant_folding_cond(ctx->type, op->args[1], op->args[2], cond);
117
+ int i = do_constant_folding_cond1(ctx, op->args[0], &op->args[1],
118
+ &op->args[2], &op->args[3]);
119
if (i >= 0) {
120
return tcg_opt_gen_movi(ctx, op, op->args[0], -i);
121
}
122
--
123
2.34.1
124
125
diff view generated by jsdifflib
Deleted patch
1
Mirror the new do_constant_folding_cond1 by doing all
2
argument and condition adjustment within one helper.
3
1
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
tcg/optimize.c | 107 ++++++++++++++++++++++++++-----------------------
8
1 file changed, 57 insertions(+), 50 deletions(-)
9
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/optimize.c
13
+++ b/tcg/optimize.c
14
@@ -XXX,XX +XXX,XX @@ static int do_constant_folding_cond(TCGType type, TCGArg x,
15
return -1;
16
}
17
18
-/*
19
- * Return -1 if the condition can't be simplified,
20
- * and the result of the condition (0 or 1) if it can.
21
- */
22
-static int do_constant_folding_cond2(TCGArg *p1, TCGArg *p2, TCGCond c)
23
-{
24
- TCGArg al = p1[0], ah = p1[1];
25
- TCGArg bl = p2[0], bh = p2[1];
26
-
27
- if (arg_is_const(bl) && arg_is_const(bh)) {
28
- tcg_target_ulong blv = arg_info(bl)->val;
29
- tcg_target_ulong bhv = arg_info(bh)->val;
30
- uint64_t b = deposit64(blv, 32, 32, bhv);
31
-
32
- if (arg_is_const(al) && arg_is_const(ah)) {
33
- tcg_target_ulong alv = arg_info(al)->val;
34
- tcg_target_ulong ahv = arg_info(ah)->val;
35
- uint64_t a = deposit64(alv, 32, 32, ahv);
36
- return do_constant_folding_cond_64(a, b, c);
37
- }
38
- if (b == 0) {
39
- switch (c) {
40
- case TCG_COND_LTU:
41
- return 0;
42
- case TCG_COND_GEU:
43
- return 1;
44
- default:
45
- break;
46
- }
47
- }
48
- }
49
- if (args_are_copies(al, bl) && args_are_copies(ah, bh)) {
50
- return do_constant_folding_cond_eq(c);
51
- }
52
- return -1;
53
-}
54
-
55
/**
56
* swap_commutative:
57
* @dest: TCGArg of the destination argument, or NO_DEST.
58
@@ -XXX,XX +XXX,XX @@ static bool swap_commutative2(TCGArg *p1, TCGArg *p2)
59
return false;
60
}
61
62
+/*
63
+ * Return -1 if the condition can't be simplified,
64
+ * and the result of the condition (0 or 1) if it can.
65
+ */
66
static int do_constant_folding_cond1(OptContext *ctx, TCGArg dest,
67
TCGArg *p1, TCGArg *p2, TCGArg *pcond)
68
{
69
@@ -XXX,XX +XXX,XX @@ static int do_constant_folding_cond1(OptContext *ctx, TCGArg dest,
70
return r;
71
}
72
73
+static int do_constant_folding_cond2(OptContext *ctx, TCGArg *args)
74
+{
75
+ TCGArg al, ah, bl, bh;
76
+ TCGCond c;
77
+ bool swap;
78
+
79
+ swap = swap_commutative2(args, args + 2);
80
+ c = args[4];
81
+ if (swap) {
82
+ args[4] = c = tcg_swap_cond(c);
83
+ }
84
+
85
+ al = args[0];
86
+ ah = args[1];
87
+ bl = args[2];
88
+ bh = args[3];
89
+
90
+ if (arg_is_const(bl) && arg_is_const(bh)) {
91
+ tcg_target_ulong blv = arg_info(bl)->val;
92
+ tcg_target_ulong bhv = arg_info(bh)->val;
93
+ uint64_t b = deposit64(blv, 32, 32, bhv);
94
+
95
+ if (arg_is_const(al) && arg_is_const(ah)) {
96
+ tcg_target_ulong alv = arg_info(al)->val;
97
+ tcg_target_ulong ahv = arg_info(ah)->val;
98
+ uint64_t a = deposit64(alv, 32, 32, ahv);
99
+ return do_constant_folding_cond_64(a, b, c);
100
+ }
101
+ if (b == 0) {
102
+ switch (c) {
103
+ case TCG_COND_LTU:
104
+ return 0;
105
+ case TCG_COND_GEU:
106
+ return 1;
107
+ default:
108
+ break;
109
+ }
110
+ }
111
+ }
112
+ if (args_are_copies(al, bl) && args_are_copies(ah, bh)) {
113
+ return do_constant_folding_cond_eq(c);
114
+ }
115
+ return -1;
116
+}
117
+
118
static void init_arguments(OptContext *ctx, TCGOp *op, int nb_args)
119
{
120
for (int i = 0; i < nb_args; i++) {
121
@@ -XXX,XX +XXX,XX @@ static bool fold_brcond(OptContext *ctx, TCGOp *op)
122
123
static bool fold_brcond2(OptContext *ctx, TCGOp *op)
124
{
125
- TCGCond cond = op->args[4];
126
- TCGArg label = op->args[5];
127
+ TCGCond cond;
128
+ TCGArg label;
129
int i, inv = 0;
130
131
- if (swap_commutative2(&op->args[0], &op->args[2])) {
132
- op->args[4] = cond = tcg_swap_cond(cond);
133
- }
134
-
135
- i = do_constant_folding_cond2(&op->args[0], &op->args[2], cond);
136
+ i = do_constant_folding_cond2(ctx, &op->args[0]);
137
+ cond = op->args[4];
138
+ label = op->args[5];
139
if (i >= 0) {
140
goto do_brcond_const;
141
}
142
@@ -XXX,XX +XXX,XX @@ static bool fold_negsetcond(OptContext *ctx, TCGOp *op)
143
144
static bool fold_setcond2(OptContext *ctx, TCGOp *op)
145
{
146
- TCGCond cond = op->args[5];
147
+ TCGCond cond;
148
int i, inv = 0;
149
150
- if (swap_commutative2(&op->args[1], &op->args[3])) {
151
- op->args[5] = cond = tcg_swap_cond(cond);
152
- }
153
-
154
- i = do_constant_folding_cond2(&op->args[1], &op->args[3], cond);
155
+ i = do_constant_folding_cond2(ctx, &op->args[1]);
156
+ cond = op->args[5];
157
if (i >= 0) {
158
goto do_setcond_const;
159
}
160
--
161
2.34.1
162
163
diff view generated by jsdifflib
Deleted patch
1
Fold constant comparisons.
2
Canonicalize "tst x,x" to equality vs zero.
3
Canonicalize "tst x,sign" to sign test vs zero.
4
Fold double-word comparisons with zero parts.
5
Fold setcond of "tst x,pow2" to a bit extract.
6
1
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
10
tcg/optimize.c | 240 ++++++++++++++++++++++++++++++++++++++++++++-----
11
1 file changed, 218 insertions(+), 22 deletions(-)
12
13
diff --git a/tcg/optimize.c b/tcg/optimize.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tcg/optimize.c
16
+++ b/tcg/optimize.c
17
@@ -XXX,XX +XXX,XX @@ static bool do_constant_folding_cond_32(uint32_t x, uint32_t y, TCGCond c)
18
return x <= y;
19
case TCG_COND_GTU:
20
return x > y;
21
- default:
22
- g_assert_not_reached();
23
+ case TCG_COND_TSTEQ:
24
+ return (x & y) == 0;
25
+ case TCG_COND_TSTNE:
26
+ return (x & y) != 0;
27
+ case TCG_COND_ALWAYS:
28
+ case TCG_COND_NEVER:
29
+ break;
30
}
31
+ g_assert_not_reached();
32
}
33
34
static bool do_constant_folding_cond_64(uint64_t x, uint64_t y, TCGCond c)
35
@@ -XXX,XX +XXX,XX @@ static bool do_constant_folding_cond_64(uint64_t x, uint64_t y, TCGCond c)
36
return x <= y;
37
case TCG_COND_GTU:
38
return x > y;
39
- default:
40
- g_assert_not_reached();
41
+ case TCG_COND_TSTEQ:
42
+ return (x & y) == 0;
43
+ case TCG_COND_TSTNE:
44
+ return (x & y) != 0;
45
+ case TCG_COND_ALWAYS:
46
+ case TCG_COND_NEVER:
47
+ break;
48
}
49
+ g_assert_not_reached();
50
}
51
52
-static bool do_constant_folding_cond_eq(TCGCond c)
53
+static int do_constant_folding_cond_eq(TCGCond c)
54
{
55
switch (c) {
56
case TCG_COND_GT:
57
@@ -XXX,XX +XXX,XX @@ static bool do_constant_folding_cond_eq(TCGCond c)
58
case TCG_COND_LEU:
59
case TCG_COND_EQ:
60
return 1;
61
- default:
62
- g_assert_not_reached();
63
+ case TCG_COND_TSTEQ:
64
+ case TCG_COND_TSTNE:
65
+ return -1;
66
+ case TCG_COND_ALWAYS:
67
+ case TCG_COND_NEVER:
68
+ break;
69
}
70
+ g_assert_not_reached();
71
}
72
73
/*
74
@@ -XXX,XX +XXX,XX @@ static int do_constant_folding_cond(TCGType type, TCGArg x,
75
} else if (arg_is_const_val(y, 0)) {
76
switch (c) {
77
case TCG_COND_LTU:
78
+ case TCG_COND_TSTNE:
79
return 0;
80
case TCG_COND_GEU:
81
+ case TCG_COND_TSTEQ:
82
return 1;
83
default:
84
return -1;
85
@@ -XXX,XX +XXX,XX @@ static int do_constant_folding_cond1(OptContext *ctx, TCGArg dest,
86
}
87
88
r = do_constant_folding_cond(ctx->type, *p1, *p2, cond);
89
- return r;
90
+ if (r >= 0) {
91
+ return r;
92
+ }
93
+ if (!is_tst_cond(cond)) {
94
+ return -1;
95
+ }
96
+
97
+ /*
98
+ * TSTNE x,x -> NE x,0
99
+ * TSTNE x,-1 -> NE x,0
100
+ */
101
+ if (args_are_copies(*p1, *p2) || arg_is_const_val(*p2, -1)) {
102
+ *p2 = arg_new_constant(ctx, 0);
103
+ *pcond = tcg_tst_eqne_cond(cond);
104
+ return -1;
105
+ }
106
+
107
+ /* TSTNE x,sign -> LT x,0 */
108
+ if (arg_is_const_val(*p2, (ctx->type == TCG_TYPE_I32
109
+ ? INT32_MIN : INT64_MIN))) {
110
+ *p2 = arg_new_constant(ctx, 0);
111
+ *pcond = tcg_tst_ltge_cond(cond);
112
+ }
113
+ return -1;
114
}
115
116
static int do_constant_folding_cond2(OptContext *ctx, TCGArg *args)
117
@@ -XXX,XX +XXX,XX @@ static int do_constant_folding_cond2(OptContext *ctx, TCGArg *args)
118
TCGArg al, ah, bl, bh;
119
TCGCond c;
120
bool swap;
121
+ int r;
122
123
swap = swap_commutative2(args, args + 2);
124
c = args[4];
125
@@ -XXX,XX +XXX,XX @@ static int do_constant_folding_cond2(OptContext *ctx, TCGArg *args)
126
tcg_target_ulong alv = arg_info(al)->val;
127
tcg_target_ulong ahv = arg_info(ah)->val;
128
uint64_t a = deposit64(alv, 32, 32, ahv);
129
- return do_constant_folding_cond_64(a, b, c);
130
+
131
+ r = do_constant_folding_cond_64(a, b, c);
132
+ if (r >= 0) {
133
+ return r;
134
+ }
135
}
136
+
137
if (b == 0) {
138
switch (c) {
139
case TCG_COND_LTU:
140
+ case TCG_COND_TSTNE:
141
return 0;
142
case TCG_COND_GEU:
143
+ case TCG_COND_TSTEQ:
144
return 1;
145
default:
146
break;
147
}
148
}
149
+
150
+ /* TSTNE x,-1 -> NE x,0 */
151
+ if (b == -1 && is_tst_cond(c)) {
152
+ args[3] = args[2] = arg_new_constant(ctx, 0);
153
+ args[4] = tcg_tst_eqne_cond(c);
154
+ return -1;
155
+ }
156
+
157
+ /* TSTNE x,sign -> LT x,0 */
158
+ if (b == INT64_MIN && is_tst_cond(c)) {
159
+ /* bl must be 0, so copy that to bh */
160
+ args[3] = bl;
161
+ args[4] = tcg_tst_ltge_cond(c);
162
+ return -1;
163
+ }
164
}
165
+
166
if (args_are_copies(al, bl) && args_are_copies(ah, bh)) {
167
- return do_constant_folding_cond_eq(c);
168
+ r = do_constant_folding_cond_eq(c);
169
+ if (r >= 0) {
170
+ return r;
171
+ }
172
+
173
+ /* TSTNE x,x -> NE x,0 */
174
+ if (is_tst_cond(c)) {
175
+ args[3] = args[2] = arg_new_constant(ctx, 0);
176
+ args[4] = tcg_tst_eqne_cond(c);
177
+ return -1;
178
+ }
179
}
180
return -1;
181
}
182
@@ -XXX,XX +XXX,XX @@ static bool fold_brcond2(OptContext *ctx, TCGOp *op)
183
case 0:
184
goto do_brcond_const;
185
case 1:
186
- op->opc = INDEX_op_brcond_i32;
187
- op->args[1] = op->args[2];
188
- op->args[2] = cond;
189
- op->args[3] = label;
190
- break;
191
+ goto do_brcond_low;
192
+ }
193
+ break;
194
+
195
+ case TCG_COND_TSTEQ:
196
+ case TCG_COND_TSTNE:
197
+ if (arg_is_const_val(op->args[2], 0)) {
198
+ goto do_brcond_high;
199
+ }
200
+ if (arg_is_const_val(op->args[3], 0)) {
201
+ goto do_brcond_low;
202
}
203
break;
204
205
default:
206
break;
207
208
+ do_brcond_low:
209
+ op->opc = INDEX_op_brcond_i32;
210
+ op->args[1] = op->args[2];
211
+ op->args[2] = cond;
212
+ op->args[3] = label;
213
+ return fold_brcond(ctx, op);
214
+
215
do_brcond_high:
216
op->opc = INDEX_op_brcond_i32;
217
op->args[0] = op->args[1];
218
op->args[1] = op->args[3];
219
op->args[2] = cond;
220
op->args[3] = label;
221
- break;
222
+ return fold_brcond(ctx, op);
223
224
do_brcond_const:
225
if (i == 0) {
226
@@ -XXX,XX +XXX,XX @@ static bool fold_remainder(OptContext *ctx, TCGOp *op)
227
return false;
228
}
229
230
+static void fold_setcond_tst_pow2(OptContext *ctx, TCGOp *op, bool neg)
231
+{
232
+ TCGOpcode and_opc, sub_opc, xor_opc, neg_opc, shr_opc, uext_opc, sext_opc;
233
+ TCGCond cond = op->args[3];
234
+ TCGArg ret, src1, src2;
235
+ TCGOp *op2;
236
+ uint64_t val;
237
+ int sh;
238
+ bool inv;
239
+
240
+ if (!is_tst_cond(cond) || !arg_is_const(op->args[2])) {
241
+ return;
242
+ }
243
+
244
+ src2 = op->args[2];
245
+ val = arg_info(src2)->val;
246
+ if (!is_power_of_2(val)) {
247
+ return;
248
+ }
249
+ sh = ctz64(val);
250
+
251
+ switch (ctx->type) {
252
+ case TCG_TYPE_I32:
253
+ and_opc = INDEX_op_and_i32;
254
+ sub_opc = INDEX_op_sub_i32;
255
+ xor_opc = INDEX_op_xor_i32;
256
+ shr_opc = INDEX_op_shr_i32;
257
+ neg_opc = INDEX_op_neg_i32;
258
+ if (TCG_TARGET_extract_i32_valid(sh, 1)) {
259
+ uext_opc = TCG_TARGET_HAS_extract_i32 ? INDEX_op_extract_i32 : 0;
260
+ sext_opc = TCG_TARGET_HAS_sextract_i32 ? INDEX_op_sextract_i32 : 0;
261
+ }
262
+ break;
263
+ case TCG_TYPE_I64:
264
+ and_opc = INDEX_op_and_i64;
265
+ sub_opc = INDEX_op_sub_i64;
266
+ xor_opc = INDEX_op_xor_i64;
267
+ shr_opc = INDEX_op_shr_i64;
268
+ neg_opc = INDEX_op_neg_i64;
269
+ if (TCG_TARGET_extract_i64_valid(sh, 1)) {
270
+ uext_opc = TCG_TARGET_HAS_extract_i64 ? INDEX_op_extract_i64 : 0;
271
+ sext_opc = TCG_TARGET_HAS_sextract_i64 ? INDEX_op_sextract_i64 : 0;
272
+ }
273
+ break;
274
+ default:
275
+ g_assert_not_reached();
276
+ }
277
+
278
+ ret = op->args[0];
279
+ src1 = op->args[1];
280
+ inv = cond == TCG_COND_TSTEQ;
281
+
282
+ if (sh && sext_opc && neg && !inv) {
283
+ op->opc = sext_opc;
284
+ op->args[1] = src1;
285
+ op->args[2] = sh;
286
+ op->args[3] = 1;
287
+ return;
288
+ } else if (sh && uext_opc) {
289
+ op->opc = uext_opc;
290
+ op->args[1] = src1;
291
+ op->args[2] = sh;
292
+ op->args[3] = 1;
293
+ } else {
294
+ if (sh) {
295
+ op2 = tcg_op_insert_before(ctx->tcg, op, shr_opc, 3);
296
+ op2->args[0] = ret;
297
+ op2->args[1] = src1;
298
+ op2->args[2] = arg_new_constant(ctx, sh);
299
+ src1 = ret;
300
+ }
301
+ op->opc = and_opc;
302
+ op->args[1] = src1;
303
+ op->args[2] = arg_new_constant(ctx, 1);
304
+ }
305
+
306
+ if (neg && inv) {
307
+ op2 = tcg_op_insert_after(ctx->tcg, op, sub_opc, 3);
308
+ op2->args[0] = ret;
309
+ op2->args[1] = ret;
310
+ op2->args[2] = arg_new_constant(ctx, 1);
311
+ } else if (inv) {
312
+ op2 = tcg_op_insert_after(ctx->tcg, op, xor_opc, 3);
313
+ op2->args[0] = ret;
314
+ op2->args[1] = ret;
315
+ op2->args[2] = arg_new_constant(ctx, 1);
316
+ } else if (neg) {
317
+ op2 = tcg_op_insert_after(ctx->tcg, op, neg_opc, 2);
318
+ op2->args[0] = ret;
319
+ op2->args[1] = ret;
320
+ }
321
+}
322
+
323
static bool fold_setcond(OptContext *ctx, TCGOp *op)
324
{
325
int i = do_constant_folding_cond1(ctx, op->args[0], &op->args[1],
326
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond(OptContext *ctx, TCGOp *op)
327
if (i >= 0) {
328
return tcg_opt_gen_movi(ctx, op, op->args[0], i);
329
}
330
+ fold_setcond_tst_pow2(ctx, op, false);
331
332
ctx->z_mask = 1;
333
ctx->s_mask = smask_from_zmask(1);
334
@@ -XXX,XX +XXX,XX @@ static bool fold_negsetcond(OptContext *ctx, TCGOp *op)
335
if (i >= 0) {
336
return tcg_opt_gen_movi(ctx, op, op->args[0], -i);
337
}
338
+ fold_setcond_tst_pow2(ctx, op, true);
339
340
/* Value is {0,-1} so all bits are repetitions of the sign. */
341
ctx->s_mask = -1;
342
return false;
343
}
344
345
-
346
static bool fold_setcond2(OptContext *ctx, TCGOp *op)
347
{
348
TCGCond cond;
349
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond2(OptContext *ctx, TCGOp *op)
350
case 0:
351
goto do_setcond_const;
352
case 1:
353
- op->args[2] = op->args[3];
354
- op->args[3] = cond;
355
- op->opc = INDEX_op_setcond_i32;
356
- break;
357
+ goto do_setcond_low;
358
+ }
359
+ break;
360
+
361
+ case TCG_COND_TSTEQ:
362
+ case TCG_COND_TSTNE:
363
+ if (arg_is_const_val(op->args[2], 0)) {
364
+ goto do_setcond_high;
365
+ }
366
+ if (arg_is_const_val(op->args[4], 0)) {
367
+ goto do_setcond_low;
368
}
369
break;
370
371
default:
372
break;
373
374
+ do_setcond_low:
375
+ op->args[2] = op->args[3];
376
+ op->args[3] = cond;
377
+ op->opc = INDEX_op_setcond_i32;
378
+ return fold_setcond(ctx, op);
379
+
380
do_setcond_high:
381
op->args[1] = op->args[2];
382
op->args[2] = op->args[4];
383
op->args[3] = cond;
384
op->opc = INDEX_op_setcond_i32;
385
- break;
386
+ return fold_setcond(ctx, op);
387
}
388
389
ctx->z_mask = 1;
390
--
391
2.34.1
392
393
diff view generated by jsdifflib
Deleted patch
1
After having performed other simplifications, lower any
2
remaining test comparisons with AND.
3
1
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
tcg/tcg-internal.h | 2 ++
8
tcg/optimize.c | 60 +++++++++++++++++++++++++++++++++++++++-------
9
tcg/tcg.c | 2 +-
10
3 files changed, 55 insertions(+), 9 deletions(-)
11
12
diff --git a/tcg/tcg-internal.h b/tcg/tcg-internal.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/tcg/tcg-internal.h
15
+++ b/tcg/tcg-internal.h
16
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i64 TCGV128_HIGH(TCGv_i128 t)
17
18
bool tcg_target_has_memory_bswap(MemOp memop);
19
20
+TCGTemp *tcg_temp_new_internal(TCGType type, TCGTempKind kind);
21
+
22
/*
23
* Locate or create a read-only temporary that is a constant.
24
* This kind of temporary need not be freed, but for convenience
25
diff --git a/tcg/optimize.c b/tcg/optimize.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/tcg/optimize.c
28
+++ b/tcg/optimize.c
29
@@ -XXX,XX +XXX,XX @@ static TCGArg arg_new_constant(OptContext *ctx, uint64_t val)
30
return temp_arg(ts);
31
}
32
33
+static TCGArg arg_new_temp(OptContext *ctx)
34
+{
35
+ TCGTemp *ts = tcg_temp_new_internal(ctx->type, TEMP_EBB);
36
+ init_ts_info(ctx, ts);
37
+ return temp_arg(ts);
38
+}
39
+
40
static bool tcg_opt_gen_mov(OptContext *ctx, TCGOp *op, TCGArg dst, TCGArg src)
41
{
42
TCGTemp *dst_ts = arg_temp(dst);
43
@@ -XXX,XX +XXX,XX @@ static bool swap_commutative2(TCGArg *p1, TCGArg *p2)
44
* Return -1 if the condition can't be simplified,
45
* and the result of the condition (0 or 1) if it can.
46
*/
47
-static int do_constant_folding_cond1(OptContext *ctx, TCGArg dest,
48
+static int do_constant_folding_cond1(OptContext *ctx, TCGOp *op, TCGArg dest,
49
TCGArg *p1, TCGArg *p2, TCGArg *pcond)
50
{
51
TCGCond cond;
52
@@ -XXX,XX +XXX,XX @@ static int do_constant_folding_cond1(OptContext *ctx, TCGArg dest,
53
? INT32_MIN : INT64_MIN))) {
54
*p2 = arg_new_constant(ctx, 0);
55
*pcond = tcg_tst_ltge_cond(cond);
56
+ return -1;
57
+ }
58
+
59
+ /* Expand to AND with a temporary if no backend support. */
60
+ if (!TCG_TARGET_HAS_tst) {
61
+ TCGOpcode and_opc = (ctx->type == TCG_TYPE_I32
62
+ ? INDEX_op_and_i32 : INDEX_op_and_i64);
63
+ TCGOp *op2 = tcg_op_insert_before(ctx->tcg, op, and_opc, 3);
64
+ TCGArg tmp = arg_new_temp(ctx);
65
+
66
+ op2->args[0] = tmp;
67
+ op2->args[1] = *p1;
68
+ op2->args[2] = *p2;
69
+
70
+ *p1 = tmp;
71
+ *p2 = arg_new_constant(ctx, 0);
72
+ *pcond = tcg_tst_eqne_cond(cond);
73
}
74
return -1;
75
}
76
77
-static int do_constant_folding_cond2(OptContext *ctx, TCGArg *args)
78
+static int do_constant_folding_cond2(OptContext *ctx, TCGOp *op, TCGArg *args)
79
{
80
TCGArg al, ah, bl, bh;
81
TCGCond c;
82
@@ -XXX,XX +XXX,XX @@ static int do_constant_folding_cond2(OptContext *ctx, TCGArg *args)
83
return -1;
84
}
85
}
86
+
87
+ /* Expand to AND with a temporary if no backend support. */
88
+ if (!TCG_TARGET_HAS_tst && is_tst_cond(c)) {
89
+ TCGOp *op1 = tcg_op_insert_before(ctx->tcg, op, INDEX_op_and_i32, 3);
90
+ TCGOp *op2 = tcg_op_insert_before(ctx->tcg, op, INDEX_op_and_i32, 3);
91
+ TCGArg t1 = arg_new_temp(ctx);
92
+ TCGArg t2 = arg_new_temp(ctx);
93
+
94
+ op1->args[0] = t1;
95
+ op1->args[1] = al;
96
+ op1->args[2] = bl;
97
+ op2->args[0] = t2;
98
+ op2->args[1] = ah;
99
+ op2->args[2] = bh;
100
+
101
+ args[0] = t1;
102
+ args[1] = t2;
103
+ args[3] = args[2] = arg_new_constant(ctx, 0);
104
+ args[4] = tcg_tst_eqne_cond(c);
105
+ }
106
return -1;
107
}
108
109
@@ -XXX,XX +XXX,XX @@ static bool fold_andc(OptContext *ctx, TCGOp *op)
110
111
static bool fold_brcond(OptContext *ctx, TCGOp *op)
112
{
113
- int i = do_constant_folding_cond1(ctx, NO_DEST, &op->args[0],
114
+ int i = do_constant_folding_cond1(ctx, op, NO_DEST, &op->args[0],
115
&op->args[1], &op->args[2]);
116
if (i == 0) {
117
tcg_op_remove(ctx->tcg, op);
118
@@ -XXX,XX +XXX,XX @@ static bool fold_brcond2(OptContext *ctx, TCGOp *op)
119
TCGArg label;
120
int i, inv = 0;
121
122
- i = do_constant_folding_cond2(ctx, &op->args[0]);
123
+ i = do_constant_folding_cond2(ctx, op, &op->args[0]);
124
cond = op->args[4];
125
label = op->args[5];
126
if (i >= 0) {
127
@@ -XXX,XX +XXX,XX @@ static bool fold_movcond(OptContext *ctx, TCGOp *op)
128
op->args[5] = tcg_invert_cond(op->args[5]);
129
}
130
131
- i = do_constant_folding_cond1(ctx, NO_DEST, &op->args[1],
132
+ i = do_constant_folding_cond1(ctx, op, NO_DEST, &op->args[1],
133
&op->args[2], &op->args[5]);
134
if (i >= 0) {
135
return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[4 - i]);
136
@@ -XXX,XX +XXX,XX @@ static void fold_setcond_tst_pow2(OptContext *ctx, TCGOp *op, bool neg)
137
138
static bool fold_setcond(OptContext *ctx, TCGOp *op)
139
{
140
- int i = do_constant_folding_cond1(ctx, op->args[0], &op->args[1],
141
+ int i = do_constant_folding_cond1(ctx, op, op->args[0], &op->args[1],
142
&op->args[2], &op->args[3]);
143
if (i >= 0) {
144
return tcg_opt_gen_movi(ctx, op, op->args[0], i);
145
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond(OptContext *ctx, TCGOp *op)
146
147
static bool fold_negsetcond(OptContext *ctx, TCGOp *op)
148
{
149
- int i = do_constant_folding_cond1(ctx, op->args[0], &op->args[1],
150
+ int i = do_constant_folding_cond1(ctx, op, op->args[0], &op->args[1],
151
&op->args[2], &op->args[3]);
152
if (i >= 0) {
153
return tcg_opt_gen_movi(ctx, op, op->args[0], -i);
154
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond2(OptContext *ctx, TCGOp *op)
155
TCGCond cond;
156
int i, inv = 0;
157
158
- i = do_constant_folding_cond2(ctx, &op->args[1]);
159
+ i = do_constant_folding_cond2(ctx, op, &op->args[1]);
160
cond = op->args[5];
161
if (i >= 0) {
162
goto do_setcond_const;
163
diff --git a/tcg/tcg.c b/tcg/tcg.c
164
index XXXXXXX..XXXXXXX 100644
165
--- a/tcg/tcg.c
166
+++ b/tcg/tcg.c
167
@@ -XXX,XX +XXX,XX @@ TCGv_ptr tcg_global_mem_new_ptr(TCGv_ptr reg, intptr_t off, const char *name)
168
return temp_tcgv_ptr(ts);
169
}
170
171
-static TCGTemp *tcg_temp_new_internal(TCGType type, TCGTempKind kind)
172
+TCGTemp *tcg_temp_new_internal(TCGType type, TCGTempKind kind)
173
{
174
TCGContext *s = tcg_ctx;
175
TCGTemp *ts;
176
--
177
2.34.1
178
179
diff view generated by jsdifflib
Deleted patch
1
Simplify gen_bcond() by passing an immediate value.
2
1
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-Id: <20231028194522.245170-33-richard.henderson@linaro.org>
6
[PMD: Split from bigger patch, part 1/2]
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-Id: <20231108205247.83234-1-philmd@linaro.org>
9
---
10
target/alpha/translate.c | 21 +++++++--------------
11
1 file changed, 7 insertions(+), 14 deletions(-)
12
13
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/alpha/translate.c
16
+++ b/target/alpha/translate.c
17
@@ -XXX,XX +XXX,XX @@ static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
18
}
19
20
static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond,
21
- TCGv cmp, int32_t disp)
22
+ TCGv cmp, uint64_t imm, int32_t disp)
23
{
24
uint64_t dest = ctx->base.pc_next + (disp << 2);
25
TCGLabel *lab_true = gen_new_label();
26
27
if (use_goto_tb(ctx, dest)) {
28
- tcg_gen_brcondi_i64(cond, cmp, 0, lab_true);
29
+ tcg_gen_brcondi_i64(cond, cmp, imm, lab_true);
30
31
tcg_gen_goto_tb(0);
32
tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
33
@@ -XXX,XX +XXX,XX @@ static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond,
34
35
return DISAS_NORETURN;
36
} else {
37
- TCGv_i64 z = load_zero(ctx);
38
+ TCGv_i64 i = tcg_constant_i64(imm);
39
TCGv_i64 d = tcg_constant_i64(dest);
40
TCGv_i64 p = tcg_constant_i64(ctx->base.pc_next);
41
42
- tcg_gen_movcond_i64(cond, cpu_pc, cmp, z, d, p);
43
+ tcg_gen_movcond_i64(cond, cpu_pc, cmp, i, d, p);
44
return DISAS_PC_UPDATED;
45
}
46
}
47
@@ -XXX,XX +XXX,XX @@ static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond,
48
static DisasJumpType gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
49
int32_t disp, int mask)
50
{
51
- if (mask) {
52
- TCGv tmp = tcg_temp_new();
53
- DisasJumpType ret;
54
-
55
- tcg_gen_andi_i64(tmp, load_gpr(ctx, ra), 1);
56
- ret = gen_bcond_internal(ctx, cond, tmp, disp);
57
- return ret;
58
- }
59
- return gen_bcond_internal(ctx, cond, load_gpr(ctx, ra), disp);
60
+ return gen_bcond_internal(ctx, cond, load_gpr(ctx, ra),
61
+ mask, disp);
62
}
63
64
/* Fold -0.0 for comparison with COND. */
65
@@ -XXX,XX +XXX,XX @@ static DisasJumpType gen_fbcond(DisasContext *ctx, TCGCond cond, int ra,
66
DisasJumpType ret;
67
68
gen_fold_mzero(cond, cmp_tmp, load_fpr(ctx, ra));
69
- ret = gen_bcond_internal(ctx, cond, cmp_tmp, disp);
70
+ ret = gen_bcond_internal(ctx, cond, cmp_tmp, 0, disp);
71
return ret;
72
}
73
74
--
75
2.34.1
76
77
diff view generated by jsdifflib
Deleted patch
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Message-Id: <20231028194522.245170-33-richard.henderson@linaro.org>
4
[PMD: Split from bigger patch, part 2/2]
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-Id: <20231108205247.83234-2-philmd@linaro.org>
7
---
8
target/alpha/translate.c | 20 ++++++++++----------
9
1 file changed, 10 insertions(+), 10 deletions(-)
10
1
11
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/alpha/translate.c
14
+++ b/target/alpha/translate.c
15
@@ -XXX,XX +XXX,XX @@ static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond,
16
}
17
18
static DisasJumpType gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
19
- int32_t disp, int mask)
20
+ int32_t disp)
21
{
22
return gen_bcond_internal(ctx, cond, load_gpr(ctx, ra),
23
- mask, disp);
24
+ is_tst_cond(cond), disp);
25
}
26
27
/* Fold -0.0 for comparison with COND. */
28
@@ -XXX,XX +XXX,XX @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn)
29
break;
30
case 0x38:
31
/* BLBC */
32
- ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 1);
33
+ ret = gen_bcond(ctx, TCG_COND_TSTEQ, ra, disp21);
34
break;
35
case 0x39:
36
/* BEQ */
37
- ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 0);
38
+ ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21);
39
break;
40
case 0x3A:
41
/* BLT */
42
- ret = gen_bcond(ctx, TCG_COND_LT, ra, disp21, 0);
43
+ ret = gen_bcond(ctx, TCG_COND_LT, ra, disp21);
44
break;
45
case 0x3B:
46
/* BLE */
47
- ret = gen_bcond(ctx, TCG_COND_LE, ra, disp21, 0);
48
+ ret = gen_bcond(ctx, TCG_COND_LE, ra, disp21);
49
break;
50
case 0x3C:
51
/* BLBS */
52
- ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 1);
53
+ ret = gen_bcond(ctx, TCG_COND_TSTNE, ra, disp21);
54
break;
55
case 0x3D:
56
/* BNE */
57
- ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 0);
58
+ ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21);
59
break;
60
case 0x3E:
61
/* BGE */
62
- ret = gen_bcond(ctx, TCG_COND_GE, ra, disp21, 0);
63
+ ret = gen_bcond(ctx, TCG_COND_GE, ra, disp21);
64
break;
65
case 0x3F:
66
/* BGT */
67
- ret = gen_bcond(ctx, TCG_COND_GT, ra, disp21, 0);
68
+ ret = gen_bcond(ctx, TCG_COND_GT, ra, disp21);
69
break;
70
invalid_opc:
71
ret = gen_invalid(ctx);
72
--
73
2.34.1
74
75
diff view generated by jsdifflib
Deleted patch
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
target/alpha/translate.c | 8 ++------
5
1 file changed, 2 insertions(+), 6 deletions(-)
6
1
7
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/target/alpha/translate.c
10
+++ b/target/alpha/translate.c
11
@@ -XXX,XX +XXX,XX @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn)
12
break;
13
case 0x14:
14
/* CMOVLBS */
15
- tmp = tcg_temp_new();
16
- tcg_gen_andi_i64(tmp, va, 1);
17
- tcg_gen_movcond_i64(TCG_COND_NE, vc, tmp, load_zero(ctx),
18
+ tcg_gen_movcond_i64(TCG_COND_TSTNE, vc, va, tcg_constant_i64(1),
19
vb, load_gpr(ctx, rc));
20
break;
21
case 0x16:
22
/* CMOVLBC */
23
- tmp = tcg_temp_new();
24
- tcg_gen_andi_i64(tmp, va, 1);
25
- tcg_gen_movcond_i64(TCG_COND_EQ, vc, tmp, load_zero(ctx),
26
+ tcg_gen_movcond_i64(TCG_COND_TSTEQ, vc, va, tcg_constant_i64(1),
27
vb, load_gpr(ctx, rc));
28
break;
29
case 0x20:
30
--
31
2.34.1
32
33
diff view generated by jsdifflib
Deleted patch
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
target/alpha/translate.c | 49 +++++++++++++++++++---------------------
5
1 file changed, 23 insertions(+), 26 deletions(-)
6
1
7
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/target/alpha/translate.c
10
+++ b/target/alpha/translate.c
11
@@ -XXX,XX +XXX,XX @@ static DisasJumpType gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
12
13
/* Fold -0.0 for comparison with COND. */
14
15
-static void gen_fold_mzero(TCGCond cond, TCGv dest, TCGv src)
16
+static TCGv_i64 gen_fold_mzero(TCGCond *pcond, uint64_t *pimm, TCGv_i64 src)
17
{
18
- uint64_t mzero = 1ull << 63;
19
+ TCGv_i64 tmp;
20
21
- switch (cond) {
22
+ *pimm = 0;
23
+ switch (*pcond) {
24
case TCG_COND_LE:
25
case TCG_COND_GT:
26
/* For <= or >, the -0.0 value directly compares the way we want. */
27
- tcg_gen_mov_i64(dest, src);
28
- break;
29
+ return src;
30
31
case TCG_COND_EQ:
32
case TCG_COND_NE:
33
- /* For == or !=, we can simply mask off the sign bit and compare. */
34
- tcg_gen_andi_i64(dest, src, mzero - 1);
35
- break;
36
+ /* For == or !=, we can compare without the sign bit. */
37
+ *pcond = *pcond == TCG_COND_EQ ? TCG_COND_TSTEQ : TCG_COND_TSTNE;
38
+ *pimm = INT64_MAX;
39
+ return src;
40
41
case TCG_COND_GE:
42
case TCG_COND_LT:
43
/* For >= or <, map -0.0 to +0.0. */
44
- tcg_gen_movcond_i64(TCG_COND_NE, dest, src, tcg_constant_i64(mzero),
45
- src, tcg_constant_i64(0));
46
- break;
47
+ tmp = tcg_temp_new_i64();
48
+ tcg_gen_movcond_i64(TCG_COND_EQ, tmp,
49
+ src, tcg_constant_i64(INT64_MIN),
50
+ tcg_constant_i64(0), src);
51
+ return tmp;
52
53
default:
54
- abort();
55
+ g_assert_not_reached();
56
}
57
}
58
59
static DisasJumpType gen_fbcond(DisasContext *ctx, TCGCond cond, int ra,
60
int32_t disp)
61
{
62
- TCGv cmp_tmp = tcg_temp_new();
63
- DisasJumpType ret;
64
-
65
- gen_fold_mzero(cond, cmp_tmp, load_fpr(ctx, ra));
66
- ret = gen_bcond_internal(ctx, cond, cmp_tmp, 0, disp);
67
- return ret;
68
+ uint64_t imm;
69
+ TCGv_i64 tmp = gen_fold_mzero(&cond, &imm, load_fpr(ctx, ra));
70
+ return gen_bcond_internal(ctx, cond, tmp, imm, disp);
71
}
72
73
static void gen_fcmov(DisasContext *ctx, TCGCond cond, int ra, int rb, int rc)
74
{
75
- TCGv_i64 va, vb, z;
76
-
77
- z = load_zero(ctx);
78
- vb = load_fpr(ctx, rb);
79
- va = tcg_temp_new();
80
- gen_fold_mzero(cond, va, load_fpr(ctx, ra));
81
-
82
- tcg_gen_movcond_i64(cond, dest_fpr(ctx, rc), va, z, vb, load_fpr(ctx, rc));
83
+ uint64_t imm;
84
+ TCGv_i64 tmp = gen_fold_mzero(&cond, &imm, load_fpr(ctx, ra));
85
+ tcg_gen_movcond_i64(cond, dest_fpr(ctx, rc),
86
+ tmp, tcg_constant_i64(imm),
87
+ load_fpr(ctx, rb), load_fpr(ctx, rc));
88
}
89
90
#define QUAL_RM_N 0x080 /* Round mode nearest even */
91
--
92
2.34.1
93
94
diff view generated by jsdifflib
Deleted patch
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
target/m68k/translate.c | 74 ++++++++++++++++++-----------------------
5
1 file changed, 33 insertions(+), 41 deletions(-)
6
1
7
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/target/m68k/translate.c
10
+++ b/target/m68k/translate.c
11
@@ -XXX,XX +XXX,XX @@ undef:
12
static void gen_fcc_cond(DisasCompare *c, DisasContext *s, int cond)
13
{
14
TCGv fpsr;
15
+ int imm = 0;
16
17
- c->v2 = tcg_constant_i32(0);
18
/* TODO: Raise BSUN exception. */
19
fpsr = tcg_temp_new();
20
gen_load_fcr(s, fpsr, M68K_FPSR);
21
+ c->v1 = fpsr;
22
+
23
switch (cond) {
24
case 0: /* False */
25
case 16: /* Signaling False */
26
- c->v1 = c->v2;
27
c->tcond = TCG_COND_NEVER;
28
break;
29
case 1: /* EQual Z */
30
case 17: /* Signaling EQual Z */
31
- c->v1 = tcg_temp_new();
32
- tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
33
- c->tcond = TCG_COND_NE;
34
+ imm = FPSR_CC_Z;
35
+ c->tcond = TCG_COND_TSTNE;
36
break;
37
case 2: /* Ordered Greater Than !(A || Z || N) */
38
case 18: /* Greater Than !(A || Z || N) */
39
- c->v1 = tcg_temp_new();
40
- tcg_gen_andi_i32(c->v1, fpsr,
41
- FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
42
- c->tcond = TCG_COND_EQ;
43
+ imm = FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N;
44
+ c->tcond = TCG_COND_TSTEQ;
45
break;
46
case 3: /* Ordered Greater than or Equal Z || !(A || N) */
47
case 19: /* Greater than or Equal Z || !(A || N) */
48
c->v1 = tcg_temp_new();
49
tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
50
tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_A));
51
- tcg_gen_andi_i32(fpsr, fpsr, FPSR_CC_Z | FPSR_CC_N);
52
tcg_gen_or_i32(c->v1, c->v1, fpsr);
53
tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N);
54
- c->tcond = TCG_COND_NE;
55
+ imm = FPSR_CC_Z | FPSR_CC_N;
56
+ c->tcond = TCG_COND_TSTNE;
57
break;
58
case 4: /* Ordered Less Than !(!N || A || Z); */
59
case 20: /* Less Than !(!N || A || Z); */
60
c->v1 = tcg_temp_new();
61
tcg_gen_xori_i32(c->v1, fpsr, FPSR_CC_N);
62
- tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_N | FPSR_CC_A | FPSR_CC_Z);
63
- c->tcond = TCG_COND_EQ;
64
+ imm = FPSR_CC_N | FPSR_CC_A | FPSR_CC_Z;
65
+ c->tcond = TCG_COND_TSTEQ;
66
break;
67
case 5: /* Ordered Less than or Equal Z || (N && !A) */
68
case 21: /* Less than or Equal Z || (N && !A) */
69
@@ -XXX,XX +XXX,XX @@ static void gen_fcc_cond(DisasCompare *c, DisasContext *s, int cond)
70
tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
71
tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_A));
72
tcg_gen_andc_i32(c->v1, fpsr, c->v1);
73
- tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_Z | FPSR_CC_N);
74
- c->tcond = TCG_COND_NE;
75
+ imm = FPSR_CC_Z | FPSR_CC_N;
76
+ c->tcond = TCG_COND_TSTNE;
77
break;
78
case 6: /* Ordered Greater or Less than !(A || Z) */
79
case 22: /* Greater or Less than !(A || Z) */
80
- c->v1 = tcg_temp_new();
81
- tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z);
82
- c->tcond = TCG_COND_EQ;
83
+ imm = FPSR_CC_A | FPSR_CC_Z;
84
+ c->tcond = TCG_COND_TSTEQ;
85
break;
86
case 7: /* Ordered !A */
87
case 23: /* Greater, Less or Equal !A */
88
- c->v1 = tcg_temp_new();
89
- tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
90
- c->tcond = TCG_COND_EQ;
91
+ imm = FPSR_CC_A;
92
+ c->tcond = TCG_COND_TSTEQ;
93
break;
94
case 8: /* Unordered A */
95
case 24: /* Not Greater, Less or Equal A */
96
- c->v1 = tcg_temp_new();
97
- tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
98
- c->tcond = TCG_COND_NE;
99
+ imm = FPSR_CC_A;
100
+ c->tcond = TCG_COND_TSTNE;
101
break;
102
case 9: /* Unordered or Equal A || Z */
103
case 25: /* Not Greater or Less then A || Z */
104
- c->v1 = tcg_temp_new();
105
- tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z);
106
- c->tcond = TCG_COND_NE;
107
+ imm = FPSR_CC_A | FPSR_CC_Z;
108
+ c->tcond = TCG_COND_TSTNE;
109
break;
110
case 10: /* Unordered or Greater Than A || !(N || Z)) */
111
case 26: /* Not Less or Equal A || !(N || Z)) */
112
c->v1 = tcg_temp_new();
113
tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
114
tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_Z));
115
- tcg_gen_andi_i32(fpsr, fpsr, FPSR_CC_A | FPSR_CC_N);
116
tcg_gen_or_i32(c->v1, c->v1, fpsr);
117
tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N);
118
- c->tcond = TCG_COND_NE;
119
+ imm = FPSR_CC_A | FPSR_CC_N;
120
+ c->tcond = TCG_COND_TSTNE;
121
break;
122
case 11: /* Unordered or Greater or Equal A || Z || !N */
123
case 27: /* Not Less Than A || Z || !N */
124
c->v1 = tcg_temp_new();
125
- tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
126
- tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N);
127
- c->tcond = TCG_COND_NE;
128
+ tcg_gen_xori_i32(c->v1, fpsr, FPSR_CC_N);
129
+ imm = FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N;
130
+ c->tcond = TCG_COND_TSTNE;
131
break;
132
case 12: /* Unordered or Less Than A || (N && !Z) */
133
case 28: /* Not Greater than or Equal A || (N && !Z) */
134
@@ -XXX,XX +XXX,XX @@ static void gen_fcc_cond(DisasCompare *c, DisasContext *s, int cond)
135
tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
136
tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_Z));
137
tcg_gen_andc_i32(c->v1, fpsr, c->v1);
138
- tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_A | FPSR_CC_N);
139
- c->tcond = TCG_COND_NE;
140
+ imm = FPSR_CC_A | FPSR_CC_N;
141
+ c->tcond = TCG_COND_TSTNE;
142
break;
143
case 13: /* Unordered or Less or Equal A || Z || N */
144
case 29: /* Not Greater Than A || Z || N */
145
- c->v1 = tcg_temp_new();
146
- tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
147
- c->tcond = TCG_COND_NE;
148
+ imm = FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N;
149
+ c->tcond = TCG_COND_TSTNE;
150
break;
151
case 14: /* Not Equal !Z */
152
case 30: /* Signaling Not Equal !Z */
153
- c->v1 = tcg_temp_new();
154
- tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
155
- c->tcond = TCG_COND_EQ;
156
+ imm = FPSR_CC_Z;
157
+ c->tcond = TCG_COND_TSTEQ;
158
break;
159
case 15: /* True */
160
case 31: /* Signaling True */
161
- c->v1 = c->v2;
162
c->tcond = TCG_COND_ALWAYS;
163
break;
164
}
165
+ c->v2 = tcg_constant_i32(imm);
166
}
167
168
static void gen_fjmpcc(DisasContext *s, int cond, TCGLabel *l1)
169
--
170
2.34.1
171
172
diff view generated by jsdifflib
Deleted patch
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
target/sparc/translate.c | 4 ++--
5
1 file changed, 2 insertions(+), 2 deletions(-)
6
1
7
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/target/sparc/translate.c
10
+++ b/target/sparc/translate.c
11
@@ -XXX,XX +XXX,XX @@ static void gen_op_subccc(TCGv dst, TCGv src1, TCGv src2)
12
static void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
13
{
14
TCGv zero = tcg_constant_tl(0);
15
+ TCGv one = tcg_constant_tl(1);
16
TCGv t_src1 = tcg_temp_new();
17
TCGv t_src2 = tcg_temp_new();
18
TCGv t0 = tcg_temp_new();
19
@@ -XXX,XX +XXX,XX @@ static void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
20
* if (!(env->y & 1))
21
* src2 = 0;
22
*/
23
- tcg_gen_andi_tl(t0, cpu_y, 0x1);
24
- tcg_gen_movcond_tl(TCG_COND_EQ, t_src2, t0, zero, zero, t_src2);
25
+ tcg_gen_movcond_tl(TCG_COND_TSTEQ, t_src2, cpu_y, one, zero, t_src2);
26
27
/*
28
* b2 = src1 & 1;
29
--
30
2.34.1
31
32
diff view generated by jsdifflib
Deleted patch
1
These are all test-and-compare type instructions.
2
1
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
target/s390x/tcg/translate.c | 18 +++++++-----------
7
1 file changed, 7 insertions(+), 11 deletions(-)
8
9
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/target/s390x/tcg/translate.c
12
+++ b/target/s390x/tcg/translate.c
13
@@ -XXX,XX +XXX,XX @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
14
case CC_OP_TM_64:
15
switch (mask) {
16
case 8:
17
- cond = TCG_COND_EQ;
18
+ cond = TCG_COND_TSTEQ;
19
break;
20
case 4 | 2 | 1:
21
- cond = TCG_COND_NE;
22
+ cond = TCG_COND_TSTNE;
23
break;
24
default:
25
goto do_dynamic;
26
@@ -XXX,XX +XXX,XX @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
27
case CC_OP_ICM:
28
switch (mask) {
29
case 8:
30
- cond = TCG_COND_EQ;
31
+ cond = TCG_COND_TSTEQ;
32
break;
33
case 4 | 2 | 1:
34
case 4 | 2:
35
- cond = TCG_COND_NE;
36
+ cond = TCG_COND_TSTNE;
37
break;
38
default:
39
goto do_dynamic;
40
@@ -XXX,XX +XXX,XX @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
41
c->u.s64.a = cc_dst;
42
c->u.s64.b = tcg_constant_i64(0);
43
break;
44
+
45
case CC_OP_LTGT_64:
46
case CC_OP_LTUGTU_64:
47
- c->u.s64.a = cc_src;
48
- c->u.s64.b = cc_dst;
49
- break;
50
-
51
case CC_OP_TM_32:
52
case CC_OP_TM_64:
53
case CC_OP_ICM:
54
- c->u.s64.a = tcg_temp_new_i64();
55
- c->u.s64.b = tcg_constant_i64(0);
56
- tcg_gen_and_i64(c->u.s64.a, cc_src, cc_dst);
57
+ c->u.s64.a = cc_src;
58
+ c->u.s64.b = cc_dst;
59
break;
60
61
case CC_OP_ADDU:
62
--
63
2.34.1
64
65
diff view generated by jsdifflib
Deleted patch
1
Avoid code duplication by handling 7 of the 14 cases
2
by inverting the test for the other 7 cases.
3
1
4
Use TCG_COND_TSTNE for cc in {1,3}.
5
Use (cc - 1) <= 1 for cc in {1,2}.
6
7
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
11
target/s390x/tcg/translate.c | 82 +++++++++++++-----------------------
12
1 file changed, 30 insertions(+), 52 deletions(-)
13
14
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/s390x/tcg/translate.c
17
+++ b/target/s390x/tcg/translate.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
19
case CC_OP_STATIC:
20
c->is_64 = false;
21
c->u.s32.a = cc_op;
22
- switch (mask) {
23
- case 0x8 | 0x4 | 0x2: /* cc != 3 */
24
- cond = TCG_COND_NE;
25
+
26
+ /* Fold half of the cases using bit 3 to invert. */
27
+ switch (mask & 8 ? mask ^ 0xf : mask) {
28
+ case 0x1: /* cc == 3 */
29
+ cond = TCG_COND_EQ;
30
c->u.s32.b = tcg_constant_i32(3);
31
break;
32
- case 0x8 | 0x4 | 0x1: /* cc != 2 */
33
- cond = TCG_COND_NE;
34
- c->u.s32.b = tcg_constant_i32(2);
35
- break;
36
- case 0x8 | 0x2 | 0x1: /* cc != 1 */
37
- cond = TCG_COND_NE;
38
- c->u.s32.b = tcg_constant_i32(1);
39
- break;
40
- case 0x8 | 0x2: /* cc == 0 || cc == 2 => (cc & 1) == 0 */
41
- cond = TCG_COND_EQ;
42
- c->u.s32.a = tcg_temp_new_i32();
43
- c->u.s32.b = tcg_constant_i32(0);
44
- tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
45
- break;
46
- case 0x8 | 0x4: /* cc < 2 */
47
- cond = TCG_COND_LTU;
48
- c->u.s32.b = tcg_constant_i32(2);
49
- break;
50
- case 0x8: /* cc == 0 */
51
- cond = TCG_COND_EQ;
52
- c->u.s32.b = tcg_constant_i32(0);
53
- break;
54
- case 0x4 | 0x2 | 0x1: /* cc != 0 */
55
- cond = TCG_COND_NE;
56
- c->u.s32.b = tcg_constant_i32(0);
57
- break;
58
- case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */
59
- cond = TCG_COND_NE;
60
- c->u.s32.a = tcg_temp_new_i32();
61
- c->u.s32.b = tcg_constant_i32(0);
62
- tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
63
- break;
64
- case 0x4: /* cc == 1 */
65
- cond = TCG_COND_EQ;
66
- c->u.s32.b = tcg_constant_i32(1);
67
- break;
68
- case 0x2 | 0x1: /* cc > 1 */
69
- cond = TCG_COND_GTU;
70
- c->u.s32.b = tcg_constant_i32(1);
71
- break;
72
case 0x2: /* cc == 2 */
73
cond = TCG_COND_EQ;
74
c->u.s32.b = tcg_constant_i32(2);
75
break;
76
- case 0x1: /* cc == 3 */
77
+ case 0x4: /* cc == 1 */
78
cond = TCG_COND_EQ;
79
- c->u.s32.b = tcg_constant_i32(3);
80
+ c->u.s32.b = tcg_constant_i32(1);
81
+ break;
82
+ case 0x2 | 0x1: /* cc == 2 || cc == 3 => cc > 1 */
83
+ cond = TCG_COND_GTU;
84
+ c->u.s32.b = tcg_constant_i32(1);
85
+ break;
86
+ case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */
87
+ cond = TCG_COND_TSTNE;
88
+ c->u.s32.b = tcg_constant_i32(1);
89
+ break;
90
+ case 0x4 | 0x2: /* cc == 1 || cc == 2 => (cc - 1) <= 1 */
91
+ cond = TCG_COND_LEU;
92
+ c->u.s32.a = tcg_temp_new_i32();
93
+ c->u.s32.b = tcg_constant_i32(1);
94
+ tcg_gen_addi_i32(c->u.s32.a, cc_op, -1);
95
+ break;
96
+ case 0x4 | 0x2 | 0x1: /* cc != 0 */
97
+ cond = TCG_COND_NE;
98
+ c->u.s32.b = tcg_constant_i32(0);
99
break;
100
default:
101
- /* CC is masked by something else: (8 >> cc) & mask. */
102
- cond = TCG_COND_NE;
103
- c->u.s32.a = tcg_temp_new_i32();
104
- c->u.s32.b = tcg_constant_i32(0);
105
- tcg_gen_shr_i32(c->u.s32.a, tcg_constant_i32(8), cc_op);
106
- tcg_gen_andi_i32(c->u.s32.a, c->u.s32.a, mask);
107
- break;
108
+ /* case 0: never, handled above. */
109
+ g_assert_not_reached();
110
+ }
111
+ if (mask & 8) {
112
+ cond = tcg_invert_cond(cond);
113
}
114
break;
115
116
--
117
2.34.1
118
119
diff view generated by jsdifflib
1
Fill the new argument from any condition within the opcode.
1
From: Roman Artemev <roman.artemev@syntacore.com>
2
Not yet used within any backend.
3
2
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
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>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
13
---
7
tcg/tcg.c | 34 ++++++++++++++++++++++++++++++--
14
tcg/riscv/tcg-target.c.inc | 2 +-
8
tcg/aarch64/tcg-target.c.inc | 3 ++-
15
1 file changed, 1 insertion(+), 1 deletion(-)
9
tcg/arm/tcg-target.c.inc | 3 ++-
10
tcg/i386/tcg-target.c.inc | 3 ++-
11
tcg/loongarch64/tcg-target.c.inc | 3 ++-
12
tcg/mips/tcg-target.c.inc | 3 ++-
13
tcg/ppc/tcg-target.c.inc | 3 ++-
14
tcg/riscv/tcg-target.c.inc | 3 ++-
15
tcg/s390x/tcg-target.c.inc | 3 ++-
16
tcg/sparc64/tcg-target.c.inc | 3 ++-
17
tcg/tci/tcg-target.c.inc | 3 ++-
18
11 files changed, 52 insertions(+), 12 deletions(-)
19
16
20
diff --git a/tcg/tcg.c b/tcg/tcg.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/tcg/tcg.c
23
+++ b/tcg/tcg.c
24
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
25
static void tcg_out_call(TCGContext *s, const tcg_insn_unit *target,
26
const TCGHelperInfo *info);
27
static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot);
28
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece);
29
+static bool tcg_target_const_match(int64_t val, int ct,
30
+ TCGType type, TCGCond cond, int vece);
31
#ifdef TCG_TARGET_NEED_LDST_LABELS
32
static int tcg_out_ldst_finalize(TCGContext *s);
33
#endif
34
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
35
TCGTemp *ts;
36
TCGArg new_args[TCG_MAX_OP_ARGS];
37
int const_args[TCG_MAX_OP_ARGS];
38
+ TCGCond op_cond;
39
40
nb_oargs = def->nb_oargs;
41
nb_iargs = def->nb_iargs;
42
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
43
i_allocated_regs = s->reserved_regs;
44
o_allocated_regs = s->reserved_regs;
45
46
+ switch (op->opc) {
47
+ case INDEX_op_brcond_i32:
48
+ case INDEX_op_brcond_i64:
49
+ op_cond = op->args[2];
50
+ break;
51
+ case INDEX_op_setcond_i32:
52
+ case INDEX_op_setcond_i64:
53
+ case INDEX_op_negsetcond_i32:
54
+ case INDEX_op_negsetcond_i64:
55
+ case INDEX_op_cmp_vec:
56
+ op_cond = op->args[3];
57
+ break;
58
+ case INDEX_op_brcond2_i32:
59
+ op_cond = op->args[4];
60
+ break;
61
+ case INDEX_op_movcond_i32:
62
+ case INDEX_op_movcond_i64:
63
+ case INDEX_op_setcond2_i32:
64
+ case INDEX_op_cmpsel_vec:
65
+ op_cond = op->args[5];
66
+ break;
67
+ default:
68
+ /* No condition within opcode. */
69
+ op_cond = TCG_COND_ALWAYS;
70
+ break;
71
+ }
72
+
73
/* satisfy input constraints */
74
for (k = 0; k < nb_iargs; k++) {
75
TCGRegSet i_preferred_regs, i_required_regs;
76
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
77
ts = arg_temp(arg);
78
79
if (ts->val_type == TEMP_VAL_CONST
80
- && tcg_target_const_match(ts->val, ts->type, arg_ct->ct, TCGOP_VECE(op))) {
81
+ && tcg_target_const_match(ts->val, arg_ct->ct, ts->type,
82
+ op_cond, TCGOP_VECE(op))) {
83
/* constant is OK for instruction */
84
const_args[i] = 1;
85
new_args[i] = ts->val;
86
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
87
index XXXXXXX..XXXXXXX 100644
88
--- a/tcg/aarch64/tcg-target.c.inc
89
+++ b/tcg/aarch64/tcg-target.c.inc
90
@@ -XXX,XX +XXX,XX @@ static bool is_shimm1632(uint32_t v32, int *cmode, int *imm8)
91
}
92
}
93
94
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
95
+static bool tcg_target_const_match(int64_t val, int ct,
96
+ TCGType type, TCGCond cond, int vece)
97
{
98
if (ct & TCG_CT_CONST) {
99
return 1;
100
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
101
index XXXXXXX..XXXXXXX 100644
102
--- a/tcg/arm/tcg-target.c.inc
103
+++ b/tcg/arm/tcg-target.c.inc
104
@@ -XXX,XX +XXX,XX @@ static bool is_shimm1632(uint32_t v32, int *cmode, int *imm8)
105
* mov operand2: values represented with x << (2 * y), x < 0x100
106
* add, sub, eor...: ditto
107
*/
108
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
109
+static bool tcg_target_const_match(int64_t val, int ct,
110
+ TCGType type, TCGCond cond, int vece)
111
{
112
if (ct & TCG_CT_CONST) {
113
return 1;
114
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
115
index XXXXXXX..XXXXXXX 100644
116
--- a/tcg/i386/tcg-target.c.inc
117
+++ b/tcg/i386/tcg-target.c.inc
118
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
119
}
120
121
/* test if a constant matches the constraint */
122
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
123
+static bool tcg_target_const_match(int64_t val, int ct,
124
+ TCGType type, TCGCond cond, int vece)
125
{
126
if (ct & TCG_CT_CONST) {
127
return 1;
128
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
129
index XXXXXXX..XXXXXXX 100644
130
--- a/tcg/loongarch64/tcg-target.c.inc
131
+++ b/tcg/loongarch64/tcg-target.c.inc
132
@@ -XXX,XX +XXX,XX @@ static inline tcg_target_long sextreg(tcg_target_long val, int pos, int len)
133
}
134
135
/* test if a constant matches the constraint */
136
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
137
+static bool tcg_target_const_match(int64_t val, int ct,
138
+ TCGType type, TCGCond cond, int vece)
139
{
140
if (ct & TCG_CT_CONST) {
141
return true;
142
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
143
index XXXXXXX..XXXXXXX 100644
144
--- a/tcg/mips/tcg-target.c.inc
145
+++ b/tcg/mips/tcg-target.c.inc
146
@@ -XXX,XX +XXX,XX @@ static bool is_p2m1(tcg_target_long val)
147
}
148
149
/* test if a constant matches the constraint */
150
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
151
+static bool tcg_target_const_match(int64_t val, int ct,
152
+ TCGType type, TCGCond cond, int vece)
153
{
154
if (ct & TCG_CT_CONST) {
155
return 1;
156
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
157
index XXXXXXX..XXXXXXX 100644
158
--- a/tcg/ppc/tcg-target.c.inc
159
+++ b/tcg/ppc/tcg-target.c.inc
160
@@ -XXX,XX +XXX,XX @@ static bool reloc_pc34(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
161
}
162
163
/* test if a constant matches the constraint */
164
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
165
+static bool tcg_target_const_match(int64_t val, int ct,
166
+ TCGType type, TCGCond cond, int vece)
167
{
168
if (ct & TCG_CT_CONST) {
169
return 1;
170
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
17
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
171
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
172
--- a/tcg/riscv/tcg-target.c.inc
19
--- a/tcg/riscv/tcg-target.c.inc
173
+++ b/tcg/riscv/tcg-target.c.inc
20
+++ b/tcg/riscv/tcg-target.c.inc
174
@@ -XXX,XX +XXX,XX @@ static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
21
@@ -XXX,XX +XXX,XX @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
175
#define sextreg sextract64
22
insn |= 0x02100000;
176
23
}
177
/* test if a constant matches the constraint */
24
if (a0 & TCG_MO_ST_ST) {
178
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
25
- insn |= 0x02200000;
179
+static bool tcg_target_const_match(int64_t val, int ct,
26
+ insn |= 0x01100000;
180
+ TCGType type, TCGCond cond, int vece)
27
}
181
{
28
tcg_out32(s, insn);
182
if (ct & TCG_CT_CONST) {
183
return 1;
184
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
185
index XXXXXXX..XXXXXXX 100644
186
--- a/tcg/s390x/tcg-target.c.inc
187
+++ b/tcg/s390x/tcg-target.c.inc
188
@@ -XXX,XX +XXX,XX @@ static bool risbg_mask(uint64_t c)
189
}
190
191
/* Test if a constant matches the constraint. */
192
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
193
+static bool tcg_target_const_match(int64_t val, int ct,
194
+ TCGType type, TCGCond cond, int vece)
195
{
196
if (ct & TCG_CT_CONST) {
197
return 1;
198
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
199
index XXXXXXX..XXXXXXX 100644
200
--- a/tcg/sparc64/tcg-target.c.inc
201
+++ b/tcg/sparc64/tcg-target.c.inc
202
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *src_rw, int type,
203
}
204
205
/* test if a constant matches the constraint */
206
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
207
+static bool tcg_target_const_match(int64_t val, int ct,
208
+ TCGType type, TCGCond cond, int vece)
209
{
210
if (ct & TCG_CT_CONST) {
211
return 1;
212
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
213
index XXXXXXX..XXXXXXX 100644
214
--- a/tcg/tci/tcg-target.c.inc
215
+++ b/tcg/tci/tcg-target.c.inc
216
@@ -XXX,XX +XXX,XX @@ static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
217
}
218
219
/* Test if a constant matches the constraint. */
220
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
221
+static bool tcg_target_const_match(int64_t val, int ct,
222
+ TCGType type, TCGCond cond, int vece)
223
{
224
return ct & TCG_CT_CONST;
225
}
29
}
226
--
30
--
227
2.34.1
31
2.43.0
228
229
diff view generated by jsdifflib
Deleted patch
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
tcg/aarch64/tcg-target-con-set.h | 5 +--
5
tcg/aarch64/tcg-target-con-str.h | 1 +
6
tcg/aarch64/tcg-target.h | 2 +-
7
tcg/aarch64/tcg-target.c.inc | 56 ++++++++++++++++++++++----------
8
4 files changed, 44 insertions(+), 20 deletions(-)
9
1
10
diff --git a/tcg/aarch64/tcg-target-con-set.h b/tcg/aarch64/tcg-target-con-set.h
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/aarch64/tcg-target-con-set.h
13
+++ b/tcg/aarch64/tcg-target-con-set.h
14
@@ -XXX,XX +XXX,XX @@
15
* tcg-target-con-str.h; the constraint combination is inclusive or.
16
*/
17
C_O0_I1(r)
18
-C_O0_I2(r, rA)
19
+C_O0_I2(r, rC)
20
C_O0_I2(rZ, r)
21
C_O0_I2(w, r)
22
C_O0_I3(rZ, rZ, r)
23
@@ -XXX,XX +XXX,XX @@ C_O1_I2(r, 0, rZ)
24
C_O1_I2(r, r, r)
25
C_O1_I2(r, r, rA)
26
C_O1_I2(r, r, rAL)
27
+C_O1_I2(r, r, rC)
28
C_O1_I2(r, r, ri)
29
C_O1_I2(r, r, rL)
30
C_O1_I2(r, rZ, rZ)
31
@@ -XXX,XX +XXX,XX @@ C_O1_I2(w, w, wN)
32
C_O1_I2(w, w, wO)
33
C_O1_I2(w, w, wZ)
34
C_O1_I3(w, w, w, w)
35
-C_O1_I4(r, r, rA, rZ, rZ)
36
+C_O1_I4(r, r, rC, rZ, rZ)
37
C_O2_I1(r, r, r)
38
C_O2_I4(r, r, rZ, rZ, rA, rMZ)
39
diff --git a/tcg/aarch64/tcg-target-con-str.h b/tcg/aarch64/tcg-target-con-str.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/tcg/aarch64/tcg-target-con-str.h
42
+++ b/tcg/aarch64/tcg-target-con-str.h
43
@@ -XXX,XX +XXX,XX @@ REGS('w', ALL_VECTOR_REGS)
44
* CONST(letter, TCG_CT_CONST_* bit set)
45
*/
46
CONST('A', TCG_CT_CONST_AIMM)
47
+CONST('C', TCG_CT_CONST_CMP)
48
CONST('L', TCG_CT_CONST_LIMM)
49
CONST('M', TCG_CT_CONST_MONE)
50
CONST('O', TCG_CT_CONST_ORRI)
51
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
52
index XXXXXXX..XXXXXXX 100644
53
--- a/tcg/aarch64/tcg-target.h
54
+++ b/tcg/aarch64/tcg-target.h
55
@@ -XXX,XX +XXX,XX @@ typedef enum {
56
#define TCG_TARGET_HAS_qemu_ldst_i128 1
57
#endif
58
59
-#define TCG_TARGET_HAS_tst 0
60
+#define TCG_TARGET_HAS_tst 1
61
62
#define TCG_TARGET_HAS_v64 1
63
#define TCG_TARGET_HAS_v128 1
64
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
65
index XXXXXXX..XXXXXXX 100644
66
--- a/tcg/aarch64/tcg-target.c.inc
67
+++ b/tcg/aarch64/tcg-target.c.inc
68
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
69
#define TCG_CT_CONST_MONE 0x800
70
#define TCG_CT_CONST_ORRI 0x1000
71
#define TCG_CT_CONST_ANDI 0x2000
72
+#define TCG_CT_CONST_CMP 0x4000
73
74
#define ALL_GENERAL_REGS 0xffffffffu
75
#define ALL_VECTOR_REGS 0xffffffff00000000ull
76
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, int ct,
77
if (type == TCG_TYPE_I32) {
78
val = (int32_t)val;
79
}
80
+
81
+ if (ct & TCG_CT_CONST_CMP) {
82
+ if (is_tst_cond(cond)) {
83
+ ct |= TCG_CT_CONST_LIMM;
84
+ } else {
85
+ ct |= TCG_CT_CONST_AIMM;
86
+ }
87
+ }
88
+
89
if ((ct & TCG_CT_CONST_AIMM) && (is_aimm(val) || is_aimm(-val))) {
90
return 1;
91
}
92
@@ -XXX,XX +XXX,XX @@ static const enum aarch64_cond_code tcg_cond_to_aarch64[] = {
93
[TCG_COND_GTU] = COND_HI,
94
[TCG_COND_GEU] = COND_HS,
95
[TCG_COND_LEU] = COND_LS,
96
+ /* bit test */
97
+ [TCG_COND_TSTEQ] = COND_EQ,
98
+ [TCG_COND_TSTNE] = COND_NE,
99
};
100
101
typedef enum {
102
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_dep(TCGContext *s, TCGType ext, TCGReg rd,
103
tcg_out_bfm(s, ext, rd, rn, a, b);
104
}
105
106
-static void tcg_out_cmp(TCGContext *s, TCGType ext, TCGReg a,
107
+static void tcg_out_cmp(TCGContext *s, TCGType ext, TCGCond cond, TCGReg a,
108
tcg_target_long b, bool const_b)
109
{
110
- if (const_b) {
111
- /* Using CMP or CMN aliases. */
112
- if (b >= 0) {
113
- tcg_out_insn(s, 3401, SUBSI, ext, TCG_REG_XZR, a, b);
114
+ if (is_tst_cond(cond)) {
115
+ if (!const_b) {
116
+ tcg_out_insn(s, 3510, ANDS, ext, TCG_REG_XZR, a, b);
117
} else {
118
- tcg_out_insn(s, 3401, ADDSI, ext, TCG_REG_XZR, a, -b);
119
+ tcg_debug_assert(is_limm(b));
120
+ tcg_out_logicali(s, I3404_ANDSI, 0, TCG_REG_XZR, a, b);
121
}
122
} else {
123
- /* Using CMP alias SUBS wzr, Wn, Wm */
124
- tcg_out_insn(s, 3502, SUBS, ext, TCG_REG_XZR, a, b);
125
+ if (!const_b) {
126
+ tcg_out_insn(s, 3502, SUBS, ext, TCG_REG_XZR, a, b);
127
+ } else if (b >= 0) {
128
+ tcg_debug_assert(is_aimm(b));
129
+ tcg_out_insn(s, 3401, SUBSI, ext, TCG_REG_XZR, a, b);
130
+ } else {
131
+ tcg_debug_assert(is_aimm(-b));
132
+ tcg_out_insn(s, 3401, ADDSI, ext, TCG_REG_XZR, a, -b);
133
+ }
134
}
135
}
136
137
@@ -XXX,XX +XXX,XX @@ static void tcg_out_brcond(TCGContext *s, TCGType ext, TCGCond c, TCGArg a,
138
need_cmp = false;
139
} else {
140
need_cmp = true;
141
- tcg_out_cmp(s, ext, a, b, b_const);
142
+ tcg_out_cmp(s, ext, c, a, b, b_const);
143
}
144
145
if (!l->has_value) {
146
@@ -XXX,XX +XXX,XX @@ static void tcg_out_cltz(TCGContext *s, TCGType ext, TCGReg d,
147
} else {
148
AArch64Insn sel = I3506_CSEL;
149
150
- tcg_out_cmp(s, ext, a0, 0, 1);
151
+ tcg_out_cmp(s, ext, TCG_COND_NE, a0, 0, 1);
152
tcg_out_insn(s, 3507, CLZ, ext, TCG_REG_TMP0, a1);
153
154
if (const_b) {
155
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
156
addr_adj, compare_mask);
157
158
/* Perform the address comparison. */
159
- tcg_out_cmp(s, addr_type, TCG_REG_TMP0, TCG_REG_TMP2, 0);
160
+ tcg_out_cmp(s, addr_type, TCG_COND_NE, TCG_REG_TMP0, TCG_REG_TMP2, 0);
161
162
/* If not equal, we jump to the slow path. */
163
ldst->label_ptr[0] = s->code_ptr;
164
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
165
a2 = (int32_t)a2;
166
/* FALLTHRU */
167
case INDEX_op_setcond_i64:
168
- tcg_out_cmp(s, ext, a1, a2, c2);
169
+ tcg_out_cmp(s, ext, args[3], a1, a2, c2);
170
/* Use CSET alias of CSINC Wd, WZR, WZR, invert(cond). */
171
tcg_out_insn(s, 3506, CSINC, TCG_TYPE_I32, a0, TCG_REG_XZR,
172
TCG_REG_XZR, tcg_invert_cond(args[3]));
173
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
174
a2 = (int32_t)a2;
175
/* FALLTHRU */
176
case INDEX_op_negsetcond_i64:
177
- tcg_out_cmp(s, ext, a1, a2, c2);
178
+ tcg_out_cmp(s, ext, args[3], a1, a2, c2);
179
/* Use CSETM alias of CSINV Wd, WZR, WZR, invert(cond). */
180
tcg_out_insn(s, 3506, CSINV, ext, a0, TCG_REG_XZR,
181
TCG_REG_XZR, tcg_invert_cond(args[3]));
182
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
183
a2 = (int32_t)a2;
184
/* FALLTHRU */
185
case INDEX_op_movcond_i64:
186
- tcg_out_cmp(s, ext, a1, a2, c2);
187
+ tcg_out_cmp(s, ext, args[5], a1, a2, c2);
188
tcg_out_insn(s, 3506, CSEL, ext, a0, REG0(3), REG0(4), args[5]);
189
break;
190
191
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
192
case INDEX_op_add_i64:
193
case INDEX_op_sub_i32:
194
case INDEX_op_sub_i64:
195
+ return C_O1_I2(r, r, rA);
196
+
197
case INDEX_op_setcond_i32:
198
case INDEX_op_setcond_i64:
199
case INDEX_op_negsetcond_i32:
200
case INDEX_op_negsetcond_i64:
201
- return C_O1_I2(r, r, rA);
202
+ return C_O1_I2(r, r, rC);
203
204
case INDEX_op_mul_i32:
205
case INDEX_op_mul_i64:
206
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
207
208
case INDEX_op_brcond_i32:
209
case INDEX_op_brcond_i64:
210
- return C_O0_I2(r, rA);
211
+ return C_O0_I2(r, rC);
212
213
case INDEX_op_movcond_i32:
214
case INDEX_op_movcond_i64:
215
- return C_O1_I4(r, r, rA, rZ, rZ);
216
+ return C_O1_I4(r, r, rC, rZ, rZ);
217
218
case INDEX_op_qemu_ld_a32_i32:
219
case INDEX_op_qemu_ld_a64_i32:
220
--
221
2.34.1
222
223
diff view generated by jsdifflib
1
Better constraint for tcg_out_cmp, based on the comparison.
1
This allows targets to declare that the helper requires a
2
float_status pointer and instead of a generic void pointer.
2
3
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
---
6
tcg/s390x/tcg-target-con-set.h | 6 +--
7
include/exec/helper-head.h.inc | 3 +++
7
tcg/s390x/tcg-target-con-str.h | 1 +
8
1 file changed, 3 insertions(+)
8
tcg/s390x/tcg-target.c.inc | 72 +++++++++++++++++++++++++---------
9
3 files changed, 58 insertions(+), 21 deletions(-)
10
9
11
diff --git a/tcg/s390x/tcg-target-con-set.h b/tcg/s390x/tcg-target-con-set.h
10
diff --git a/include/exec/helper-head.h.inc b/include/exec/helper-head.h.inc
12
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
13
--- a/tcg/s390x/tcg-target-con-set.h
12
--- a/include/exec/helper-head.h.inc
14
+++ b/tcg/s390x/tcg-target-con-set.h
13
+++ b/include/exec/helper-head.h.inc
15
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@
16
C_O0_I1(r)
15
#define dh_alias_ptr ptr
17
C_O0_I2(r, r)
16
#define dh_alias_cptr ptr
18
C_O0_I2(r, ri)
17
#define dh_alias_env ptr
19
-C_O0_I2(r, rJU)
18
+#define dh_alias_fpst ptr
20
+C_O0_I2(r, rC)
19
#define dh_alias_void void
21
C_O0_I2(v, r)
20
#define dh_alias_noreturn noreturn
22
C_O0_I3(o, m, r)
21
#define dh_alias(t) glue(dh_alias_, t)
23
C_O1_I1(r, r)
24
@@ -XXX,XX +XXX,XX @@ C_O1_I2(r, 0, rI)
25
C_O1_I2(r, 0, rJ)
26
C_O1_I2(r, r, r)
27
C_O1_I2(r, r, ri)
28
-C_O1_I2(r, r, rJU)
29
+C_O1_I2(r, r, rC)
30
C_O1_I2(r, r, rI)
31
C_O1_I2(r, r, rJ)
32
C_O1_I2(r, r, rK)
33
@@ -XXX,XX +XXX,XX @@ C_O1_I2(v, v, r)
34
C_O1_I2(v, v, v)
35
C_O1_I3(v, v, v, v)
36
C_O1_I4(r, r, ri, rI, r)
37
-C_O1_I4(r, r, rJU, rI, r)
38
+C_O1_I4(r, r, rC, rI, r)
39
C_O2_I1(o, m, r)
40
C_O2_I2(o, m, 0, r)
41
C_O2_I2(o, m, r, r)
42
diff --git a/tcg/s390x/tcg-target-con-str.h b/tcg/s390x/tcg-target-con-str.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/tcg/s390x/tcg-target-con-str.h
45
+++ b/tcg/s390x/tcg-target-con-str.h
46
@@ -XXX,XX +XXX,XX @@ REGS('o', 0xaaaa) /* odd numbered general regs */
47
* Define constraint letters for constants:
48
* CONST(letter, TCG_CT_CONST_* bit set)
49
*/
50
+CONST('C', TCG_CT_CONST_CMP)
51
CONST('I', TCG_CT_CONST_S16)
52
CONST('J', TCG_CT_CONST_S32)
53
CONST('K', TCG_CT_CONST_P32)
54
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
55
index XXXXXXX..XXXXXXX 100644
56
--- a/tcg/s390x/tcg-target.c.inc
57
+++ b/tcg/s390x/tcg-target.c.inc
58
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@
59
#define TCG_CT_CONST_P32 (1 << 12)
23
#define dh_ctype_ptr void *
60
#define TCG_CT_CONST_INV (1 << 13)
24
#define dh_ctype_cptr const void *
61
#define TCG_CT_CONST_INVRISBG (1 << 14)
25
#define dh_ctype_env CPUArchState *
62
+#define TCG_CT_CONST_CMP (1 << 15)
26
+#define dh_ctype_fpst float_status *
63
27
#define dh_ctype_void void
64
#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 16)
28
#define dh_ctype_noreturn G_NORETURN void
65
#define ALL_VECTOR_REGS MAKE_64BIT_MASK(32, 32)
29
#define dh_ctype(t) dh_ctype_##t
66
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, int ct,
30
@@ -XXX,XX +XXX,XX @@
67
val = (int32_t)val;
31
#define dh_typecode_f64 dh_typecode_i64
68
}
32
#define dh_typecode_cptr dh_typecode_ptr
69
33
#define dh_typecode_env dh_typecode_ptr
70
+ if (ct & TCG_CT_CONST_CMP) {
34
+#define dh_typecode_fpst dh_typecode_ptr
71
+ switch (cond) {
35
#define dh_typecode(t) dh_typecode_##t
72
+ case TCG_COND_EQ:
36
73
+ case TCG_COND_NE:
37
#define dh_callflag_i32 0
74
+ ct |= TCG_CT_CONST_S32 | TCG_CT_CONST_U32; /* CGFI or CLGFI */
75
+ break;
76
+ case TCG_COND_LT:
77
+ case TCG_COND_GE:
78
+ case TCG_COND_LE:
79
+ case TCG_COND_GT:
80
+ ct |= TCG_CT_CONST_S32; /* CGFI */
81
+ break;
82
+ case TCG_COND_LTU:
83
+ case TCG_COND_GEU:
84
+ case TCG_COND_LEU:
85
+ case TCG_COND_GTU:
86
+ ct |= TCG_CT_CONST_U32; /* CLGFI */
87
+ break;
88
+ default:
89
+ g_assert_not_reached();
90
+ }
91
+ }
92
+
93
if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
94
return true;
95
}
96
@@ -XXX,XX +XXX,XX @@ static int tgen_cmp2(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
97
goto exit;
98
}
99
100
- /*
101
- * Constraints are for a signed 33-bit operand, which is a
102
- * convenient superset of this signed/unsigned test.
103
- */
104
- if (c2 == (is_unsigned ? (TCGArg)(uint32_t)c2 : (TCGArg)(int32_t)c2)) {
105
- op = (is_unsigned ? RIL_CLGFI : RIL_CGFI);
106
- tcg_out_insn_RIL(s, op, r1, c2);
107
- goto exit;
108
+ /* Should match TCG_CT_CONST_CMP. */
109
+ switch (c) {
110
+ case TCG_COND_LT:
111
+ case TCG_COND_GE:
112
+ case TCG_COND_LE:
113
+ case TCG_COND_GT:
114
+ tcg_debug_assert(c2 == (int32_t)c2);
115
+ op = RIL_CGFI;
116
+ break;
117
+ case TCG_COND_EQ:
118
+ case TCG_COND_NE:
119
+ if (c2 == (int32_t)c2) {
120
+ op = RIL_CGFI;
121
+ break;
122
+ }
123
+ /* fall through */
124
+ case TCG_COND_LTU:
125
+ case TCG_COND_GEU:
126
+ case TCG_COND_LEU:
127
+ case TCG_COND_GTU:
128
+ tcg_debug_assert(c2 == (uint32_t)c2);
129
+ op = RIL_CLGFI;
130
+ break;
131
+ default:
132
+ g_assert_not_reached();
133
}
134
-
135
- /* Load everything else into a register. */
136
- tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, c2);
137
- c2 = TCG_TMP0;
138
- }
139
-
140
- if (type == TCG_TYPE_I32) {
141
+ tcg_out_insn_RIL(s, op, r1, c2);
142
+ } else if (type == TCG_TYPE_I32) {
143
op = (is_unsigned ? RR_CLR : RR_CR);
144
tcg_out_insn_RR(s, op, r1, c2);
145
} else {
146
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
147
return C_O1_I2(r, r, ri);
148
case INDEX_op_setcond_i64:
149
case INDEX_op_negsetcond_i64:
150
- return C_O1_I2(r, r, rJU);
151
+ return C_O1_I2(r, r, rC);
152
153
case INDEX_op_clz_i64:
154
return C_O1_I2(r, r, rI);
155
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
156
case INDEX_op_brcond_i32:
157
return C_O0_I2(r, ri);
158
case INDEX_op_brcond_i64:
159
- return C_O0_I2(r, rJU);
160
+ return C_O0_I2(r, rC);
161
162
case INDEX_op_bswap16_i32:
163
case INDEX_op_bswap16_i64:
164
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
165
case INDEX_op_movcond_i32:
166
return C_O1_I4(r, r, ri, rI, r);
167
case INDEX_op_movcond_i64:
168
- return C_O1_I4(r, r, rJU, rI, r);
169
+ return C_O1_I4(r, r, rC, rI, r);
170
171
case INDEX_op_div2_i32:
172
case INDEX_op_div2_i64:
173
--
38
--
174
2.34.1
39
2.43.0
175
40
176
41
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
In order to ease next commit review, modify tcg_out_brcond()
3
Rather than manually copying each register, use
4
to switch over TCGCond. No logical change intended.
4
the libc memcpy(), which is well optimized nowadays.
5
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>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-Id: <20240119224737.48943-1-philmd@linaro.org>
10
Message-ID: <20241205205418.67613-1-philmd@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
12
---
10
tcg/aarch64/tcg-target.c.inc | 31 +++++++++++++++++++++++--------
13
target/sparc/win_helper.c | 26 ++++++++------------------
11
1 file changed, 23 insertions(+), 8 deletions(-)
14
1 file changed, 8 insertions(+), 18 deletions(-)
12
15
13
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
16
diff --git a/target/sparc/win_helper.c b/target/sparc/win_helper.c
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/tcg/aarch64/tcg-target.c.inc
18
--- a/target/sparc/win_helper.c
16
+++ b/tcg/aarch64/tcg-target.c.inc
19
+++ b/target/sparc/win_helper.c
17
@@ -XXX,XX +XXX,XX @@ static void tcg_out_brcond(TCGContext *s, TCGType ext, TCGCond c, TCGArg a,
20
@@ -XXX,XX +XXX,XX @@
18
TCGArg b, bool b_const, TCGLabel *l)
21
#include "exec/helper-proto.h"
22
#include "trace.h"
23
24
-static inline void memcpy32(target_ulong *dst, const target_ulong *src)
25
-{
26
- dst[0] = src[0];
27
- dst[1] = src[1];
28
- dst[2] = src[2];
29
- dst[3] = src[3];
30
- dst[4] = src[4];
31
- dst[5] = src[5];
32
- dst[6] = src[6];
33
- dst[7] = src[7];
34
-}
35
-
36
void cpu_set_cwp(CPUSPARCState *env, int new_cwp)
19
{
37
{
20
intptr_t offset;
38
/* put the modified wrap registers at their proper location */
21
- bool need_cmp;
39
if (env->cwp == env->nwindows - 1) {
22
+ bool need_cmp = true;
40
- memcpy32(env->regbase, env->regbase + env->nwindows * 16);
23
41
+ memcpy(env->regbase, env->regbase + env->nwindows * 16,
24
- if (b_const && b == 0 && (c == TCG_COND_EQ || c == TCG_COND_NE)) {
42
+ sizeof(env->gregs));
25
- need_cmp = false;
26
- } else {
27
- need_cmp = true;
28
+ switch (c) {
29
+ case TCG_COND_EQ:
30
+ case TCG_COND_NE:
31
+ if (b_const && b == 0) {
32
+ need_cmp = false;
33
+ }
34
+ break;
35
+ default:
36
+ break;
37
+ }
38
+
39
+ if (need_cmp) {
40
tcg_out_cmp(s, ext, c, a, b, b_const);
41
}
43
}
42
44
env->cwp = new_cwp;
43
@@ -XXX,XX +XXX,XX @@ static void tcg_out_brcond(TCGContext *s, TCGType ext, TCGCond c, TCGArg a,
45
44
46
/* put the wrap registers at their temporary location */
45
if (need_cmp) {
47
if (new_cwp == env->nwindows - 1) {
46
tcg_out_insn(s, 3202, B_C, c, offset);
48
- memcpy32(env->regbase + env->nwindows * 16, env->regbase);
47
- } else if (c == TCG_COND_EQ) {
49
+ memcpy(env->regbase + env->nwindows * 16, env->regbase,
48
- tcg_out_insn(s, 3201, CBZ, ext, a, offset);
50
+ sizeof(env->gregs));
49
} else {
51
}
50
- tcg_out_insn(s, 3201, CBNZ, ext, a, offset);
52
env->regwptr = env->regbase + (new_cwp * 16);
51
+ switch (c) {
53
}
52
+ case TCG_COND_EQ:
54
@@ -XXX,XX +XXX,XX @@ void cpu_gl_switch_gregs(CPUSPARCState *env, uint32_t new_gl)
53
+ tcg_out_insn(s, 3201, CBZ, ext, a, offset);
55
dst = get_gl_gregset(env, env->gl);
54
+ break;
56
55
+ case TCG_COND_NE:
57
if (src != dst) {
56
+ tcg_out_insn(s, 3201, CBNZ, ext, a, offset);
58
- memcpy32(dst, env->gregs);
57
+ break;
59
- memcpy32(env->gregs, src);
58
+ default:
60
+ memcpy(dst, env->gregs, sizeof(env->gregs));
59
+ g_assert_not_reached();
61
+ memcpy(env->gregs, src, sizeof(env->gregs));
60
+ }
61
}
62
}
62
}
63
}
63
64
65
@@ -XXX,XX +XXX,XX @@ void cpu_change_pstate(CPUSPARCState *env, uint32_t new_pstate)
66
/* Switch global register bank */
67
src = get_gregset(env, new_pstate_regs);
68
dst = get_gregset(env, pstate_regs);
69
- memcpy32(dst, env->gregs);
70
- memcpy32(env->gregs, src);
71
+ memcpy(dst, env->gregs, sizeof(env->gregs));
72
+ memcpy(env->gregs, src, sizeof(env->gregs));
73
} else {
74
trace_win_helper_no_switch_pstate(new_pstate_regs);
75
}
64
--
76
--
65
2.34.1
77
2.43.0
66
78
67
79
diff view generated by jsdifflib
Deleted patch
1
Test the sign bit for LT/GE vs 0, and TSTNE/EQ vs a power of 2.
2
1
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Message-Id: <20240119224737.48943-2-philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
tcg/aarch64/tcg-target.c.inc | 74 ++++++++++++++++++++++++++++++------
8
1 file changed, 62 insertions(+), 12 deletions(-)
9
10
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/aarch64/tcg-target.c.inc
13
+++ b/tcg/aarch64/tcg-target.c.inc
14
@@ -XXX,XX +XXX,XX @@ static bool reloc_pc19(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
15
return false;
16
}
17
18
+static bool reloc_pc14(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
19
+{
20
+ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
21
+ ptrdiff_t offset = target - src_rx;
22
+
23
+ if (offset == sextract64(offset, 0, 14)) {
24
+ *src_rw = deposit32(*src_rw, 5, 14, offset);
25
+ return true;
26
+ }
27
+ return false;
28
+}
29
+
30
static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
31
intptr_t value, intptr_t addend)
32
{
33
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
34
return reloc_pc26(code_ptr, (const tcg_insn_unit *)value);
35
case R_AARCH64_CONDBR19:
36
return reloc_pc19(code_ptr, (const tcg_insn_unit *)value);
37
+ case R_AARCH64_TSTBR14:
38
+ return reloc_pc14(code_ptr, (const tcg_insn_unit *)value);
39
default:
40
g_assert_not_reached();
41
}
42
@@ -XXX,XX +XXX,XX @@ typedef enum {
43
/* Conditional branch (immediate). */
44
I3202_B_C = 0x54000000,
45
46
+ /* Test and branch (immediate). */
47
+ I3205_TBZ = 0x36000000,
48
+ I3205_TBNZ = 0x37000000,
49
+
50
/* Unconditional branch (immediate). */
51
I3206_B = 0x14000000,
52
I3206_BL = 0x94000000,
53
@@ -XXX,XX +XXX,XX @@ static void tcg_out_insn_3202(TCGContext *s, AArch64Insn insn,
54
tcg_out32(s, insn | tcg_cond_to_aarch64[c] | (imm19 & 0x7ffff) << 5);
55
}
56
57
+static void tcg_out_insn_3205(TCGContext *s, AArch64Insn insn,
58
+ TCGReg rt, int imm6, int imm14)
59
+{
60
+ insn |= (imm6 & 0x20) << (31 - 5);
61
+ insn |= (imm6 & 0x1f) << 19;
62
+ tcg_out32(s, insn | (imm14 & 0x3fff) << 5 | rt);
63
+}
64
+
65
static void tcg_out_insn_3206(TCGContext *s, AArch64Insn insn, int imm26)
66
{
67
tcg_out32(s, insn | (imm26 & 0x03ffffff));
68
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_goto_label(TCGContext *s, TCGLabel *l)
69
static void tcg_out_brcond(TCGContext *s, TCGType ext, TCGCond c, TCGArg a,
70
TCGArg b, bool b_const, TCGLabel *l)
71
{
72
- intptr_t offset;
73
+ int tbit = -1;
74
bool need_cmp = true;
75
76
switch (c) {
77
case TCG_COND_EQ:
78
case TCG_COND_NE:
79
+ /* cmp xN,0; b.ne L -> cbnz xN,L */
80
if (b_const && b == 0) {
81
need_cmp = false;
82
}
83
break;
84
+ case TCG_COND_LT:
85
+ case TCG_COND_GE:
86
+ /* cmp xN,0; b.mi L -> tbnz xN,63,L */
87
+ if (b_const && b == 0) {
88
+ c = (c == TCG_COND_LT ? TCG_COND_TSTNE : TCG_COND_TSTEQ);
89
+ tbit = ext ? 63 : 31;
90
+ need_cmp = false;
91
+ }
92
+ break;
93
+ case TCG_COND_TSTEQ:
94
+ case TCG_COND_TSTNE:
95
+ /* tst xN,1<<B; b.ne L -> tbnz xN,B,L */
96
+ if (b_const && is_power_of_2(b)) {
97
+ tbit = ctz64(b);
98
+ need_cmp = false;
99
+ }
100
+ break;
101
default:
102
break;
103
}
104
105
if (need_cmp) {
106
tcg_out_cmp(s, ext, c, a, b, b_const);
107
- }
108
-
109
- if (!l->has_value) {
110
tcg_out_reloc(s, s->code_ptr, R_AARCH64_CONDBR19, l, 0);
111
- offset = tcg_in32(s) >> 5;
112
- } else {
113
- offset = tcg_pcrel_diff(s, l->u.value_ptr) >> 2;
114
- tcg_debug_assert(offset == sextract64(offset, 0, 19));
115
+ tcg_out_insn(s, 3202, B_C, c, 0);
116
+ return;
117
}
118
119
- if (need_cmp) {
120
- tcg_out_insn(s, 3202, B_C, c, offset);
121
+ if (tbit >= 0) {
122
+ tcg_out_reloc(s, s->code_ptr, R_AARCH64_TSTBR14, l, 0);
123
+ switch (c) {
124
+ case TCG_COND_TSTEQ:
125
+ tcg_out_insn(s, 3205, TBZ, a, tbit, 0);
126
+ break;
127
+ case TCG_COND_TSTNE:
128
+ tcg_out_insn(s, 3205, TBNZ, a, tbit, 0);
129
+ break;
130
+ default:
131
+ g_assert_not_reached();
132
+ }
133
} else {
134
+ tcg_out_reloc(s, s->code_ptr, R_AARCH64_CONDBR19, l, 0);
135
switch (c) {
136
case TCG_COND_EQ:
137
- tcg_out_insn(s, 3201, CBZ, ext, a, offset);
138
+ tcg_out_insn(s, 3201, CBZ, ext, a, 0);
139
break;
140
case TCG_COND_NE:
141
- tcg_out_insn(s, 3201, CBNZ, ext, a, offset);
142
+ tcg_out_insn(s, 3201, CBNZ, ext, a, 0);
143
break;
144
default:
145
g_assert_not_reached();
146
--
147
2.34.1
148
149
diff view generated by jsdifflib
Deleted patch
1
... and the inverse, CBZ for TSTEQ.
2
1
3
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
tcg/aarch64/tcg-target.c.inc | 6 ++++++
8
1 file changed, 6 insertions(+)
9
10
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/aarch64/tcg-target.c.inc
13
+++ b/tcg/aarch64/tcg-target.c.inc
14
@@ -XXX,XX +XXX,XX @@ static void tcg_out_brcond(TCGContext *s, TCGType ext, TCGCond c, TCGArg a,
15
break;
16
case TCG_COND_TSTEQ:
17
case TCG_COND_TSTNE:
18
+ /* tst xN,0xffffffff; b.ne L -> cbnz wN,L */
19
+ if (b_const && b == UINT32_MAX) {
20
+ ext = TCG_TYPE_I32;
21
+ need_cmp = false;
22
+ break;
23
+ }
24
/* tst xN,1<<B; b.ne L -> tbnz xN,B,L */
25
if (b_const && is_power_of_2(b)) {
26
tbit = ctz64(b);
27
--
28
2.34.1
29
30
diff view generated by jsdifflib
Deleted patch
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Message-Id: <20231028194522.245170-12-richard.henderson@linaro.org>
4
[PMD: Split from bigger patch, part 1/2]
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-Id: <20231108145244.72421-1-philmd@linaro.org>
7
---
8
tcg/arm/tcg-target.c.inc | 32 +++++++++++++++++---------------
9
1 file changed, 17 insertions(+), 15 deletions(-)
10
1
11
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
12
index XXXXXXX..XXXXXXX 100644
13
--- a/tcg/arm/tcg-target.c.inc
14
+++ b/tcg/arm/tcg-target.c.inc
15
@@ -XXX,XX +XXX,XX @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
16
}
17
}
18
19
+static TCGCond tcg_out_cmp(TCGContext *s, TCGCond cond, TCGReg a,
20
+ TCGArg b, int b_const)
21
+{
22
+ tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0, a, b, b_const);
23
+ return cond;
24
+}
25
+
26
static TCGCond tcg_out_cmp2(TCGContext *s, const TCGArg *args,
27
const int *const_args)
28
{
29
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
30
/* Constraints mean that v2 is always in the same register as dest,
31
* so we only need to do "if condition passed, move v1 to dest".
32
*/
33
- tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
34
- args[1], args[2], const_args[2]);
35
- tcg_out_dat_rIK(s, tcg_cond_to_arm_cond[args[5]], ARITH_MOV,
36
+ c = tcg_out_cmp(s, args[5], args[1], args[2], const_args[2]);
37
+ tcg_out_dat_rIK(s, tcg_cond_to_arm_cond[c], ARITH_MOV,
38
ARITH_MVN, args[0], 0, args[3], const_args[3]);
39
break;
40
case INDEX_op_add_i32:
41
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
42
break;
43
44
case INDEX_op_brcond_i32:
45
- tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
46
- args[0], args[1], const_args[1]);
47
- tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[2]],
48
- arg_label(args[3]));
49
+ c = tcg_out_cmp(s, args[2], args[0], args[1], const_args[1]);
50
+ tcg_out_goto_label(s, tcg_cond_to_arm_cond[c], arg_label(args[3]));
51
break;
52
case INDEX_op_setcond_i32:
53
- tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
54
- args[1], args[2], const_args[2]);
55
- tcg_out_dat_imm(s, tcg_cond_to_arm_cond[args[3]],
56
+ c = tcg_out_cmp(s, args[3], args[1], args[2], const_args[2]);
57
+ tcg_out_dat_imm(s, tcg_cond_to_arm_cond[c],
58
ARITH_MOV, args[0], 0, 1);
59
- tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(args[3])],
60
+ tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(c)],
61
ARITH_MOV, args[0], 0, 0);
62
break;
63
case INDEX_op_negsetcond_i32:
64
- tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
65
- args[1], args[2], const_args[2]);
66
- tcg_out_dat_imm(s, tcg_cond_to_arm_cond[args[3]],
67
+ c = tcg_out_cmp(s, args[3], args[1], args[2], const_args[2]);
68
+ tcg_out_dat_imm(s, tcg_cond_to_arm_cond[c],
69
ARITH_MVN, args[0], 0, 0);
70
- tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(args[3])],
71
+ tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(c)],
72
ARITH_MOV, args[0], 0, 0);
73
break;
74
75
--
76
2.34.1
77
78
diff view generated by jsdifflib
Deleted patch
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Message-Id: <20231028194522.245170-12-richard.henderson@linaro.org>
4
[PMD: Split from bigger patch, part 2/2]
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-Id: <20231108145244.72421-2-philmd@linaro.org>
7
---
8
tcg/arm/tcg-target.h | 2 +-
9
tcg/arm/tcg-target.c.inc | 29 ++++++++++++++++++++++++++++-
10
2 files changed, 29 insertions(+), 2 deletions(-)
11
1
12
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/tcg/arm/tcg-target.h
15
+++ b/tcg/arm/tcg-target.h
16
@@ -XXX,XX +XXX,XX @@ extern bool use_neon_instructions;
17
18
#define TCG_TARGET_HAS_qemu_ldst_i128 0
19
20
-#define TCG_TARGET_HAS_tst 0
21
+#define TCG_TARGET_HAS_tst 1
22
23
#define TCG_TARGET_HAS_v64 use_neon_instructions
24
#define TCG_TARGET_HAS_v128 use_neon_instructions
25
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/tcg/arm/tcg-target.c.inc
28
+++ b/tcg/arm/tcg-target.c.inc
29
@@ -XXX,XX +XXX,XX @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
30
static TCGCond tcg_out_cmp(TCGContext *s, TCGCond cond, TCGReg a,
31
TCGArg b, int b_const)
32
{
33
- tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0, a, b, b_const);
34
+ if (!is_tst_cond(cond)) {
35
+ tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0, a, b, b_const);
36
+ return cond;
37
+ }
38
+
39
+ cond = tcg_tst_eqne_cond(cond);
40
+ if (b_const) {
41
+ int imm12 = encode_imm(b);
42
+
43
+ /*
44
+ * The compare constraints allow rIN, but TST does not support N.
45
+ * Be prepared to load the constant into a scratch register.
46
+ */
47
+ if (imm12 >= 0) {
48
+ tcg_out_dat_imm(s, COND_AL, ARITH_TST, 0, a, imm12);
49
+ return cond;
50
+ }
51
+ tcg_out_movi32(s, COND_AL, TCG_REG_TMP, b);
52
+ b = TCG_REG_TMP;
53
+ }
54
+ tcg_out_dat_reg(s, COND_AL, ARITH_TST, 0, a, b, SHIFT_IMM_LSL(0));
55
return cond;
56
}
57
58
@@ -XXX,XX +XXX,XX @@ static TCGCond tcg_out_cmp2(TCGContext *s, const TCGArg *args,
59
tcg_out_dat_rI(s, COND_EQ, ARITH_CMP, 0, al, bl, const_bl);
60
return cond;
61
62
+ case TCG_COND_TSTEQ:
63
+ case TCG_COND_TSTNE:
64
+ /* Similar, but with TST instead of CMP. */
65
+ tcg_out_dat_rI(s, COND_AL, ARITH_TST, 0, ah, bh, const_bh);
66
+ tcg_out_dat_rI(s, COND_EQ, ARITH_TST, 0, al, bl, const_bl);
67
+ return tcg_tst_eqne_cond(cond);
68
+
69
case TCG_COND_LT:
70
case TCG_COND_GE:
71
/* We perform a double-word subtraction and examine the result.
72
--
73
2.34.1
74
75
diff view generated by jsdifflib
Deleted patch
1
Hoist the tcg_cond_to_jcc index outside the function.
2
1
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/i386/tcg-target.c.inc | 16 ++++++++--------
7
1 file changed, 8 insertions(+), 8 deletions(-)
8
9
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/i386/tcg-target.c.inc
12
+++ b/tcg/i386/tcg-target.c.inc
13
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
14
}
15
#endif
16
17
-static void tcg_out_cmov(TCGContext *s, TCGCond cond, int rexw,
18
+static void tcg_out_cmov(TCGContext *s, int jcc, int rexw,
19
TCGReg dest, TCGReg v1)
20
{
21
if (have_cmov) {
22
- tcg_out_modrm(s, OPC_CMOVCC | tcg_cond_to_jcc[cond] | rexw, dest, v1);
23
+ tcg_out_modrm(s, OPC_CMOVCC | jcc | rexw, dest, v1);
24
} else {
25
TCGLabel *over = gen_new_label();
26
- tcg_out_jxx(s, tcg_cond_to_jcc[tcg_invert_cond(cond)], over, 1);
27
+ tcg_out_jxx(s, jcc ^ 1, over, 1);
28
tcg_out_mov(s, TCG_TYPE_I32, dest, v1);
29
tcg_out_label(s, over);
30
}
31
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movcond(TCGContext *s, int rexw, TCGCond cond,
32
TCGReg v1)
33
{
34
tcg_out_cmp(s, c1, c2, const_c2, rexw);
35
- tcg_out_cmov(s, cond, rexw, dest, v1);
36
+ tcg_out_cmov(s, tcg_cond_to_jcc[cond], rexw, dest, v1);
37
}
38
39
static void tcg_out_ctz(TCGContext *s, int rexw, TCGReg dest, TCGReg arg1,
40
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ctz(TCGContext *s, int rexw, TCGReg dest, TCGReg arg1,
41
tcg_debug_assert(arg2 == (rexw ? 64 : 32));
42
} else {
43
tcg_debug_assert(dest != arg2);
44
- tcg_out_cmov(s, TCG_COND_LTU, rexw, dest, arg2);
45
+ tcg_out_cmov(s, JCC_JB, rexw, dest, arg2);
46
}
47
} else {
48
tcg_debug_assert(dest != arg2);
49
tcg_out_modrm(s, OPC_BSF + rexw, dest, arg1);
50
- tcg_out_cmov(s, TCG_COND_EQ, rexw, dest, arg2);
51
+ tcg_out_cmov(s, JCC_JE, rexw, dest, arg2);
52
}
53
}
54
55
@@ -XXX,XX +XXX,XX @@ static void tcg_out_clz(TCGContext *s, int rexw, TCGReg dest, TCGReg arg1,
56
tcg_debug_assert(arg2 == (rexw ? 64 : 32));
57
} else {
58
tcg_debug_assert(dest != arg2);
59
- tcg_out_cmov(s, TCG_COND_LTU, rexw, dest, arg2);
60
+ tcg_out_cmov(s, JCC_JB, rexw, dest, arg2);
61
}
62
} else {
63
tcg_debug_assert(!const_a2);
64
@@ -XXX,XX +XXX,XX @@ static void tcg_out_clz(TCGContext *s, int rexw, TCGReg dest, TCGReg arg1,
65
66
/* Since we have destroyed the flags from BSR, we have to re-test. */
67
tcg_out_cmp(s, arg1, 0, 1, rexw);
68
- tcg_out_cmov(s, TCG_COND_EQ, rexw, dest, arg2);
69
+ tcg_out_cmov(s, JCC_JE, rexw, dest, arg2);
70
}
71
}
72
73
--
74
2.34.1
75
76
diff view generated by jsdifflib
Deleted patch
1
Return the x86 condition codes to use after the compare.
2
1
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/i386/tcg-target.c.inc | 24 +++++++++++++-----------
7
1 file changed, 13 insertions(+), 11 deletions(-)
8
9
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/i386/tcg-target.c.inc
12
+++ b/tcg/i386/tcg-target.c.inc
13
@@ -XXX,XX +XXX,XX @@ static void tcg_out_jxx(TCGContext *s, int opc, TCGLabel *l, bool small)
14
}
15
}
16
17
-static void tcg_out_cmp(TCGContext *s, TCGArg arg1, TCGArg arg2,
18
- int const_arg2, int rexw)
19
+static int tcg_out_cmp(TCGContext *s, TCGCond cond, TCGArg arg1,
20
+ TCGArg arg2, int const_arg2, int rexw)
21
{
22
if (const_arg2) {
23
if (arg2 == 0) {
24
@@ -XXX,XX +XXX,XX @@ static void tcg_out_cmp(TCGContext *s, TCGArg arg1, TCGArg arg2,
25
} else {
26
tgen_arithr(s, ARITH_CMP + rexw, arg1, arg2);
27
}
28
+ return tcg_cond_to_jcc[cond];
29
}
30
31
static void tcg_out_brcond(TCGContext *s, int rexw, TCGCond cond,
32
TCGArg arg1, TCGArg arg2, int const_arg2,
33
TCGLabel *label, bool small)
34
{
35
- tcg_out_cmp(s, arg1, arg2, const_arg2, rexw);
36
- tcg_out_jxx(s, tcg_cond_to_jcc[cond], label, small);
37
+ int jcc = tcg_out_cmp(s, cond, arg1, arg2, const_arg2, rexw);
38
+ tcg_out_jxx(s, jcc, label, small);
39
}
40
41
#if TCG_TARGET_REG_BITS == 32
42
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond(TCGContext *s, int rexw, TCGCond cond,
43
{
44
bool inv = false;
45
bool cleared;
46
+ int jcc;
47
48
switch (cond) {
49
case TCG_COND_NE:
50
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond(TCGContext *s, int rexw, TCGCond cond,
51
* We can then use NEG or INC to produce the desired result.
52
* This is always smaller than the SETCC expansion.
53
*/
54
- tcg_out_cmp(s, arg1, arg2, const_arg2, rexw);
55
+ tcg_out_cmp(s, TCG_COND_LTU, arg1, arg2, const_arg2, rexw);
56
57
/* X - X - C = -C = (C ? -1 : 0) */
58
tgen_arithr(s, ARITH_SBB + (neg ? rexw : 0), dest, dest);
59
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond(TCGContext *s, int rexw, TCGCond cond,
60
cleared = true;
61
}
62
63
- tcg_out_cmp(s, arg1, arg2, const_arg2, rexw);
64
- tcg_out_modrm(s, OPC_SETCC | tcg_cond_to_jcc[cond], 0, dest);
65
+ jcc = tcg_out_cmp(s, cond, arg1, arg2, const_arg2, rexw);
66
+ tcg_out_modrm(s, OPC_SETCC | jcc, 0, dest);
67
68
if (!cleared) {
69
tcg_out_ext8u(s, dest, dest);
70
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movcond(TCGContext *s, int rexw, TCGCond cond,
71
TCGReg dest, TCGReg c1, TCGArg c2, int const_c2,
72
TCGReg v1)
73
{
74
- tcg_out_cmp(s, c1, c2, const_c2, rexw);
75
- tcg_out_cmov(s, tcg_cond_to_jcc[cond], rexw, dest, v1);
76
+ int jcc = tcg_out_cmp(s, cond, c1, c2, const_c2, rexw);
77
+ tcg_out_cmov(s, jcc, rexw, dest, v1);
78
}
79
80
static void tcg_out_ctz(TCGContext *s, int rexw, TCGReg dest, TCGReg arg1,
81
@@ -XXX,XX +XXX,XX @@ static void tcg_out_clz(TCGContext *s, int rexw, TCGReg dest, TCGReg arg1,
82
tgen_arithi(s, ARITH_XOR + rexw, dest, rexw ? 63 : 31, 0);
83
84
/* Since we have destroyed the flags from BSR, we have to re-test. */
85
- tcg_out_cmp(s, arg1, 0, 1, rexw);
86
- tcg_out_cmov(s, JCC_JE, rexw, dest, arg2);
87
+ int jcc = tcg_out_cmp(s, TCG_COND_EQ, arg1, 0, 1, rexw);
88
+ tcg_out_cmov(s, jcc, rexw, dest, arg2);
89
}
90
}
91
92
--
93
2.34.1
94
95
diff view generated by jsdifflib
Deleted patch
1
Merge tcg_out_testi into tcg_out_cmp and adjust the two uses.
2
1
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/i386/tcg-target.h | 2 +-
7
tcg/i386/tcg-target.c.inc | 95 ++++++++++++++++++++++++---------------
8
2 files changed, 60 insertions(+), 37 deletions(-)
9
10
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/i386/tcg-target.h
13
+++ b/tcg/i386/tcg-target.h
14
@@ -XXX,XX +XXX,XX @@ typedef enum {
15
#define TCG_TARGET_HAS_qemu_ldst_i128 \
16
(TCG_TARGET_REG_BITS == 64 && (cpuinfo & CPUINFO_ATOMIC_VMOVDQA))
17
18
-#define TCG_TARGET_HAS_tst 0
19
+#define TCG_TARGET_HAS_tst 1
20
21
/* We do not support older SSE systems, only beginning with AVX1. */
22
#define TCG_TARGET_HAS_v64 have_avx1
23
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
24
index XXXXXXX..XXXXXXX 100644
25
--- a/tcg/i386/tcg-target.c.inc
26
+++ b/tcg/i386/tcg-target.c.inc
27
@@ -XXX,XX +XXX,XX @@ static const uint8_t tcg_cond_to_jcc[] = {
28
[TCG_COND_GEU] = JCC_JAE,
29
[TCG_COND_LEU] = JCC_JBE,
30
[TCG_COND_GTU] = JCC_JA,
31
+ [TCG_COND_TSTEQ] = JCC_JE,
32
+ [TCG_COND_TSTNE] = JCC_JNE,
33
};
34
35
#if TCG_TARGET_REG_BITS == 64
36
@@ -XXX,XX +XXX,XX @@ static void tcg_out_jxx(TCGContext *s, int opc, TCGLabel *l, bool small)
37
static int tcg_out_cmp(TCGContext *s, TCGCond cond, TCGArg arg1,
38
TCGArg arg2, int const_arg2, int rexw)
39
{
40
- if (const_arg2) {
41
- if (arg2 == 0) {
42
- /* test r, r */
43
+ int jz;
44
+
45
+ if (!is_tst_cond(cond)) {
46
+ if (!const_arg2) {
47
+ tgen_arithr(s, ARITH_CMP + rexw, arg1, arg2);
48
+ } else if (arg2 == 0) {
49
tcg_out_modrm(s, OPC_TESTL + rexw, arg1, arg1);
50
} else {
51
+ tcg_debug_assert(!rexw || arg2 == (int32_t)arg2);
52
tgen_arithi(s, ARITH_CMP + rexw, arg1, arg2, 0);
53
}
54
- } else {
55
- tgen_arithr(s, ARITH_CMP + rexw, arg1, arg2);
56
+ return tcg_cond_to_jcc[cond];
57
}
58
- return tcg_cond_to_jcc[cond];
59
+
60
+ jz = tcg_cond_to_jcc[cond];
61
+
62
+ if (!const_arg2) {
63
+ tcg_out_modrm(s, OPC_TESTL + rexw, arg1, arg2);
64
+ return jz;
65
+ }
66
+
67
+ if (arg2 <= 0xff && (TCG_TARGET_REG_BITS == 64 || arg1 < 4)) {
68
+ tcg_out_modrm(s, OPC_GRP3_Eb | P_REXB_RM, EXT3_TESTi, arg1);
69
+ tcg_out8(s, arg2);
70
+ return jz;
71
+ }
72
+
73
+ if ((arg2 & ~0xff00) == 0 && arg1 < 4) {
74
+ tcg_out_modrm(s, OPC_GRP3_Eb, EXT3_TESTi, arg1 + 4);
75
+ tcg_out8(s, arg2 >> 8);
76
+ return jz;
77
+ }
78
+
79
+ if (rexw) {
80
+ if (arg2 == (uint32_t)arg2) {
81
+ rexw = 0;
82
+ } else {
83
+ tcg_debug_assert(arg2 == (int32_t)arg2);
84
+ }
85
+ }
86
+ tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_TESTi, arg1);
87
+ tcg_out32(s, arg2);
88
+ return jz;
89
}
90
91
static void tcg_out_brcond(TCGContext *s, int rexw, TCGCond cond,
92
@@ -XXX,XX +XXX,XX @@ static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
93
{
94
TCGLabel *label_next = gen_new_label();
95
TCGLabel *label_this = arg_label(args[5]);
96
+ TCGCond cond = args[4];
97
98
- switch(args[4]) {
99
+ switch (cond) {
100
case TCG_COND_EQ:
101
- tcg_out_brcond(s, 0, TCG_COND_NE, args[0], args[2], const_args[2],
102
- label_next, 1);
103
- tcg_out_brcond(s, 0, TCG_COND_EQ, args[1], args[3], const_args[3],
104
+ case TCG_COND_TSTEQ:
105
+ tcg_out_brcond(s, 0, tcg_invert_cond(cond),
106
+ args[0], args[2], const_args[2], label_next, 1);
107
+ tcg_out_brcond(s, 0, cond, args[1], args[3], const_args[3],
108
label_this, small);
109
break;
110
case TCG_COND_NE:
111
- tcg_out_brcond(s, 0, TCG_COND_NE, args[0], args[2], const_args[2],
112
+ case TCG_COND_TSTNE:
113
+ tcg_out_brcond(s, 0, cond, args[0], args[2], const_args[2],
114
label_this, small);
115
- tcg_out_brcond(s, 0, TCG_COND_NE, args[1], args[3], const_args[3],
116
+ tcg_out_brcond(s, 0, cond, args[1], args[3], const_args[3],
117
label_this, small);
118
break;
119
case TCG_COND_LT:
120
@@ -XXX,XX +XXX,XX @@ static void tcg_out_nopn(TCGContext *s, int n)
121
tcg_out8(s, 0x90);
122
}
123
124
-/* Test register R vs immediate bits I, setting Z flag for EQ/NE. */
125
-static void __attribute__((unused))
126
-tcg_out_testi(TCGContext *s, TCGReg r, uint32_t i)
127
-{
128
- /*
129
- * This is used for testing alignment, so we can usually use testb.
130
- * For i686, we have to use testl for %esi/%edi.
131
- */
132
- if (i <= 0xff && (TCG_TARGET_REG_BITS == 64 || r < 4)) {
133
- tcg_out_modrm(s, OPC_GRP3_Eb | P_REXB_RM, EXT3_TESTi, r);
134
- tcg_out8(s, i);
135
- } else {
136
- tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_TESTi, r);
137
- tcg_out32(s, i);
138
- }
139
-}
140
-
141
typedef struct {
142
TCGReg base;
143
int index;
144
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
145
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_L0, TCG_REG_L0,
146
offsetof(CPUTLBEntry, addend));
147
} else if (a_mask) {
148
- ldst = new_ldst_label(s);
149
+ int jcc;
150
151
+ ldst = new_ldst_label(s);
152
ldst->is_ld = is_ld;
153
ldst->oi = oi;
154
ldst->addrlo_reg = addrlo;
155
ldst->addrhi_reg = addrhi;
156
157
- tcg_out_testi(s, addrlo, a_mask);
158
/* jne slow_path */
159
- tcg_out_opc(s, OPC_JCC_long + JCC_JNE, 0, 0, 0);
160
+ jcc = tcg_out_cmp(s, TCG_COND_TSTNE, addrlo, a_mask, true, false);
161
+ tcg_out_opc(s, OPC_JCC_long + jcc, 0, 0, 0);
162
ldst->label_ptr[0] = s->code_ptr;
163
s->code_ptr += 4;
164
}
165
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
166
} else {
167
TCGLabel *l1 = gen_new_label();
168
TCGLabel *l2 = gen_new_label();
169
+ int jcc;
170
171
- tcg_out_testi(s, h.base, 15);
172
- tcg_out_jxx(s, JCC_JNE, l1, true);
173
+ jcc = tcg_out_cmp(s, TCG_COND_TSTNE, h.base, 15, true, false);
174
+ tcg_out_jxx(s, jcc, l1, true);
175
176
tcg_out_vex_modrm_sib_offset(s, OPC_MOVDQA_VxWx + h.seg,
177
TCG_TMP_VEC, 0,
178
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
179
} else {
180
TCGLabel *l1 = gen_new_label();
181
TCGLabel *l2 = gen_new_label();
182
+ int jcc;
183
184
- tcg_out_testi(s, h.base, 15);
185
- tcg_out_jxx(s, JCC_JNE, l1, true);
186
+ jcc = tcg_out_cmp(s, TCG_COND_TSTNE, h.base, 15, true, false);
187
+ tcg_out_jxx(s, jcc, l1, true);
188
189
tcg_out_vex_modrm_sib_offset(s, OPC_MOVDQA_WxVx + h.seg,
190
TCG_TMP_VEC, 0,
191
--
192
2.34.1
193
194
diff view generated by jsdifflib
Deleted patch
1
Use "test x,x" when the bit is one of the 4 sign bits.
2
Use "bt imm,x" otherwise.
3
1
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/i386/tcg-target-con-set.h | 6 ++--
7
tcg/i386/tcg-target-con-str.h | 1 +
8
tcg/i386/tcg-target.c.inc | 54 +++++++++++++++++++++++++++++++----
9
3 files changed, 53 insertions(+), 8 deletions(-)
10
11
diff --git a/tcg/i386/tcg-target-con-set.h b/tcg/i386/tcg-target-con-set.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/tcg/i386/tcg-target-con-set.h
14
+++ b/tcg/i386/tcg-target-con-set.h
15
@@ -XXX,XX +XXX,XX @@ C_O0_I2(L, L)
16
C_O0_I2(qi, r)
17
C_O0_I2(re, r)
18
C_O0_I2(ri, r)
19
-C_O0_I2(r, re)
20
+C_O0_I2(r, reT)
21
C_O0_I2(s, L)
22
C_O0_I2(x, r)
23
C_O0_I3(L, L, L)
24
@@ -XXX,XX +XXX,XX @@ C_O1_I1(r, r)
25
C_O1_I1(x, r)
26
C_O1_I1(x, x)
27
C_O1_I2(q, 0, qi)
28
-C_O1_I2(q, r, re)
29
+C_O1_I2(q, r, reT)
30
C_O1_I2(r, 0, ci)
31
C_O1_I2(r, 0, r)
32
C_O1_I2(r, 0, re)
33
@@ -XXX,XX +XXX,XX @@ C_N1_I2(r, r, r)
34
C_N1_I2(r, r, rW)
35
C_O1_I3(x, 0, x, x)
36
C_O1_I3(x, x, x, x)
37
-C_O1_I4(r, r, re, r, 0)
38
+C_O1_I4(r, r, reT, r, 0)
39
C_O1_I4(r, r, r, ri, ri)
40
C_O2_I1(r, r, L)
41
C_O2_I2(a, d, a, r)
42
diff --git a/tcg/i386/tcg-target-con-str.h b/tcg/i386/tcg-target-con-str.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/tcg/i386/tcg-target-con-str.h
45
+++ b/tcg/i386/tcg-target-con-str.h
46
@@ -XXX,XX +XXX,XX @@ REGS('s', ALL_BYTEL_REGS & ~SOFTMMU_RESERVE_REGS) /* qemu_st8_i32 data */
47
*/
48
CONST('e', TCG_CT_CONST_S32)
49
CONST('I', TCG_CT_CONST_I32)
50
+CONST('T', TCG_CT_CONST_TST)
51
CONST('W', TCG_CT_CONST_WSZ)
52
CONST('Z', TCG_CT_CONST_U32)
53
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
54
index XXXXXXX..XXXXXXX 100644
55
--- a/tcg/i386/tcg-target.c.inc
56
+++ b/tcg/i386/tcg-target.c.inc
57
@@ -XXX,XX +XXX,XX @@ static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
58
#define TCG_CT_CONST_U32 0x200
59
#define TCG_CT_CONST_I32 0x400
60
#define TCG_CT_CONST_WSZ 0x800
61
+#define TCG_CT_CONST_TST 0x1000
62
63
/* Registers used with L constraint, which are the first argument
64
registers on x86_64, and two random call clobbered registers on
65
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, int ct,
66
return 1;
67
}
68
if (type == TCG_TYPE_I32) {
69
- if (ct & (TCG_CT_CONST_S32 | TCG_CT_CONST_U32 | TCG_CT_CONST_I32)) {
70
+ if (ct & (TCG_CT_CONST_S32 | TCG_CT_CONST_U32 |
71
+ TCG_CT_CONST_I32 | TCG_CT_CONST_TST)) {
72
return 1;
73
}
74
} else {
75
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, int ct,
76
if ((ct & TCG_CT_CONST_I32) && ~val == (int32_t)~val) {
77
return 1;
78
}
79
+ /*
80
+ * This will be used in combination with TCG_CT_CONST_S32,
81
+ * so "normal" TESTQ is already matched. Also accept:
82
+ * TESTQ -> TESTL (uint32_t)
83
+ * TESTQ -> BT (is_power_of_2)
84
+ */
85
+ if ((ct & TCG_CT_CONST_TST)
86
+ && is_tst_cond(cond)
87
+ && (val == (uint32_t)val || is_power_of_2(val))) {
88
+ return 1;
89
+ }
90
}
91
if ((ct & TCG_CT_CONST_WSZ) && val == (type == TCG_TYPE_I32 ? 32 : 64)) {
92
return 1;
93
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, int ct,
94
#define OPC_SHLX (0xf7 | P_EXT38 | P_DATA16)
95
#define OPC_SHRX (0xf7 | P_EXT38 | P_SIMDF2)
96
#define OPC_SHRD_Ib (0xac | P_EXT)
97
+#define OPC_TESTB    (0x84)
98
#define OPC_TESTL    (0x85)
99
#define OPC_TZCNT (0xbc | P_EXT | P_SIMDF3)
100
#define OPC_UD2 (0x0b | P_EXT)
101
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, int ct,
102
#define OPC_GRP3_Ev (0xf7)
103
#define OPC_GRP5 (0xff)
104
#define OPC_GRP14 (0x73 | P_EXT | P_DATA16)
105
+#define OPC_GRPBT (0xba | P_EXT)
106
+
107
+#define OPC_GRPBT_BT 4
108
+#define OPC_GRPBT_BTS 5
109
+#define OPC_GRPBT_BTR 6
110
+#define OPC_GRPBT_BTC 7
111
112
/* Group 1 opcode extensions for 0x80-0x83.
113
These are also used as modifiers for OPC_ARITH. */
114
@@ -XXX,XX +XXX,XX @@ static void tcg_out_jxx(TCGContext *s, int opc, TCGLabel *l, bool small)
115
static int tcg_out_cmp(TCGContext *s, TCGCond cond, TCGArg arg1,
116
TCGArg arg2, int const_arg2, int rexw)
117
{
118
- int jz;
119
+ int jz, js;
120
121
if (!is_tst_cond(cond)) {
122
if (!const_arg2) {
123
@@ -XXX,XX +XXX,XX @@ static int tcg_out_cmp(TCGContext *s, TCGCond cond, TCGArg arg1,
124
}
125
126
jz = tcg_cond_to_jcc[cond];
127
+ js = (cond == TCG_COND_TSTNE ? JCC_JS : JCC_JNS);
128
129
if (!const_arg2) {
130
tcg_out_modrm(s, OPC_TESTL + rexw, arg1, arg2);
131
@@ -XXX,XX +XXX,XX @@ static int tcg_out_cmp(TCGContext *s, TCGCond cond, TCGArg arg1,
132
}
133
134
if (arg2 <= 0xff && (TCG_TARGET_REG_BITS == 64 || arg1 < 4)) {
135
+ if (arg2 == 0x80) {
136
+ tcg_out_modrm(s, OPC_TESTB | P_REXB_R, arg1, arg1);
137
+ return js;
138
+ }
139
tcg_out_modrm(s, OPC_GRP3_Eb | P_REXB_RM, EXT3_TESTi, arg1);
140
tcg_out8(s, arg2);
141
return jz;
142
}
143
144
if ((arg2 & ~0xff00) == 0 && arg1 < 4) {
145
+ if (arg2 == 0x8000) {
146
+ tcg_out_modrm(s, OPC_TESTB, arg1 + 4, arg1 + 4);
147
+ return js;
148
+ }
149
tcg_out_modrm(s, OPC_GRP3_Eb, EXT3_TESTi, arg1 + 4);
150
tcg_out8(s, arg2 >> 8);
151
return jz;
152
}
153
154
+ if (is_power_of_2(rexw ? arg2 : (uint32_t)arg2)) {
155
+ int jc = (cond == TCG_COND_TSTNE ? JCC_JB : JCC_JAE);
156
+ int sh = ctz64(arg2);
157
+
158
+ rexw = (sh & 32 ? P_REXW : 0);
159
+ if ((sh & 31) == 31) {
160
+ tcg_out_modrm(s, OPC_TESTL | rexw, arg1, arg1);
161
+ return js;
162
+ } else {
163
+ tcg_out_modrm(s, OPC_GRPBT | rexw, OPC_GRPBT_BT, arg1);
164
+ tcg_out8(s, sh);
165
+ return jc;
166
+ }
167
+ }
168
+
169
if (rexw) {
170
if (arg2 == (uint32_t)arg2) {
171
rexw = 0;
172
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
173
174
case INDEX_op_brcond_i32:
175
case INDEX_op_brcond_i64:
176
- return C_O0_I2(r, re);
177
+ return C_O0_I2(r, reT);
178
179
case INDEX_op_bswap16_i32:
180
case INDEX_op_bswap16_i64:
181
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
182
case INDEX_op_setcond_i64:
183
case INDEX_op_negsetcond_i32:
184
case INDEX_op_negsetcond_i64:
185
- return C_O1_I2(q, r, re);
186
+ return C_O1_I2(q, r, reT);
187
188
case INDEX_op_movcond_i32:
189
case INDEX_op_movcond_i64:
190
- return C_O1_I4(r, r, re, r, 0);
191
+ return C_O1_I4(r, r, reT, r, 0);
192
193
case INDEX_op_div2_i32:
194
case INDEX_op_div2_i64:
195
--
196
2.34.1
diff view generated by jsdifflib
Deleted patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
1
3
Just like when testing against the sign bits, TEST r,r can be used when the
4
immediate is 0xff, 0xff00, 0xffff, 0xffffffff.
5
6
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
11
tcg/i386/tcg-target.c.inc | 17 +++++++++++++++++
12
1 file changed, 17 insertions(+)
13
14
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tcg/i386/tcg-target.c.inc
17
+++ b/tcg/i386/tcg-target.c.inc
18
@@ -XXX,XX +XXX,XX @@ static int tcg_out_cmp(TCGContext *s, TCGCond cond, TCGArg arg1,
19
tcg_out_modrm(s, OPC_TESTB | P_REXB_R, arg1, arg1);
20
return js;
21
}
22
+ if (arg2 == 0xff) {
23
+ tcg_out_modrm(s, OPC_TESTB | P_REXB_R, arg1, arg1);
24
+ return jz;
25
+ }
26
tcg_out_modrm(s, OPC_GRP3_Eb | P_REXB_RM, EXT3_TESTi, arg1);
27
tcg_out8(s, arg2);
28
return jz;
29
@@ -XXX,XX +XXX,XX @@ static int tcg_out_cmp(TCGContext *s, TCGCond cond, TCGArg arg1,
30
tcg_out_modrm(s, OPC_TESTB, arg1 + 4, arg1 + 4);
31
return js;
32
}
33
+ if (arg2 == 0xff00) {
34
+ tcg_out_modrm(s, OPC_TESTB, arg1 + 4, arg1 + 4);
35
+ return jz;
36
+ }
37
tcg_out_modrm(s, OPC_GRP3_Eb, EXT3_TESTi, arg1 + 4);
38
tcg_out8(s, arg2 >> 8);
39
return jz;
40
}
41
42
+ if (arg2 == 0xffff) {
43
+ tcg_out_modrm(s, OPC_TESTL | P_DATA16, arg1, arg1);
44
+ return jz;
45
+ }
46
+ if (arg2 == 0xffffffffu) {
47
+ tcg_out_modrm(s, OPC_TESTL, arg1, arg1);
48
+ return jz;
49
+ }
50
+
51
if (is_power_of_2(rexw ? arg2 : (uint32_t)arg2)) {
52
int jc = (cond == TCG_COND_TSTNE ? JCC_JB : JCC_JAE);
53
int sh = ctz64(arg2);
54
--
55
2.34.1
56
57
diff view generated by jsdifflib
Deleted patch
1
Use a non-zero value here (an illegal encoding) as a better
2
condition than is_unsigned_cond for when MOVR/BPR is usable.
3
1
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
tcg/sparc64/tcg-target.c.inc | 25 ++++++++++++++-----------
8
1 file changed, 14 insertions(+), 11 deletions(-)
9
10
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/sparc64/tcg-target.c.inc
13
+++ b/tcg/sparc64/tcg-target.c.inc
14
@@ -XXX,XX +XXX,XX @@ static const uint8_t tcg_cond_to_bcond[] = {
15
[TCG_COND_GTU] = COND_GU,
16
};
17
18
-static const uint8_t tcg_cond_to_rcond[] = {
19
+static const uint8_t tcg_cond_to_rcond[16] = {
20
[TCG_COND_EQ] = RCOND_Z,
21
[TCG_COND_NE] = RCOND_NZ,
22
[TCG_COND_LT] = RCOND_LZ,
23
@@ -XXX,XX +XXX,XX @@ static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGReg arg1,
24
int32_t arg2, int const_arg2, TCGLabel *l)
25
{
26
/* For 64-bit signed comparisons vs zero, we can avoid the compare. */
27
- if (arg2 == 0 && !is_unsigned_cond(cond)) {
28
+ int rcond = tcg_cond_to_rcond[cond];
29
+ if (arg2 == 0 && rcond) {
30
int off16 = 0;
31
32
if (l->has_value) {
33
@@ -XXX,XX +XXX,XX @@ static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGReg arg1,
34
tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP16, l, 0);
35
}
36
tcg_out32(s, INSN_OP(0) | INSN_OP2(3) | BPR_PT | INSN_RS1(arg1)
37
- | INSN_COND(tcg_cond_to_rcond[cond]) | off16);
38
+ | INSN_COND(rcond) | off16);
39
} else {
40
tcg_out_cmp(s, arg1, arg2, const_arg2);
41
tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_XCC | BPCC_PT, l);
42
@@ -XXX,XX +XXX,XX @@ static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGReg arg1,
43
tcg_out_nop(s);
44
}
45
46
-static void tcg_out_movr(TCGContext *s, TCGCond cond, TCGReg ret, TCGReg c1,
47
+static void tcg_out_movr(TCGContext *s, int rcond, TCGReg ret, TCGReg c1,
48
int32_t v1, int v1const)
49
{
50
- tcg_out32(s, ARITH_MOVR | INSN_RD(ret) | INSN_RS1(c1)
51
- | (tcg_cond_to_rcond[cond] << 10)
52
+ tcg_out32(s, ARITH_MOVR | INSN_RD(ret) | INSN_RS1(c1) | (rcond << 10)
53
| (v1const ? INSN_IMM10(v1) : INSN_RS2(v1)));
54
}
55
56
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
57
/* For 64-bit signed comparisons vs zero, we can avoid the compare.
58
Note that the immediate range is one bit smaller, so we must check
59
for that as well. */
60
- if (c2 == 0 && !is_unsigned_cond(cond)
61
- && (!v1const || check_fit_i32(v1, 10))) {
62
- tcg_out_movr(s, cond, ret, c1, v1, v1const);
63
+ int rcond = tcg_cond_to_rcond[cond];
64
+ if (c2 == 0 && rcond && (!v1const || check_fit_i32(v1, 10))) {
65
+ tcg_out_movr(s, rcond, ret, c1, v1, v1const);
66
} else {
67
tcg_out_cmp(s, c1, c2, c2const);
68
tcg_out_movcc(s, cond, MOVCC_XCC, ret, v1, v1const);
69
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGReg ret,
70
static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
71
TCGReg c1, int32_t c2, int c2const, bool neg)
72
{
73
+ int rcond;
74
+
75
if (use_vis3_instructions && !neg) {
76
switch (cond) {
77
case TCG_COND_NE:
78
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
79
80
/* For 64-bit signed comparisons vs zero, we can avoid the compare
81
if the input does not overlap the output. */
82
- if (c2 == 0 && !is_unsigned_cond(cond) && c1 != ret) {
83
+ rcond = tcg_cond_to_rcond[cond];
84
+ if (c2 == 0 && rcond && c1 != ret) {
85
tcg_out_movi_s13(s, ret, 0);
86
- tcg_out_movr(s, cond, ret, c1, neg ? -1 : 1, 1);
87
+ tcg_out_movr(s, rcond, ret, c1, neg ? -1 : 1, 1);
88
} else {
89
tcg_out_cmp(s, c1, c2, c2const);
90
tcg_out_movi_s13(s, ret, 0);
91
--
92
2.34.1
93
94
diff view generated by jsdifflib
Deleted patch
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
tcg/sparc64/tcg-target.c.inc | 21 +++++++++++----------
5
1 file changed, 11 insertions(+), 10 deletions(-)
6
1
7
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
8
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/sparc64/tcg-target.c.inc
10
+++ b/tcg/sparc64/tcg-target.c.inc
11
@@ -XXX,XX +XXX,XX @@ static void tcg_out_bpcc(TCGContext *s, int scond, int flags, TCGLabel *l)
12
tcg_out_bpcc0(s, scond, flags, off19);
13
}
14
15
-static void tcg_out_cmp(TCGContext *s, TCGReg c1, int32_t c2, int c2const)
16
+static void tcg_out_cmp(TCGContext *s, TCGCond cond,
17
+ TCGReg c1, int32_t c2, int c2const)
18
{
19
tcg_out_arithc(s, TCG_REG_G0, c1, c2, c2const, ARITH_SUBCC);
20
}
21
@@ -XXX,XX +XXX,XX @@ static void tcg_out_cmp(TCGContext *s, TCGReg c1, int32_t c2, int c2const)
22
static void tcg_out_brcond_i32(TCGContext *s, TCGCond cond, TCGReg arg1,
23
int32_t arg2, int const_arg2, TCGLabel *l)
24
{
25
- tcg_out_cmp(s, arg1, arg2, const_arg2);
26
+ tcg_out_cmp(s, cond, arg1, arg2, const_arg2);
27
tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_ICC | BPCC_PT, l);
28
tcg_out_nop(s);
29
}
30
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movcond_i32(TCGContext *s, TCGCond cond, TCGReg ret,
31
TCGReg c1, int32_t c2, int c2const,
32
int32_t v1, int v1const)
33
{
34
- tcg_out_cmp(s, c1, c2, c2const);
35
+ tcg_out_cmp(s, cond, c1, c2, c2const);
36
tcg_out_movcc(s, cond, MOVCC_ICC, ret, v1, v1const);
37
}
38
39
@@ -XXX,XX +XXX,XX @@ static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGReg arg1,
40
tcg_out32(s, INSN_OP(0) | INSN_OP2(3) | BPR_PT | INSN_RS1(arg1)
41
| INSN_COND(rcond) | off16);
42
} else {
43
- tcg_out_cmp(s, arg1, arg2, const_arg2);
44
+ tcg_out_cmp(s, cond, arg1, arg2, const_arg2);
45
tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_XCC | BPCC_PT, l);
46
}
47
tcg_out_nop(s);
48
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
49
if (c2 == 0 && rcond && (!v1const || check_fit_i32(v1, 10))) {
50
tcg_out_movr(s, rcond, ret, c1, v1, v1const);
51
} else {
52
- tcg_out_cmp(s, c1, c2, c2const);
53
+ tcg_out_cmp(s, cond, c1, c2, c2const);
54
tcg_out_movcc(s, cond, MOVCC_XCC, ret, v1, v1const);
55
}
56
}
57
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGReg ret,
58
/* FALLTHRU */
59
60
default:
61
- tcg_out_cmp(s, c1, c2, c2const);
62
+ tcg_out_cmp(s, cond, c1, c2, c2const);
63
tcg_out_movi_s13(s, ret, 0);
64
tcg_out_movcc(s, cond, MOVCC_ICC, ret, neg ? -1 : 1, 1);
65
return;
66
}
67
68
- tcg_out_cmp(s, c1, c2, c2const);
69
+ tcg_out_cmp(s, cond, c1, c2, c2const);
70
if (cond == TCG_COND_LTU) {
71
if (neg) {
72
/* 0 - 0 - C = -C = (C ? -1 : 0) */
73
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
74
c2 = c1, c2const = 0, c1 = TCG_REG_G0;
75
/* FALLTHRU */
76
case TCG_COND_LTU:
77
- tcg_out_cmp(s, c1, c2, c2const);
78
+ tcg_out_cmp(s, cond, c1, c2, c2const);
79
tcg_out_arith(s, ret, TCG_REG_G0, TCG_REG_G0, ARITH_ADDXC);
80
return;
81
default:
82
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
83
tcg_out_movi_s13(s, ret, 0);
84
tcg_out_movr(s, rcond, ret, c1, neg ? -1 : 1, 1);
85
} else {
86
- tcg_out_cmp(s, c1, c2, c2const);
87
+ tcg_out_cmp(s, cond, c1, c2, c2const);
88
tcg_out_movi_s13(s, ret, 0);
89
tcg_out_movcc(s, cond, MOVCC_XCC, ret, neg ? -1 : 1, 1);
90
}
91
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
92
tcg_out_movi_s32(s, TCG_REG_T3, compare_mask);
93
tcg_out_arith(s, TCG_REG_T3, addr_reg, TCG_REG_T3, ARITH_AND);
94
}
95
- tcg_out_cmp(s, TCG_REG_T2, TCG_REG_T3, 0);
96
+ tcg_out_cmp(s, TCG_COND_NE, TCG_REG_T2, TCG_REG_T3, 0);
97
98
ldst = new_ldst_label(s);
99
ldst->is_ld = is_ld;
100
--
101
2.34.1
102
103
diff view generated by jsdifflib
Deleted patch
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
tcg/sparc64/tcg-target.h | 2 +-
5
tcg/sparc64/tcg-target.c.inc | 16 ++++++++++++++--
6
2 files changed, 15 insertions(+), 3 deletions(-)
7
1
8
diff --git a/tcg/sparc64/tcg-target.h b/tcg/sparc64/tcg-target.h
9
index XXXXXXX..XXXXXXX 100644
10
--- a/tcg/sparc64/tcg-target.h
11
+++ b/tcg/sparc64/tcg-target.h
12
@@ -XXX,XX +XXX,XX @@ extern bool use_vis3_instructions;
13
14
#define TCG_TARGET_HAS_qemu_ldst_i128 0
15
16
-#define TCG_TARGET_HAS_tst 0
17
+#define TCG_TARGET_HAS_tst 1
18
19
#define TCG_AREG0 TCG_REG_I0
20
21
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
22
index XXXXXXX..XXXXXXX 100644
23
--- a/tcg/sparc64/tcg-target.c.inc
24
+++ b/tcg/sparc64/tcg-target.c.inc
25
@@ -XXX,XX +XXX,XX @@ static void tcg_out_div32(TCGContext *s, TCGReg rd, TCGReg rs1,
26
uns ? ARITH_UDIV : ARITH_SDIV);
27
}
28
29
-static const uint8_t tcg_cond_to_bcond[] = {
30
+static const uint8_t tcg_cond_to_bcond[16] = {
31
[TCG_COND_EQ] = COND_E,
32
[TCG_COND_NE] = COND_NE,
33
+ [TCG_COND_TSTEQ] = COND_E,
34
+ [TCG_COND_TSTNE] = COND_NE,
35
[TCG_COND_LT] = COND_L,
36
[TCG_COND_GE] = COND_GE,
37
[TCG_COND_LE] = COND_LE,
38
@@ -XXX,XX +XXX,XX @@ static void tcg_out_bpcc(TCGContext *s, int scond, int flags, TCGLabel *l)
39
static void tcg_out_cmp(TCGContext *s, TCGCond cond,
40
TCGReg c1, int32_t c2, int c2const)
41
{
42
- tcg_out_arithc(s, TCG_REG_G0, c1, c2, c2const, ARITH_SUBCC);
43
+ tcg_out_arithc(s, TCG_REG_G0, c1, c2, c2const,
44
+ is_tst_cond(cond) ? ARITH_ANDCC : ARITH_SUBCC);
45
}
46
47
static void tcg_out_brcond_i32(TCGContext *s, TCGCond cond, TCGReg arg1,
48
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGReg ret,
49
cond = (cond == TCG_COND_EQ ? TCG_COND_GEU : TCG_COND_LTU);
50
    break;
51
52
+ case TCG_COND_TSTEQ:
53
+ case TCG_COND_TSTNE:
54
+ /* Transform to inequality vs zero. */
55
+ tcg_out_arithc(s, TCG_REG_T1, c1, c2, c2const, ARITH_AND);
56
+ c1 = TCG_REG_G0;
57
+ c2 = TCG_REG_T1, c2const = 0;
58
+ cond = (cond == TCG_COND_TSTEQ ? TCG_COND_GEU : TCG_COND_LTU);
59
+    break;
60
+
61
case TCG_COND_GTU:
62
case TCG_COND_LEU:
63
/* If we don't need to load a constant into a register, we can
64
--
65
2.34.1
66
67
diff view generated by jsdifflib
Deleted patch
1
Rename the current tcg_out_bc function to tcg_out_bc_lab, and
2
create a new function that takes an integer displacement + link.
3
1
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
tcg/ppc/tcg-target.c.inc | 28 +++++++++++++++++-----------
8
1 file changed, 17 insertions(+), 11 deletions(-)
9
10
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/ppc/tcg-target.c.inc
13
+++ b/tcg/ppc/tcg-target.c.inc
14
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
15
}
16
}
17
18
-static void tcg_out_bc(TCGContext *s, int bc, TCGLabel *l)
19
+static void tcg_out_bc(TCGContext *s, TCGCond cond, int bd)
20
{
21
+ tcg_out32(s, tcg_to_bc[cond] | bd);
22
+}
23
+
24
+static void tcg_out_bc_lab(TCGContext *s, TCGCond cond, TCGLabel *l)
25
+{
26
+ int bd = 0;
27
if (l->has_value) {
28
- bc |= reloc_pc14_val(tcg_splitwx_to_rx(s->code_ptr), l->u.value_ptr);
29
+ bd = reloc_pc14_val(tcg_splitwx_to_rx(s->code_ptr), l->u.value_ptr);
30
} else {
31
tcg_out_reloc(s, s->code_ptr, R_PPC_REL14, l, 0);
32
}
33
- tcg_out32(s, bc);
34
+ tcg_out_bc(s, cond, bd);
35
}
36
37
static void tcg_out_brcond(TCGContext *s, TCGCond cond,
38
@@ -XXX,XX +XXX,XX @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond,
39
TCGLabel *l, TCGType type)
40
{
41
tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
42
- tcg_out_bc(s, tcg_to_bc[cond], l);
43
+ tcg_out_bc_lab(s, cond, l);
44
}
45
46
static void tcg_out_movcond(TCGContext *s, TCGType type, TCGCond cond,
47
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movcond(TCGContext *s, TCGType type, TCGCond cond,
48
}
49
}
50
/* Branch forward over one insn */
51
- tcg_out32(s, tcg_to_bc[cond] | 8);
52
+ tcg_out_bc(s, cond, 8);
53
if (v2 == 0) {
54
tcg_out_movi(s, type, dest, 0);
55
} else {
56
@@ -XXX,XX +XXX,XX @@ static void tcg_out_cntxz(TCGContext *s, TCGType type, uint32_t opc,
57
tcg_out32(s, opc | RA(TCG_REG_R0) | RS(a1));
58
tcg_out32(s, tcg_to_isel[TCG_COND_EQ] | TAB(a0, a2, TCG_REG_R0));
59
} else if (!const_a2 && a0 == a2) {
60
- tcg_out32(s, tcg_to_bc[TCG_COND_EQ] | 8);
61
+ tcg_out_bc(s, TCG_COND_EQ, 8);
62
tcg_out32(s, opc | RA(a0) | RS(a1));
63
} else {
64
tcg_out32(s, opc | RA(a0) | RS(a1));
65
- tcg_out32(s, tcg_to_bc[TCG_COND_NE] | 8);
66
+ tcg_out_bc(s, TCG_COND_NE, 8);
67
if (const_a2) {
68
tcg_out_movi(s, type, a0, 0);
69
} else {
70
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
71
tcg_out_rlw(s, RLWINM, args[0], TCG_REG_R0, 31, 31, 31);
72
}
73
74
-static void tcg_out_brcond2 (TCGContext *s, const TCGArg *args,
75
- const int *const_args)
76
+static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
77
+ const int *const_args)
78
{
79
tcg_out_cmp2(s, args, const_args);
80
- tcg_out_bc(s, BC | BI(7, CR_EQ) | BO_COND_TRUE, arg_label(args[5]));
81
+ tcg_out_bc_lab(s, TCG_COND_EQ, arg_label(args[5]));
82
}
83
84
static void tcg_out_mb(TCGContext *s, TCGArg a0)
85
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
86
87
/* Load a pointer into the current opcode w/conditional branch-link. */
88
ldst->label_ptr[0] = s->code_ptr;
89
- tcg_out32(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK);
90
+ tcg_out_bc(s, TCG_COND_NE, LK);
91
92
h->base = TCG_REG_TMP1;
93
} else {
94
--
95
2.34.1
96
97
diff view generated by jsdifflib
Deleted patch
1
Using cr0 means we could choose to use rc=1 to compute the condition.
2
Adjust the tables and tcg_out_cmp that feeds them.
3
1
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
tcg/ppc/tcg-target.c.inc | 68 ++++++++++++++++++++--------------------
8
1 file changed, 34 insertions(+), 34 deletions(-)
9
10
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/ppc/tcg-target.c.inc
13
+++ b/tcg/ppc/tcg-target.c.inc
14
@@ -XXX,XX +XXX,XX @@ enum {
15
};
16
17
static const uint32_t tcg_to_bc[] = {
18
- [TCG_COND_EQ] = BC | BI(7, CR_EQ) | BO_COND_TRUE,
19
- [TCG_COND_NE] = BC | BI(7, CR_EQ) | BO_COND_FALSE,
20
- [TCG_COND_LT] = BC | BI(7, CR_LT) | BO_COND_TRUE,
21
- [TCG_COND_GE] = BC | BI(7, CR_LT) | BO_COND_FALSE,
22
- [TCG_COND_LE] = BC | BI(7, CR_GT) | BO_COND_FALSE,
23
- [TCG_COND_GT] = BC | BI(7, CR_GT) | BO_COND_TRUE,
24
- [TCG_COND_LTU] = BC | BI(7, CR_LT) | BO_COND_TRUE,
25
- [TCG_COND_GEU] = BC | BI(7, CR_LT) | BO_COND_FALSE,
26
- [TCG_COND_LEU] = BC | BI(7, CR_GT) | BO_COND_FALSE,
27
- [TCG_COND_GTU] = BC | BI(7, CR_GT) | BO_COND_TRUE,
28
+ [TCG_COND_EQ] = BC | BI(0, CR_EQ) | BO_COND_TRUE,
29
+ [TCG_COND_NE] = BC | BI(0, CR_EQ) | BO_COND_FALSE,
30
+ [TCG_COND_LT] = BC | BI(0, CR_LT) | BO_COND_TRUE,
31
+ [TCG_COND_GE] = BC | BI(0, CR_LT) | BO_COND_FALSE,
32
+ [TCG_COND_LE] = BC | BI(0, CR_GT) | BO_COND_FALSE,
33
+ [TCG_COND_GT] = BC | BI(0, CR_GT) | BO_COND_TRUE,
34
+ [TCG_COND_LTU] = BC | BI(0, CR_LT) | BO_COND_TRUE,
35
+ [TCG_COND_GEU] = BC | BI(0, CR_LT) | BO_COND_FALSE,
36
+ [TCG_COND_LEU] = BC | BI(0, CR_GT) | BO_COND_FALSE,
37
+ [TCG_COND_GTU] = BC | BI(0, CR_GT) | BO_COND_TRUE,
38
};
39
40
/* The low bit here is set if the RA and RB fields must be inverted. */
41
static const uint32_t tcg_to_isel[] = {
42
- [TCG_COND_EQ] = ISEL | BC_(7, CR_EQ),
43
- [TCG_COND_NE] = ISEL | BC_(7, CR_EQ) | 1,
44
- [TCG_COND_LT] = ISEL | BC_(7, CR_LT),
45
- [TCG_COND_GE] = ISEL | BC_(7, CR_LT) | 1,
46
- [TCG_COND_LE] = ISEL | BC_(7, CR_GT) | 1,
47
- [TCG_COND_GT] = ISEL | BC_(7, CR_GT),
48
- [TCG_COND_LTU] = ISEL | BC_(7, CR_LT),
49
- [TCG_COND_GEU] = ISEL | BC_(7, CR_LT) | 1,
50
- [TCG_COND_LEU] = ISEL | BC_(7, CR_GT) | 1,
51
- [TCG_COND_GTU] = ISEL | BC_(7, CR_GT),
52
+ [TCG_COND_EQ] = ISEL | BC_(0, CR_EQ),
53
+ [TCG_COND_NE] = ISEL | BC_(0, CR_EQ) | 1,
54
+ [TCG_COND_LT] = ISEL | BC_(0, CR_LT),
55
+ [TCG_COND_GE] = ISEL | BC_(0, CR_LT) | 1,
56
+ [TCG_COND_LE] = ISEL | BC_(0, CR_GT) | 1,
57
+ [TCG_COND_GT] = ISEL | BC_(0, CR_GT),
58
+ [TCG_COND_LTU] = ISEL | BC_(0, CR_LT),
59
+ [TCG_COND_GEU] = ISEL | BC_(0, CR_LT) | 1,
60
+ [TCG_COND_LEU] = ISEL | BC_(0, CR_GT) | 1,
61
+ [TCG_COND_GTU] = ISEL | BC_(0, CR_GT),
62
};
63
64
static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
65
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
66
if (have_isa_3_10) {
67
tcg_insn_unit bi, opc;
68
69
- tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
70
+ tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 0, type);
71
72
/* Re-use tcg_to_bc for BI and BO_COND_{TRUE,FALSE}. */
73
bi = tcg_to_bc[cond] & (0x1f << 16);
74
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
75
if (have_isel) {
76
int isel, tab;
77
78
- tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
79
+ tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 0, type);
80
81
isel = tcg_to_isel[cond];
82
83
@@ -XXX,XX +XXX,XX @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond,
84
TCGArg arg1, TCGArg arg2, int const_arg2,
85
TCGLabel *l, TCGType type)
86
{
87
- tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
88
+ tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 0, type);
89
tcg_out_bc_lab(s, cond, l);
90
}
91
92
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movcond(TCGContext *s, TCGType type, TCGCond cond,
93
return;
94
}
95
96
- tcg_out_cmp(s, cond, c1, c2, const_c2, 7, type);
97
+ tcg_out_cmp(s, cond, c1, c2, const_c2, 0, type);
98
99
if (have_isel) {
100
int isel = tcg_to_isel[cond];
101
@@ -XXX,XX +XXX,XX @@ static void tcg_out_cntxz(TCGContext *s, TCGType type, uint32_t opc,
102
if (const_a2 && a2 == (type == TCG_TYPE_I32 ? 32 : 64)) {
103
tcg_out32(s, opc | RA(a0) | RS(a1));
104
} else {
105
- tcg_out_cmp(s, TCG_COND_EQ, a1, 0, 1, 7, type);
106
+ tcg_out_cmp(s, TCG_COND_EQ, a1, 0, 1, 0, type);
107
/* Note that the only other valid constant for a2 is 0. */
108
if (have_isel) {
109
tcg_out32(s, opc | RA(TCG_REG_R0) | RS(a1));
110
@@ -XXX,XX +XXX,XX @@ static void tcg_out_cmp2(TCGContext *s, const TCGArg *args,
111
do_equality:
112
tcg_out_cmp(s, cond, al, bl, blconst, 6, TCG_TYPE_I32);
113
tcg_out_cmp(s, cond, ah, bh, bhconst, 7, TCG_TYPE_I32);
114
- tcg_out32(s, op | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
115
+ tcg_out32(s, op | BT(0, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
116
break;
117
118
case TCG_COND_LT:
119
@@ -XXX,XX +XXX,XX @@ static void tcg_out_cmp2(TCGContext *s, const TCGArg *args,
120
121
tcg_out_cmp(s, cond, ah, bh, bhconst, 6, TCG_TYPE_I32);
122
tcg_out_cmp(s, cond2, al, bl, blconst, 7, TCG_TYPE_I32);
123
- tcg_out32(s, op | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, bit2));
124
- tcg_out32(s, CROR | BT(7, CR_EQ) | BA(6, bit1) | BB(7, CR_EQ));
125
+ tcg_out32(s, op | BT(0, CR_EQ) | BA(6, CR_EQ) | BB(7, bit2));
126
+ tcg_out32(s, CROR | BT(0, CR_EQ) | BA(6, bit1) | BB(0, CR_EQ));
127
break;
128
129
default:
130
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
131
const int *const_args)
132
{
133
tcg_out_cmp2(s, args + 1, const_args + 1);
134
- tcg_out32(s, MFOCRF | RT(TCG_REG_R0) | FXM(7));
135
- tcg_out_rlw(s, RLWINM, args[0], TCG_REG_R0, 31, 31, 31);
136
+ tcg_out32(s, MFOCRF | RT(TCG_REG_R0) | FXM(0));
137
+ tcg_out_rlw(s, RLWINM, args[0], TCG_REG_R0, CR_EQ + 0*4 + 1, 31, 31);
138
}
139
140
static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
141
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
142
tcg_out_cmp(s, TCG_COND_EQ, addrhi, TCG_REG_TMP2,
143
0, 6, TCG_TYPE_I32);
144
145
- /* Combine comparisons into cr7. */
146
- tcg_out32(s, CRAND | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
147
+ /* Combine comparisons into cr0. */
148
+ tcg_out32(s, CRAND | BT(0, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
149
} else {
150
- /* Full comparison into cr7. */
151
+ /* Full comparison into cr0. */
152
tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP2,
153
- 0, 7, addr_type);
154
+ 0, 0, addr_type);
155
}
156
157
/* Load a pointer into the current opcode w/conditional branch-link. */
158
--
159
2.34.1
160
161
diff view generated by jsdifflib
Deleted patch
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
tcg/ppc/tcg-target.c.inc | 27 ++++++++++++++++-----------
5
1 file changed, 16 insertions(+), 11 deletions(-)
6
1
7
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
8
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/ppc/tcg-target.c.inc
10
+++ b/tcg/ppc/tcg-target.c.inc
11
@@ -XXX,XX +XXX,XX @@ static bool reloc_pc34(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
12
}
13
14
/* test if a constant matches the constraint */
15
-static bool tcg_target_const_match(int64_t val, int ct,
16
+static bool tcg_target_const_match(int64_t sval, int ct,
17
TCGType type, TCGCond cond, int vece)
18
{
19
+ uint64_t uval = sval;
20
+
21
if (ct & TCG_CT_CONST) {
22
return 1;
23
}
24
25
- /* The only 32-bit constraint we use aside from
26
- TCG_CT_CONST is TCG_CT_CONST_S16. */
27
if (type == TCG_TYPE_I32) {
28
- val = (int32_t)val;
29
+ uval = (uint32_t)sval;
30
+ sval = (int32_t)sval;
31
}
32
33
- if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
34
+ if ((ct & TCG_CT_CONST_S16) && sval == (int16_t)sval) {
35
return 1;
36
- } else if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
37
+ }
38
+ if ((ct & TCG_CT_CONST_S32) && sval == (int32_t)sval) {
39
return 1;
40
- } else if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
41
+ }
42
+ if ((ct & TCG_CT_CONST_U32) && uval == (uint32_t)uval) {
43
return 1;
44
- } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
45
+ }
46
+ if ((ct & TCG_CT_CONST_ZERO) && sval == 0) {
47
return 1;
48
- } else if ((ct & TCG_CT_CONST_MONE) && val == -1) {
49
+ }
50
+ if ((ct & TCG_CT_CONST_MONE) && sval == -1) {
51
return 1;
52
- } else if ((ct & TCG_CT_CONST_WSZ)
53
- && val == (type == TCG_TYPE_I32 ? 32 : 64)) {
54
+ }
55
+ if ((ct & TCG_CT_CONST_WSZ) && sval == (type == TCG_TYPE_I32 ? 32 : 64)) {
56
return 1;
57
}
58
return 0;
59
--
60
2.34.1
61
62
diff view generated by jsdifflib
Deleted patch
1
Better constraint for tcg_out_cmp, based on the comparison.
2
We can't yet remove the fallback to load constants into a
3
scratch because of tcg_out_cmp2, but that path should not
4
be as frequent.
5
1
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
9
tcg/ppc/tcg-target-con-set.h | 5 ++--
10
tcg/ppc/tcg-target-con-str.h | 1 +
11
tcg/ppc/tcg-target.c.inc | 48 ++++++++++++++++++++++++++++++------
12
3 files changed, 44 insertions(+), 10 deletions(-)
13
14
diff --git a/tcg/ppc/tcg-target-con-set.h b/tcg/ppc/tcg-target-con-set.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tcg/ppc/tcg-target-con-set.h
17
+++ b/tcg/ppc/tcg-target-con-set.h
18
@@ -XXX,XX +XXX,XX @@
19
*/
20
C_O0_I1(r)
21
C_O0_I2(r, r)
22
-C_O0_I2(r, ri)
23
+C_O0_I2(r, rC)
24
C_O0_I2(v, r)
25
C_O0_I3(r, r, r)
26
C_O0_I3(o, m, r)
27
@@ -XXX,XX +XXX,XX @@ C_O1_I2(r, rI, ri)
28
C_O1_I2(r, rI, rT)
29
C_O1_I2(r, r, r)
30
C_O1_I2(r, r, ri)
31
+C_O1_I2(r, r, rC)
32
C_O1_I2(r, r, rI)
33
C_O1_I2(r, r, rT)
34
C_O1_I2(r, r, rU)
35
C_O1_I2(r, r, rZW)
36
C_O1_I2(v, v, v)
37
C_O1_I3(v, v, v, v)
38
-C_O1_I4(r, r, ri, rZ, rZ)
39
+C_O1_I4(r, r, rC, rZ, rZ)
40
C_O1_I4(r, r, r, ri, ri)
41
C_O2_I1(r, r, r)
42
C_N1O1_I1(o, m, r)
43
diff --git a/tcg/ppc/tcg-target-con-str.h b/tcg/ppc/tcg-target-con-str.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/tcg/ppc/tcg-target-con-str.h
46
+++ b/tcg/ppc/tcg-target-con-str.h
47
@@ -XXX,XX +XXX,XX @@ REGS('v', ALL_VECTOR_REGS)
48
* Define constraint letters for constants:
49
* CONST(letter, TCG_CT_CONST_* bit set)
50
*/
51
+CONST('C', TCG_CT_CONST_CMP)
52
CONST('I', TCG_CT_CONST_S16)
53
CONST('M', TCG_CT_CONST_MONE)
54
CONST('T', TCG_CT_CONST_S32)
55
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
56
index XXXXXXX..XXXXXXX 100644
57
--- a/tcg/ppc/tcg-target.c.inc
58
+++ b/tcg/ppc/tcg-target.c.inc
59
@@ -XXX,XX +XXX,XX @@
60
#define SZR (TCG_TARGET_REG_BITS / 8)
61
62
#define TCG_CT_CONST_S16 0x100
63
+#define TCG_CT_CONST_U16 0x200
64
#define TCG_CT_CONST_S32 0x400
65
#define TCG_CT_CONST_U32 0x800
66
#define TCG_CT_CONST_ZERO 0x1000
67
#define TCG_CT_CONST_MONE 0x2000
68
#define TCG_CT_CONST_WSZ 0x4000
69
+#define TCG_CT_CONST_CMP 0x8000
70
71
#define ALL_GENERAL_REGS 0xffffffffu
72
#define ALL_VECTOR_REGS 0xffffffff00000000ull
73
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t sval, int ct,
74
sval = (int32_t)sval;
75
}
76
77
+ if (ct & TCG_CT_CONST_CMP) {
78
+ switch (cond) {
79
+ case TCG_COND_EQ:
80
+ case TCG_COND_NE:
81
+ ct |= TCG_CT_CONST_S16 | TCG_CT_CONST_U16;
82
+ break;
83
+ case TCG_COND_LT:
84
+ case TCG_COND_GE:
85
+ case TCG_COND_LE:
86
+ case TCG_COND_GT:
87
+ ct |= TCG_CT_CONST_S16;
88
+ break;
89
+ case TCG_COND_LTU:
90
+ case TCG_COND_GEU:
91
+ case TCG_COND_LEU:
92
+ case TCG_COND_GTU:
93
+ ct |= TCG_CT_CONST_U16;
94
+ break;
95
+ default:
96
+ g_assert_not_reached();
97
+ }
98
+ }
99
+
100
if ((ct & TCG_CT_CONST_S16) && sval == (int16_t)sval) {
101
return 1;
102
}
103
+ if ((ct & TCG_CT_CONST_U16) && uval == (uint16_t)uval) {
104
+ return 1;
105
+ }
106
if ((ct & TCG_CT_CONST_S32) && sval == (int32_t)sval) {
107
return 1;
108
}
109
@@ -XXX,XX +XXX,XX @@ static void tcg_out_cmp(TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
110
111
tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
112
113
- /* Simplify the comparisons below wrt CMPI. */
114
+ /*
115
+ * Simplify the comparisons below wrt CMPI.
116
+ * All of the tests are 16-bit, so a 32-bit sign extend always works.
117
+ */
118
if (type == TCG_TYPE_I32) {
119
arg2 = (int32_t)arg2;
120
}
121
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
122
case INDEX_op_sar_i32:
123
case INDEX_op_rotl_i32:
124
case INDEX_op_rotr_i32:
125
- case INDEX_op_setcond_i32:
126
- case INDEX_op_negsetcond_i32:
127
case INDEX_op_and_i64:
128
case INDEX_op_andc_i64:
129
case INDEX_op_shl_i64:
130
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
131
case INDEX_op_sar_i64:
132
case INDEX_op_rotl_i64:
133
case INDEX_op_rotr_i64:
134
- case INDEX_op_setcond_i64:
135
- case INDEX_op_negsetcond_i64:
136
return C_O1_I2(r, r, ri);
137
138
case INDEX_op_mul_i32:
139
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
140
141
case INDEX_op_brcond_i32:
142
case INDEX_op_brcond_i64:
143
- return C_O0_I2(r, ri);
144
-
145
+ return C_O0_I2(r, rC);
146
+ case INDEX_op_setcond_i32:
147
+ case INDEX_op_setcond_i64:
148
+ case INDEX_op_negsetcond_i32:
149
+ case INDEX_op_negsetcond_i64:
150
+ return C_O1_I2(r, r, rC);
151
case INDEX_op_movcond_i32:
152
case INDEX_op_movcond_i64:
153
- return C_O1_I4(r, r, ri, rZ, rZ);
154
+ return C_O1_I4(r, r, rC, rZ, rZ);
155
+
156
case INDEX_op_deposit_i32:
157
case INDEX_op_deposit_i64:
158
return C_O1_I2(r, 0, rZ);
159
--
160
2.34.1
161
162
diff view generated by jsdifflib
Deleted patch
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
tcg/ppc/tcg-target.h | 2 +-
5
tcg/ppc/tcg-target.c.inc | 122 ++++++++++++++++++++++++++++++++++++---
6
2 files changed, 115 insertions(+), 9 deletions(-)
7
1
8
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
9
index XXXXXXX..XXXXXXX 100644
10
--- a/tcg/ppc/tcg-target.h
11
+++ b/tcg/ppc/tcg-target.h
12
@@ -XXX,XX +XXX,XX @@ typedef enum {
13
#define TCG_TARGET_HAS_qemu_ldst_i128 \
14
(TCG_TARGET_REG_BITS == 64 && have_isa_2_07)
15
16
-#define TCG_TARGET_HAS_tst 0
17
+#define TCG_TARGET_HAS_tst 1
18
19
/*
20
* While technically Altivec could support V64, it has no 64-bit store
21
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
22
index XXXXXXX..XXXXXXX 100644
23
--- a/tcg/ppc/tcg-target.c.inc
24
+++ b/tcg/ppc/tcg-target.c.inc
25
@@ -XXX,XX +XXX,XX @@ static bool reloc_pc34(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
26
return false;
27
}
28
29
+static bool mask_operand(uint32_t c, int *mb, int *me);
30
+static bool mask64_operand(uint64_t c, int *mb, int *me);
31
+
32
/* test if a constant matches the constraint */
33
static bool tcg_target_const_match(int64_t sval, int ct,
34
TCGType type, TCGCond cond, int vece)
35
{
36
uint64_t uval = sval;
37
+ int mb, me;
38
39
if (ct & TCG_CT_CONST) {
40
return 1;
41
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t sval, int ct,
42
case TCG_COND_GTU:
43
ct |= TCG_CT_CONST_U16;
44
break;
45
+ case TCG_COND_TSTEQ:
46
+ case TCG_COND_TSTNE:
47
+ if ((uval & ~0xffff) == 0 || (uval & ~0xffff0000ull) == 0) {
48
+ return 1;
49
+ }
50
+ if (TCG_TARGET_REG_BITS == 32 || type == TCG_TYPE_I32
51
+ ? mask_operand(uval, &mb, &me)
52
+ : mask64_operand(uval << clz64(uval), &mb, &me)) {
53
+ return 1;
54
+ }
55
+ return 0;
56
default:
57
g_assert_not_reached();
58
}
59
@@ -XXX,XX +XXX,XX @@ enum {
60
CR_SO
61
};
62
63
-static const uint32_t tcg_to_bc[] = {
64
+static const uint32_t tcg_to_bc[16] = {
65
[TCG_COND_EQ] = BC | BI(0, CR_EQ) | BO_COND_TRUE,
66
[TCG_COND_NE] = BC | BI(0, CR_EQ) | BO_COND_FALSE,
67
+ [TCG_COND_TSTEQ] = BC | BI(0, CR_EQ) | BO_COND_TRUE,
68
+ [TCG_COND_TSTNE] = BC | BI(0, CR_EQ) | BO_COND_FALSE,
69
[TCG_COND_LT] = BC | BI(0, CR_LT) | BO_COND_TRUE,
70
[TCG_COND_GE] = BC | BI(0, CR_LT) | BO_COND_FALSE,
71
[TCG_COND_LE] = BC | BI(0, CR_GT) | BO_COND_FALSE,
72
@@ -XXX,XX +XXX,XX @@ static const uint32_t tcg_to_bc[] = {
73
};
74
75
/* The low bit here is set if the RA and RB fields must be inverted. */
76
-static const uint32_t tcg_to_isel[] = {
77
+static const uint32_t tcg_to_isel[16] = {
78
[TCG_COND_EQ] = ISEL | BC_(0, CR_EQ),
79
[TCG_COND_NE] = ISEL | BC_(0, CR_EQ) | 1,
80
+ [TCG_COND_TSTEQ] = ISEL | BC_(0, CR_EQ),
81
+ [TCG_COND_TSTNE] = ISEL | BC_(0, CR_EQ) | 1,
82
[TCG_COND_LT] = ISEL | BC_(0, CR_LT),
83
[TCG_COND_GE] = ISEL | BC_(0, CR_LT) | 1,
84
[TCG_COND_LE] = ISEL | BC_(0, CR_GT) | 1,
85
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
86
return true;
87
}
88
89
-static inline void tcg_out_rld(TCGContext *s, int op, TCGReg ra, TCGReg rs,
90
- int sh, int mb)
91
+static void tcg_out_rld_rc(TCGContext *s, int op, TCGReg ra, TCGReg rs,
92
+ int sh, int mb, bool rc)
93
{
94
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
95
sh = SH(sh & 0x1f) | (((sh >> 5) & 1) << 1);
96
mb = MB64((mb >> 5) | ((mb << 1) & 0x3f));
97
- tcg_out32(s, op | RA(ra) | RS(rs) | sh | mb);
98
+ tcg_out32(s, op | RA(ra) | RS(rs) | sh | mb | rc);
99
}
100
101
-static inline void tcg_out_rlw(TCGContext *s, int op, TCGReg ra, TCGReg rs,
102
- int sh, int mb, int me)
103
+static void tcg_out_rld(TCGContext *s, int op, TCGReg ra, TCGReg rs,
104
+ int sh, int mb)
105
{
106
- tcg_out32(s, op | RA(ra) | RS(rs) | SH(sh) | MB(mb) | ME(me));
107
+ tcg_out_rld_rc(s, op, ra, rs, sh, mb, false);
108
+}
109
+
110
+static void tcg_out_rlw_rc(TCGContext *s, int op, TCGReg ra, TCGReg rs,
111
+ int sh, int mb, int me, bool rc)
112
+{
113
+ tcg_out32(s, op | RA(ra) | RS(rs) | SH(sh) | MB(mb) | ME(me) | rc);
114
+}
115
+
116
+static void tcg_out_rlw(TCGContext *s, int op, TCGReg ra, TCGReg rs,
117
+ int sh, int mb, int me)
118
+{
119
+ tcg_out_rlw_rc(s, op, ra, rs, sh, mb, me, false);
120
}
121
122
static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg dst, TCGReg src)
123
@@ -XXX,XX +XXX,XX @@ static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
124
return false;
125
}
126
127
+/*
128
+ * Set dest non-zero if and only if (arg1 & arg2) is non-zero.
129
+ * If RC, then also set RC0.
130
+ */
131
+static void tcg_out_test(TCGContext *s, TCGReg dest, TCGReg arg1, TCGArg arg2,
132
+ bool const_arg2, TCGType type, bool rc)
133
+{
134
+ int mb, me;
135
+
136
+ if (!const_arg2) {
137
+ tcg_out32(s, AND | SAB(arg1, dest, arg2) | rc);
138
+ return;
139
+ }
140
+
141
+ if (type == TCG_TYPE_I32) {
142
+ arg2 = (uint32_t)arg2;
143
+ } else if (arg2 == (uint32_t)arg2) {
144
+ type = TCG_TYPE_I32;
145
+ }
146
+
147
+ if ((arg2 & ~0xffff) == 0) {
148
+ tcg_out32(s, ANDI | SAI(arg1, dest, arg2));
149
+ return;
150
+ }
151
+ if ((arg2 & ~0xffff0000ull) == 0) {
152
+ tcg_out32(s, ANDIS | SAI(arg1, dest, arg2 >> 16));
153
+ return;
154
+ }
155
+ if (TCG_TARGET_REG_BITS == 32 || type == TCG_TYPE_I32) {
156
+ if (mask_operand(arg2, &mb, &me)) {
157
+ tcg_out_rlw_rc(s, RLWINM, dest, arg1, 0, mb, me, rc);
158
+ return;
159
+ }
160
+ } else {
161
+ int sh = clz64(arg2);
162
+ if (mask64_operand(arg2 << sh, &mb, &me)) {
163
+ tcg_out_rld_rc(s, RLDICR, dest, arg1, sh, me, rc);
164
+ return;
165
+ }
166
+ }
167
+ /* Constraints should satisfy this. */
168
+ g_assert_not_reached();
169
+}
170
+
171
static void tcg_out_cmp(TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
172
int const_arg2, int cr, TCGType type)
173
{
174
@@ -XXX,XX +XXX,XX @@ static void tcg_out_cmp(TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
175
imm = 0;
176
break;
177
178
+ case TCG_COND_TSTEQ:
179
+ case TCG_COND_TSTNE:
180
+ tcg_debug_assert(cr == 0);
181
+ tcg_out_test(s, TCG_REG_R0, arg1, arg2, const_arg2, type, true);
182
+ return;
183
+
184
case TCG_COND_LT:
185
case TCG_COND_GE:
186
case TCG_COND_LE:
187
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
188
tcg_out_setcond_ne0(s, type, arg0, arg1, neg);
189
break;
190
191
+ case TCG_COND_TSTEQ:
192
+ tcg_out_test(s, TCG_REG_R0, arg1, arg2, const_arg2, type, false);
193
+ tcg_out_setcond_eq0(s, type, arg0, TCG_REG_R0, neg);
194
+ break;
195
+
196
+ case TCG_COND_TSTNE:
197
+ tcg_out_test(s, TCG_REG_R0, arg1, arg2, const_arg2, type, false);
198
+ tcg_out_setcond_ne0(s, type, arg0, TCG_REG_R0, neg);
199
+ break;
200
+
201
case TCG_COND_LE:
202
case TCG_COND_LEU:
203
inv = true;
204
@@ -XXX,XX +XXX,XX @@ static void tcg_out_cmp2(TCGContext *s, const TCGArg *args,
205
tcg_out32(s, op | BT(0, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
206
break;
207
208
+ case TCG_COND_TSTEQ:
209
+ case TCG_COND_TSTNE:
210
+ if (blconst) {
211
+ tcg_out_andi32(s, TCG_REG_R0, al, bl);
212
+ } else {
213
+ tcg_out32(s, AND | SAB(al, TCG_REG_R0, bl));
214
+ }
215
+ if (bhconst) {
216
+ tcg_out_andi32(s, TCG_REG_TMP1, ah, bh);
217
+ } else {
218
+ tcg_out32(s, AND | SAB(ah, TCG_REG_TMP1, bh));
219
+ }
220
+ tcg_out32(s, OR | SAB(TCG_REG_R0, TCG_REG_R0, TCG_REG_TMP1) | 1);
221
+ break;
222
+
223
case TCG_COND_LT:
224
case TCG_COND_LE:
225
case TCG_COND_GT:
226
--
227
2.34.1
228
229
diff view generated by jsdifflib
Deleted patch
1
Signed 33-bit == signed 32-bit + unsigned 32-bit.
2
1
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/s390x/tcg-target-con-set.h | 8 ++++----
7
tcg/s390x/tcg-target-con-str.h | 2 +-
8
tcg/s390x/tcg-target.c.inc | 36 +++++++++++++++++-----------------
9
3 files changed, 23 insertions(+), 23 deletions(-)
10
11
diff --git a/tcg/s390x/tcg-target-con-set.h b/tcg/s390x/tcg-target-con-set.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/tcg/s390x/tcg-target-con-set.h
14
+++ b/tcg/s390x/tcg-target-con-set.h
15
@@ -XXX,XX +XXX,XX @@
16
C_O0_I1(r)
17
C_O0_I2(r, r)
18
C_O0_I2(r, ri)
19
-C_O0_I2(r, rA)
20
+C_O0_I2(r, rJU)
21
C_O0_I2(v, r)
22
C_O0_I3(o, m, r)
23
C_O1_I1(r, r)
24
@@ -XXX,XX +XXX,XX @@ C_O1_I2(r, 0, rI)
25
C_O1_I2(r, 0, rJ)
26
C_O1_I2(r, r, r)
27
C_O1_I2(r, r, ri)
28
-C_O1_I2(r, r, rA)
29
+C_O1_I2(r, r, rJU)
30
C_O1_I2(r, r, rI)
31
C_O1_I2(r, r, rJ)
32
C_O1_I2(r, r, rK)
33
@@ -XXX,XX +XXX,XX @@ C_O1_I2(v, v, r)
34
C_O1_I2(v, v, v)
35
C_O1_I3(v, v, v, v)
36
C_O1_I4(r, r, ri, rI, r)
37
-C_O1_I4(r, r, rA, rI, r)
38
+C_O1_I4(r, r, rJU, rI, r)
39
C_O2_I1(o, m, r)
40
C_O2_I2(o, m, 0, r)
41
C_O2_I2(o, m, r, r)
42
C_O2_I3(o, m, 0, 1, r)
43
C_N1_O1_I4(r, r, 0, 1, ri, r)
44
-C_N1_O1_I4(r, r, 0, 1, rA, r)
45
+C_N1_O1_I4(r, r, 0, 1, rJU, r)
46
diff --git a/tcg/s390x/tcg-target-con-str.h b/tcg/s390x/tcg-target-con-str.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/tcg/s390x/tcg-target-con-str.h
49
+++ b/tcg/s390x/tcg-target-con-str.h
50
@@ -XXX,XX +XXX,XX @@ REGS('o', 0xaaaa) /* odd numbered general regs */
51
* Define constraint letters for constants:
52
* CONST(letter, TCG_CT_CONST_* bit set)
53
*/
54
-CONST('A', TCG_CT_CONST_S33)
55
CONST('I', TCG_CT_CONST_S16)
56
CONST('J', TCG_CT_CONST_S32)
57
CONST('K', TCG_CT_CONST_P32)
58
CONST('N', TCG_CT_CONST_INV)
59
CONST('R', TCG_CT_CONST_INVRISBG)
60
+CONST('U', TCG_CT_CONST_U32)
61
CONST('Z', TCG_CT_CONST_ZERO)
62
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
63
index XXXXXXX..XXXXXXX 100644
64
--- a/tcg/s390x/tcg-target.c.inc
65
+++ b/tcg/s390x/tcg-target.c.inc
66
@@ -XXX,XX +XXX,XX @@
67
68
#define TCG_CT_CONST_S16 (1 << 8)
69
#define TCG_CT_CONST_S32 (1 << 9)
70
-#define TCG_CT_CONST_S33 (1 << 10)
71
+#define TCG_CT_CONST_U32 (1 << 10)
72
#define TCG_CT_CONST_ZERO (1 << 11)
73
#define TCG_CT_CONST_P32 (1 << 12)
74
#define TCG_CT_CONST_INV (1 << 13)
75
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, int ct,
76
TCGType type, TCGCond cond, int vece)
77
{
78
if (ct & TCG_CT_CONST) {
79
- return 1;
80
+ return true;
81
}
82
-
83
if (type == TCG_TYPE_I32) {
84
val = (int32_t)val;
85
}
86
87
- /* The following are mutually exclusive. */
88
- if (ct & TCG_CT_CONST_S16) {
89
- return val == (int16_t)val;
90
- } else if (ct & TCG_CT_CONST_S32) {
91
- return val == (int32_t)val;
92
- } else if (ct & TCG_CT_CONST_S33) {
93
- return val >= -0xffffffffll && val <= 0xffffffffll;
94
- } else if (ct & TCG_CT_CONST_ZERO) {
95
- return val == 0;
96
+ if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
97
+ return true;
98
+ }
99
+ if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
100
+ return true;
101
+ }
102
+ if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
103
+ return true;
104
+ }
105
+ if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
106
+ return true;
107
}
108
109
if (ct & TCG_CT_CONST_INV) {
110
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, int ct,
111
if ((ct & TCG_CT_CONST_INVRISBG) && risbg_mask(~val)) {
112
return true;
113
}
114
-
115
- return 0;
116
+ return false;
117
}
118
119
/* Emit instructions according to the given instruction format. */
120
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
121
return C_O1_I2(r, r, ri);
122
case INDEX_op_setcond_i64:
123
case INDEX_op_negsetcond_i64:
124
- return C_O1_I2(r, r, rA);
125
+ return C_O1_I2(r, r, rJU);
126
127
case INDEX_op_clz_i64:
128
return C_O1_I2(r, r, rI);
129
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
130
case INDEX_op_brcond_i32:
131
return C_O0_I2(r, ri);
132
case INDEX_op_brcond_i64:
133
- return C_O0_I2(r, rA);
134
+ return C_O0_I2(r, rJU);
135
136
case INDEX_op_bswap16_i32:
137
case INDEX_op_bswap16_i64:
138
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
139
case INDEX_op_movcond_i32:
140
return C_O1_I4(r, r, ri, rI, r);
141
case INDEX_op_movcond_i64:
142
- return C_O1_I4(r, r, rA, rI, r);
143
+ return C_O1_I4(r, r, rJU, rI, r);
144
145
case INDEX_op_div2_i32:
146
case INDEX_op_div2_i64:
147
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
148
149
case INDEX_op_add2_i64:
150
case INDEX_op_sub2_i64:
151
- return C_N1_O1_I4(r, r, 0, 1, rA, r);
152
+ return C_N1_O1_I4(r, r, 0, 1, rJU, r);
153
154
case INDEX_op_st_vec:
155
return C_O0_I2(v, r);
156
--
157
2.34.1
158
159
diff view generated by jsdifflib
Deleted patch
1
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
---
3
tcg/s390x/tcg-target.h | 2 +-
4
tcg/s390x/tcg-target.c.inc | 139 +++++++++++++++++++++++++------------
5
2 files changed, 97 insertions(+), 44 deletions(-)
6
1
7
diff --git a/tcg/s390x/tcg-target.h b/tcg/s390x/tcg-target.h
8
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/s390x/tcg-target.h
10
+++ b/tcg/s390x/tcg-target.h
11
@@ -XXX,XX +XXX,XX @@ extern uint64_t s390_facilities[3];
12
13
#define TCG_TARGET_HAS_qemu_ldst_i128 1
14
15
-#define TCG_TARGET_HAS_tst 0
16
+#define TCG_TARGET_HAS_tst 1
17
18
#define TCG_TARGET_HAS_v64 HAVE_FACILITY(VECTOR)
19
#define TCG_TARGET_HAS_v128 HAVE_FACILITY(VECTOR)
20
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
21
index XXXXXXX..XXXXXXX 100644
22
--- a/tcg/s390x/tcg-target.c.inc
23
+++ b/tcg/s390x/tcg-target.c.inc
24
@@ -XXX,XX +XXX,XX @@ typedef enum S390Opcode {
25
RI_OILH = 0xa50a,
26
RI_OILL = 0xa50b,
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)
67
{
68
+ uint64_t uval = val;
69
+
70
if (ct & TCG_CT_CONST) {
71
return true;
72
}
73
if (type == TCG_TYPE_I32) {
74
+ uval = (uint32_t)val;
75
val = (int32_t)val;
76
}
77
78
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, int ct,
79
case TCG_COND_GTU:
80
ct |= TCG_CT_CONST_U32; /* CLGFI */
81
break;
82
+ case TCG_COND_TSTNE:
83
+ case TCG_COND_TSTEQ:
84
+ if (is_const_p16(uval) >= 0) {
85
+ return true; /* TMxx */
86
+ }
87
+ if (risbg_mask(uval)) {
88
+ return true; /* RISBG */
89
+ }
90
+ break;
91
default:
92
g_assert_not_reached();
93
}
94
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, int ct,
95
if (ct & TCG_CT_CONST_INV) {
96
val = ~val;
97
}
98
- /*
99
- * Note that is_const_p16 is a subset of is_const_p32,
100
- * so we don't need both constraints.
101
- */
102
if ((ct & TCG_CT_CONST_P32) && is_const_p32(val) >= 0) {
103
return true;
104
}
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 = 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);
258
--
259
2.34.1
diff view generated by jsdifflib
Deleted patch
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
tcg/tci/tcg-target.h | 2 +-
5
tcg/tci.c | 14 ++++++++++++++
6
2 files changed, 15 insertions(+), 1 deletion(-)
7
1
8
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
9
index XXXXXXX..XXXXXXX 100644
10
--- a/tcg/tci/tcg-target.h
11
+++ b/tcg/tci/tcg-target.h
12
@@ -XXX,XX +XXX,XX @@
13
14
#define TCG_TARGET_HAS_qemu_ldst_i128 0
15
16
-#define TCG_TARGET_HAS_tst 0
17
+#define TCG_TARGET_HAS_tst 1
18
19
/* Number of registers available. */
20
#define TCG_TARGET_NB_REGS 16
21
diff --git a/tcg/tci.c b/tcg/tci.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/tcg/tci.c
24
+++ b/tcg/tci.c
25
@@ -XXX,XX +XXX,XX @@ static bool tci_compare32(uint32_t u0, uint32_t u1, TCGCond condition)
26
case TCG_COND_GTU:
27
result = (u0 > u1);
28
break;
29
+ case TCG_COND_TSTEQ:
30
+ result = (u0 & u1) == 0;
31
+ break;
32
+ case TCG_COND_TSTNE:
33
+ result = (u0 & u1) != 0;
34
+ break;
35
default:
36
g_assert_not_reached();
37
}
38
@@ -XXX,XX +XXX,XX @@ static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
39
case TCG_COND_GTU:
40
result = (u0 > u1);
41
break;
42
+ case TCG_COND_TSTEQ:
43
+ result = (u0 & u1) == 0;
44
+ break;
45
+ case TCG_COND_TSTNE:
46
+ result = (u0 & u1) != 0;
47
+ break;
48
default:
49
g_assert_not_reached();
50
}
51
@@ -XXX,XX +XXX,XX @@ static const char *str_c(TCGCond c)
52
[TCG_COND_GEU] = "geu",
53
[TCG_COND_LEU] = "leu",
54
[TCG_COND_GTU] = "gtu",
55
+ [TCG_COND_TSTEQ] = "tsteq",
56
+ [TCG_COND_TSTNE] = "tstne",
57
};
58
59
assert((unsigned)c < ARRAY_SIZE(cond));
60
--
61
2.34.1
62
63
diff view generated by jsdifflib