1
The following changes since commit ff56877e911782dedc9a424233fd3f62369c258c:
1
The following changes since commit 77f3804ab7ed94b471a14acb260e5aeacf26193f:
2
2
3
Merge remote-tracking branch 'remotes/kraxel/tags/vga-20181015-pull-request' into staging (2018-10-15 15:03:45 +0100)
3
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2021-02-02 16:47:51 +0000)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://github.com/rth7680/qemu.git tags/pull-tcg-20181016
7
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20210202
8
8
9
for you to fetch changes up to e3e9d1ea20c75718ce7c528c588a0a497f12f750:
9
for you to fetch changes up to 0c823e596877a30fd6c17a1ae9f98218a53055ea:
10
10
11
cputlb: read CPUTLBEntry.addr_write atomically (2018-10-16 10:04:27 -0700)
11
tcg: Remove TCG_TARGET_CON_SET_H (2021-02-02 12:12:43 -1000)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Queued tcg patches
14
TCG backend constraints cleanup
15
15
16
----------------------------------------------------------------
16
----------------------------------------------------------------
17
Emilio G. Cota (10):
17
Richard Henderson (24):
18
tcg: access cpu->icount_decr.u16.high with atomics
18
tcg/tci: Drop L and S constraints
19
tcg: fix use of uninitialized variable under CONFIG_PROFILER
19
tcg/tci: Remove TCG_TARGET_HAS_* ifdefs
20
tcg: plug holes in struct TCGProfile
20
tcg/i386: Move constraint type check to tcg_target_const_match
21
tcg: distribute tcg_time into TCG contexts
21
tcg/i386: Tidy register constraint definitions
22
target/alpha: remove tlb_flush from alpha_cpu_initfn
22
tcg/i386: Split out target constraints to tcg-target-con-str.h
23
target/unicore32: remove tlb_flush from uc32_init_fn
23
tcg/arm: Split out target constraints to tcg-target-con-str.h
24
exec: introduce tlb_init
24
tcg/aarch64: Split out target constraints to tcg-target-con-str.h
25
cputlb: fix assert_cpu_is_self macro
25
tcg/ppc: Split out target constraints to tcg-target-con-str.h
26
cputlb: serialize tlb updates with env->tlb_lock
26
tcg/tci: Split out target constraints to tcg-target-con-str.h
27
cputlb: read CPUTLBEntry.addr_write atomically
27
tcg/mips: Split out target constraints to tcg-target-con-str.h
28
tcg/riscv: Split out target constraints to tcg-target-con-str.h
29
tcg/s390: Split out target constraints to tcg-target-con-str.h
30
tcg/sparc: Split out target constraints to tcg-target-con-str.h
31
tcg: Remove TCG_TARGET_CON_STR_H
32
tcg/i386: Split out constraint sets to tcg-target-con-set.h
33
tcg/aarch64: Split out constraint sets to tcg-target-con-set.h
34
tcg/arm: Split out constraint sets to tcg-target-con-set.h
35
tcg/mips: Split out constraint sets to tcg-target-con-set.h
36
tcg/ppc: Split out constraint sets to tcg-target-con-set.h
37
tcg/riscv: Split out constraint sets to tcg-target-con-set.h
38
tcg/s390: Split out constraint sets to tcg-target-con-set.h
39
tcg/sparc: Split out constraint sets to tcg-target-con-set.h
40
tcg/tci: Split out constraint sets to tcg-target-con-set.h
41
tcg: Remove TCG_TARGET_CON_SET_H
28
42
29
Richard Henderson (11):
43
tcg/aarch64/tcg-target-con-set.h | 36 ++++
30
tcg: Implement CPU_LOG_TB_NOCHAIN during expansion
44
tcg/aarch64/tcg-target-con-str.h | 24 +++
31
tcg: Add tlb_index and tlb_entry helpers
45
tcg/arm/tcg-target-con-set.h | 35 ++++
32
tcg: Split CONFIG_ATOMIC128
46
tcg/arm/tcg-target-con-str.h | 22 +++
33
target/i386: Convert to HAVE_CMPXCHG128
47
tcg/i386/tcg-target-con-set.h | 55 ++++++
34
target/arm: Convert to HAVE_CMPXCHG128
48
tcg/i386/tcg-target-con-str.h | 33 ++++
35
target/arm: Check HAVE_CMPXCHG128 at translate time
49
tcg/mips/tcg-target-con-set.h | 36 ++++
36
target/ppc: Convert to HAVE_CMPXCHG128 and HAVE_ATOMIC128
50
tcg/mips/tcg-target-con-str.h | 24 +++
37
target/s390x: Convert to HAVE_CMPXCHG128 and HAVE_ATOMIC128
51
tcg/ppc/tcg-target-con-set.h | 42 +++++
38
target/s390x: Split do_cdsg, do_lpq, do_stpq
52
tcg/ppc/tcg-target-con-str.h | 30 ++++
39
target/s390x: Skip wout, cout helpers if op helper does not return
53
tcg/riscv/tcg-target-con-set.h | 30 ++++
40
target/s390x: Check HAVE_ATOMIC128 and HAVE_CMPXCHG128 at translate
54
tcg/riscv/tcg-target-con-str.h | 21 +++
55
tcg/s390/tcg-target-con-set.h | 29 ++++
56
tcg/s390/tcg-target-con-str.h | 28 +++
57
tcg/sparc/tcg-target-con-set.h | 32 ++++
58
tcg/sparc/tcg-target-con-str.h | 23 +++
59
tcg/sparc/tcg-target.h | 4 -
60
tcg/tci/tcg-target-con-set.h | 25 +++
61
tcg/tci/tcg-target-con-str.h | 11 ++
62
tcg/tcg.c | 136 +++++++++++++--
63
tcg/aarch64/tcg-target.c.inc | 137 ++++-----------
64
tcg/arm/tcg-target.c.inc | 168 ++++++------------
65
tcg/i386/tcg-target.c.inc | 317 +++++++++++-----------------------
66
tcg/mips/tcg-target.c.inc | 173 ++++++-------------
67
tcg/ppc/tcg-target.c.inc | 209 ++++++++---------------
68
tcg/riscv/tcg-target.c.inc | 135 ++++-----------
69
tcg/s390/tcg-target.c.inc | 174 +++++++------------
70
tcg/sparc/tcg-target.c.inc | 156 ++++++-----------
71
tcg/tci/tcg-target.c.inc | 359 ++++++++++++++-------------------------
72
29 files changed, 1244 insertions(+), 1260 deletions(-)
73
create mode 100644 tcg/aarch64/tcg-target-con-set.h
74
create mode 100644 tcg/aarch64/tcg-target-con-str.h
75
create mode 100644 tcg/arm/tcg-target-con-set.h
76
create mode 100644 tcg/arm/tcg-target-con-str.h
77
create mode 100644 tcg/i386/tcg-target-con-set.h
78
create mode 100644 tcg/i386/tcg-target-con-str.h
79
create mode 100644 tcg/mips/tcg-target-con-set.h
80
create mode 100644 tcg/mips/tcg-target-con-str.h
81
create mode 100644 tcg/ppc/tcg-target-con-set.h
82
create mode 100644 tcg/ppc/tcg-target-con-str.h
83
create mode 100644 tcg/riscv/tcg-target-con-set.h
84
create mode 100644 tcg/riscv/tcg-target-con-str.h
85
create mode 100644 tcg/s390/tcg-target-con-set.h
86
create mode 100644 tcg/s390/tcg-target-con-str.h
87
create mode 100644 tcg/sparc/tcg-target-con-set.h
88
create mode 100644 tcg/sparc/tcg-target-con-str.h
89
create mode 100644 tcg/tci/tcg-target-con-set.h
90
create mode 100644 tcg/tci/tcg-target-con-str.h
41
91
42
accel/tcg/atomic_template.h | 20 +++-
43
accel/tcg/softmmu_template.h | 64 +++++-----
44
include/exec/cpu-defs.h | 3 +
45
include/exec/cpu_ldst.h | 30 ++++-
46
include/exec/cpu_ldst_template.h | 25 ++--
47
include/exec/exec-all.h | 8 ++
48
include/qemu/atomic128.h | 155 ++++++++++++++++++++++++
49
include/qemu/timer.h | 1 -
50
target/ppc/helper.h | 2 +-
51
tcg/tcg.h | 20 ++--
52
accel/tcg/cpu-exec.c | 2 +-
53
accel/tcg/cputlb.c | 235 +++++++++++++++++++-----------------
54
accel/tcg/tcg-all.c | 2 +-
55
accel/tcg/translate-all.c | 2 +-
56
accel/tcg/user-exec.c | 5 +-
57
cpus.c | 3 +-
58
exec.c | 1 +
59
monitor.c | 13 +-
60
qom/cpu.c | 2 +-
61
target/alpha/cpu.c | 1 -
62
target/arm/helper-a64.c | 251 +++++++++++++++++++--------------------
63
target/arm/translate-a64.c | 38 +++---
64
target/i386/mem_helper.c | 9 +-
65
target/ppc/mem_helper.c | 33 ++++-
66
target/ppc/translate.c | 115 +++++++++---------
67
target/s390x/mem_helper.c | 202 +++++++++++++++----------------
68
target/s390x/translate.c | 45 +++++--
69
target/unicore32/cpu.c | 2 -
70
tcg/tcg-op.c | 9 +-
71
tcg/tcg.c | 25 +++-
72
configure | 19 +++
73
31 files changed, 830 insertions(+), 512 deletions(-)
74
create mode 100644 include/qemu/atomic128.h
75
diff view generated by jsdifflib
New patch
1
These are identical to the 'r' constraint.
1
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/tci/tcg-target.c.inc | 10 ++++------
7
1 file changed, 4 insertions(+), 6 deletions(-)
8
9
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/tci/tcg-target.c.inc
12
+++ b/tcg/tci/tcg-target.c.inc
13
@@ -XXX,XX +XXX,XX @@
14
# define R64 "r"
15
#endif
16
#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
17
-# define L "L", "L"
18
-# define S "S", "S"
19
+# define L "r", "r"
20
+# define S "r", "r"
21
#else
22
-# define L "L"
23
-# define S "S"
24
+# define L "r"
25
+# define S "r"
26
#endif
27
28
/* TODO: documentation. */
29
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
30
{
31
switch (*ct_str++) {
32
case 'r':
33
- case 'L': /* qemu_ld constraint */
34
- case 'S': /* qemu_st constraint */
35
ct->regs = BIT(TCG_TARGET_NB_REGS) - 1;
36
break;
37
default:
38
--
39
2.25.1
40
41
diff view generated by jsdifflib
New patch
1
The opcodes always exist, regardless of whether or not they
2
are enabled. Remove the unnecessary ifdefs.
1
3
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/tci/tcg-target.c.inc | 82 ----------------------------------------
7
1 file changed, 82 deletions(-)
8
9
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/tci/tcg-target.c.inc
12
+++ b/tcg/tci/tcg-target.c.inc
13
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef tcg_target_op_defs[] = {
14
{ INDEX_op_add_i32, { R, RI, RI } },
15
{ INDEX_op_sub_i32, { R, RI, RI } },
16
{ INDEX_op_mul_i32, { R, RI, RI } },
17
-#if TCG_TARGET_HAS_div_i32
18
{ INDEX_op_div_i32, { R, R, R } },
19
{ INDEX_op_divu_i32, { R, R, R } },
20
{ INDEX_op_rem_i32, { R, R, R } },
21
{ INDEX_op_remu_i32, { R, R, R } },
22
-#elif TCG_TARGET_HAS_div2_i32
23
- { INDEX_op_div2_i32, { R, R, "0", "1", R } },
24
- { INDEX_op_divu2_i32, { R, R, "0", "1", R } },
25
-#endif
26
/* TODO: Does R, RI, RI result in faster code than R, R, RI?
27
If both operands are constants, we can optimize. */
28
{ INDEX_op_and_i32, { R, RI, RI } },
29
-#if TCG_TARGET_HAS_andc_i32
30
{ INDEX_op_andc_i32, { R, RI, RI } },
31
-#endif
32
-#if TCG_TARGET_HAS_eqv_i32
33
{ INDEX_op_eqv_i32, { R, RI, RI } },
34
-#endif
35
-#if TCG_TARGET_HAS_nand_i32
36
{ INDEX_op_nand_i32, { R, RI, RI } },
37
-#endif
38
-#if TCG_TARGET_HAS_nor_i32
39
{ INDEX_op_nor_i32, { R, RI, RI } },
40
-#endif
41
{ INDEX_op_or_i32, { R, RI, RI } },
42
-#if TCG_TARGET_HAS_orc_i32
43
{ INDEX_op_orc_i32, { R, RI, RI } },
44
-#endif
45
{ INDEX_op_xor_i32, { R, RI, RI } },
46
{ INDEX_op_shl_i32, { R, RI, RI } },
47
{ INDEX_op_shr_i32, { R, RI, RI } },
48
{ INDEX_op_sar_i32, { R, RI, RI } },
49
-#if TCG_TARGET_HAS_rot_i32
50
{ INDEX_op_rotl_i32, { R, RI, RI } },
51
{ INDEX_op_rotr_i32, { R, RI, RI } },
52
-#endif
53
-#if TCG_TARGET_HAS_deposit_i32
54
{ INDEX_op_deposit_i32, { R, "0", R } },
55
-#endif
56
57
{ INDEX_op_brcond_i32, { R, RI } },
58
59
{ INDEX_op_setcond_i32, { R, R, RI } },
60
-#if TCG_TARGET_REG_BITS == 64
61
{ INDEX_op_setcond_i64, { R, R, RI } },
62
-#endif /* TCG_TARGET_REG_BITS == 64 */
63
64
-#if TCG_TARGET_REG_BITS == 32
65
/* TODO: Support R, R, R, R, RI, RI? Will it be faster? */
66
{ INDEX_op_add2_i32, { R, R, R, R, R, R } },
67
{ INDEX_op_sub2_i32, { R, R, R, R, R, R } },
68
{ INDEX_op_brcond2_i32, { R, R, RI, RI } },
69
{ INDEX_op_mulu2_i32, { R, R, R, R } },
70
{ INDEX_op_setcond2_i32, { R, R, R, RI, RI } },
71
-#endif
72
73
-#if TCG_TARGET_HAS_not_i32
74
{ INDEX_op_not_i32, { R, R } },
75
-#endif
76
-#if TCG_TARGET_HAS_neg_i32
77
{ INDEX_op_neg_i32, { R, R } },
78
-#endif
79
80
-#if TCG_TARGET_REG_BITS == 64
81
{ INDEX_op_ld8u_i64, { R, R } },
82
{ INDEX_op_ld8s_i64, { R, R } },
83
{ INDEX_op_ld16u_i64, { R, R } },
84
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef tcg_target_op_defs[] = {
85
{ INDEX_op_add_i64, { R, RI, RI } },
86
{ INDEX_op_sub_i64, { R, RI, RI } },
87
{ INDEX_op_mul_i64, { R, RI, RI } },
88
-#if TCG_TARGET_HAS_div_i64
89
{ INDEX_op_div_i64, { R, R, R } },
90
{ INDEX_op_divu_i64, { R, R, R } },
91
{ INDEX_op_rem_i64, { R, R, R } },
92
{ INDEX_op_remu_i64, { R, R, R } },
93
-#elif TCG_TARGET_HAS_div2_i64
94
- { INDEX_op_div2_i64, { R, R, "0", "1", R } },
95
- { INDEX_op_divu2_i64, { R, R, "0", "1", R } },
96
-#endif
97
{ INDEX_op_and_i64, { R, RI, RI } },
98
-#if TCG_TARGET_HAS_andc_i64
99
{ INDEX_op_andc_i64, { R, RI, RI } },
100
-#endif
101
-#if TCG_TARGET_HAS_eqv_i64
102
{ INDEX_op_eqv_i64, { R, RI, RI } },
103
-#endif
104
-#if TCG_TARGET_HAS_nand_i64
105
{ INDEX_op_nand_i64, { R, RI, RI } },
106
-#endif
107
-#if TCG_TARGET_HAS_nor_i64
108
{ INDEX_op_nor_i64, { R, RI, RI } },
109
-#endif
110
{ INDEX_op_or_i64, { R, RI, RI } },
111
-#if TCG_TARGET_HAS_orc_i64
112
{ INDEX_op_orc_i64, { R, RI, RI } },
113
-#endif
114
{ INDEX_op_xor_i64, { R, RI, RI } },
115
{ INDEX_op_shl_i64, { R, RI, RI } },
116
{ INDEX_op_shr_i64, { R, RI, RI } },
117
{ INDEX_op_sar_i64, { R, RI, RI } },
118
-#if TCG_TARGET_HAS_rot_i64
119
{ INDEX_op_rotl_i64, { R, RI, RI } },
120
{ INDEX_op_rotr_i64, { R, RI, RI } },
121
-#endif
122
-#if TCG_TARGET_HAS_deposit_i64
123
{ INDEX_op_deposit_i64, { R, "0", R } },
124
-#endif
125
{ INDEX_op_brcond_i64, { R, RI } },
126
127
-#if TCG_TARGET_HAS_ext8s_i64
128
{ INDEX_op_ext8s_i64, { R, R } },
129
-#endif
130
-#if TCG_TARGET_HAS_ext16s_i64
131
{ INDEX_op_ext16s_i64, { R, R } },
132
-#endif
133
-#if TCG_TARGET_HAS_ext32s_i64
134
{ INDEX_op_ext32s_i64, { R, R } },
135
-#endif
136
-#if TCG_TARGET_HAS_ext8u_i64
137
{ INDEX_op_ext8u_i64, { R, R } },
138
-#endif
139
-#if TCG_TARGET_HAS_ext16u_i64
140
{ INDEX_op_ext16u_i64, { R, R } },
141
-#endif
142
-#if TCG_TARGET_HAS_ext32u_i64
143
{ INDEX_op_ext32u_i64, { R, R } },
144
-#endif
145
{ INDEX_op_ext_i32_i64, { R, R } },
146
{ INDEX_op_extu_i32_i64, { R, R } },
147
-#if TCG_TARGET_HAS_bswap16_i64
148
{ INDEX_op_bswap16_i64, { R, R } },
149
-#endif
150
-#if TCG_TARGET_HAS_bswap32_i64
151
{ INDEX_op_bswap32_i64, { R, R } },
152
-#endif
153
-#if TCG_TARGET_HAS_bswap64_i64
154
{ INDEX_op_bswap64_i64, { R, R } },
155
-#endif
156
-#if TCG_TARGET_HAS_not_i64
157
{ INDEX_op_not_i64, { R, R } },
158
-#endif
159
-#if TCG_TARGET_HAS_neg_i64
160
{ INDEX_op_neg_i64, { R, R } },
161
-#endif
162
-#endif /* TCG_TARGET_REG_BITS == 64 */
163
164
{ INDEX_op_qemu_ld_i32, { R, L } },
165
{ INDEX_op_qemu_ld_i64, { R64, L } },
166
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef tcg_target_op_defs[] = {
167
{ INDEX_op_qemu_st_i32, { R, S } },
168
{ INDEX_op_qemu_st_i64, { R64, S } },
169
170
-#if TCG_TARGET_HAS_ext8s_i32
171
{ INDEX_op_ext8s_i32, { R, R } },
172
-#endif
173
-#if TCG_TARGET_HAS_ext16s_i32
174
{ INDEX_op_ext16s_i32, { R, R } },
175
-#endif
176
-#if TCG_TARGET_HAS_ext8u_i32
177
{ INDEX_op_ext8u_i32, { R, R } },
178
-#endif
179
-#if TCG_TARGET_HAS_ext16u_i32
180
{ INDEX_op_ext16u_i32, { R, R } },
181
-#endif
182
183
-#if TCG_TARGET_HAS_bswap16_i32
184
{ INDEX_op_bswap16_i32, { R, R } },
185
-#endif
186
-#if TCG_TARGET_HAS_bswap32_i32
187
{ INDEX_op_bswap32_i32, { R, R } },
188
-#endif
189
190
{ INDEX_op_mb, { } },
191
{ -1 },
192
--
193
2.25.1
194
195
diff view generated by jsdifflib
1
When op raises an exception, it may not have initialized the output
1
Rather than check the type when filling in the constraint,
2
temps that would be written back by wout or cout.
2
check it when matching the constant. This removes the only
3
use of the type argument to target_parse_constraint.
3
4
4
Reviewed-by: David Hildenbrand <david@redhat.com>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
---
7
target/s390x/translate.c | 20 +++++++++++++++-----
8
tcg/i386/tcg-target.c.inc | 28 +++++++++++++++++-----------
8
1 file changed, 15 insertions(+), 5 deletions(-)
9
1 file changed, 17 insertions(+), 11 deletions(-)
9
10
10
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
11
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
11
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
12
--- a/target/s390x/translate.c
13
--- a/tcg/i386/tcg-target.c.inc
13
+++ b/target/s390x/translate.c
14
+++ b/tcg/i386/tcg-target.c.inc
14
@@ -XXX,XX +XXX,XX @@ struct DisasInsn {
15
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
15
16
break;
16
const char *name;
17
17
18
case 'e':
18
+ /* Pre-process arguments before HELP_OP. */
19
- ct->ct |= (type == TCG_TYPE_I32 ? TCG_CT_CONST : TCG_CT_CONST_S32);
19
void (*help_in1)(DisasContext *, DisasFields *, DisasOps *);
20
+ ct->ct |= TCG_CT_CONST_S32;
20
void (*help_in2)(DisasContext *, DisasFields *, DisasOps *);
21
break;
21
void (*help_prep)(DisasContext *, DisasFields *, DisasOps *);
22
case 'Z':
22
+
23
- ct->ct |= (type == TCG_TYPE_I32 ? TCG_CT_CONST : TCG_CT_CONST_U32);
23
+ /*
24
+ ct->ct |= TCG_CT_CONST_U32;
24
+ * Post-process output after HELP_OP.
25
break;
25
+ * Note that these are not called if HELP_OP returns DISAS_NORETURN.
26
case 'I':
26
+ */
27
- ct->ct |= (type == TCG_TYPE_I32 ? TCG_CT_CONST : TCG_CT_CONST_I32);
27
void (*help_wout)(DisasContext *, DisasFields *, DisasOps *);
28
+ ct->ct |= TCG_CT_CONST_I32;
28
void (*help_cout)(DisasContext *, DisasOps *);
29
break;
29
+
30
30
+ /* Implement the operation itself. */
31
default:
31
DisasJumpType (*help_op)(DisasContext *, DisasOps *);
32
@@ -XXX,XX +XXX,XX @@ static inline int tcg_target_const_match(tcg_target_long val, TCGType type,
32
33
if (ct & TCG_CT_CONST) {
33
uint64_t data;
34
return 1;
34
@@ -XXX,XX +XXX,XX @@ static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s)
35
if (insn->help_op) {
36
ret = insn->help_op(s, &o);
37
}
35
}
38
- if (insn->help_wout) {
36
- if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
39
- insn->help_wout(s, &f, &o);
37
- return 1;
40
- }
38
- }
41
- if (insn->help_cout) {
39
- if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
42
- insn->help_cout(s, &o);
40
- return 1;
43
+ if (ret != DISAS_NORETURN) {
41
- }
44
+ if (insn->help_wout) {
42
- if ((ct & TCG_CT_CONST_I32) && ~val == (int32_t)~val) {
45
+ insn->help_wout(s, &f, &o);
43
- return 1;
44
+ if (type == TCG_TYPE_I32) {
45
+ if (ct & (TCG_CT_CONST_S32 | TCG_CT_CONST_U32 | TCG_CT_CONST_I32)) {
46
+ return 1;
46
+ }
47
+ }
47
+ if (insn->help_cout) {
48
+ } else {
48
+ insn->help_cout(s, &o);
49
+ if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
50
+ return 1;
51
+ }
52
+ if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
53
+ return 1;
54
+ }
55
+ if ((ct & TCG_CT_CONST_I32) && ~val == (int32_t)~val) {
56
+ return 1;
49
+ }
57
+ }
50
}
58
}
51
59
if ((ct & TCG_CT_CONST_WSZ) && val == (type == TCG_TYPE_I32 ? 32 : 64)) {
52
/* Free any temporaries created by the helpers. */
60
return 1;
53
--
61
--
54
2.17.2
62
2.25.1
55
63
56
64
diff view generated by jsdifflib
1
Reviewed-by: Emilio G. Cota <cota@braap.org>
1
Create symbolic constants for all low-byte-addressable
2
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
2
and second-byte-addressable registers. Create a symbol
3
for the registers that need reserving for softmmu.
4
5
There is no functional change for 's', as this letter is
6
only used for i386. The BYTEL name is correct for the
7
action we wish from the constraint.
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
11
---
5
target/arm/helper-a64.c | 16 ++++------------
12
tcg/i386/tcg-target.c.inc | 40 +++++++++++++++++++--------------------
6
target/arm/translate-a64.c | 38 ++++++++++++++++++++++----------------
13
1 file changed, 20 insertions(+), 20 deletions(-)
7
2 files changed, 26 insertions(+), 28 deletions(-)
8
14
9
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
15
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
10
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
11
--- a/target/arm/helper-a64.c
17
--- a/tcg/i386/tcg-target.c.inc
12
+++ b/target/arm/helper-a64.c
18
+++ b/tcg/i386/tcg-target.c.inc
13
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(paired_cmpxchg64_le_parallel)(CPUARMState *env, uint64_t addr,
19
@@ -XXX,XX +XXX,XX @@ static const int tcg_target_call_oarg_regs[] = {
14
int mem_idx;
20
# define TCG_REG_L1 TCG_REG_EDX
15
TCGMemOpIdx oi;
21
#endif
16
22
17
- if (!HAVE_CMPXCHG128) {
23
+#define ALL_BYTEH_REGS 0x0000000fu
18
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
24
+#if TCG_TARGET_REG_BITS == 64
19
- }
25
+# define ALL_GENERAL_REGS 0x0000ffffu
20
+ assert(HAVE_CMPXCHG128);
26
+# define ALL_VECTOR_REGS 0xffff0000u
21
27
+# define ALL_BYTEL_REGS ALL_GENERAL_REGS
22
mem_idx = cpu_mmu_index(env, false);
28
+#else
23
oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
29
+# define ALL_GENERAL_REGS 0x000000ffu
24
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(paired_cmpxchg64_be_parallel)(CPUARMState *env, uint64_t addr,
30
+# define ALL_VECTOR_REGS 0x00ff0000u
25
int mem_idx;
31
+# define ALL_BYTEL_REGS ALL_BYTEH_REGS
26
TCGMemOpIdx oi;
32
+#endif
27
33
+#ifdef CONFIG_SOFTMMU
28
- if (!HAVE_CMPXCHG128) {
34
+# define SOFTMMU_RESERVE_REGS ((1 << TCG_REG_L0) | (1 << TCG_REG_L1))
29
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
35
+#else
30
- }
36
+# define SOFTMMU_RESERVE_REGS 0
31
+ assert(HAVE_CMPXCHG128);
37
+#endif
32
38
+
33
mem_idx = cpu_mmu_index(env, false);
39
/* The host compiler should supply <cpuid.h> to enable runtime features
34
oi = make_memop_idx(MO_BEQ | MO_ALIGN_16, mem_idx);
40
detection, as we're not going to go so far as our own inline assembly.
35
@@ -XXX,XX +XXX,XX @@ void HELPER(casp_le_parallel)(CPUARMState *env, uint32_t rs, uint64_t addr,
41
If not available, default values will be assumed. */
36
int mem_idx;
42
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
37
TCGMemOpIdx oi;
43
return true;
38
44
}
39
- if (!HAVE_CMPXCHG128) {
45
40
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
46
-#if TCG_TARGET_REG_BITS == 64
41
- }
47
-#define ALL_GENERAL_REGS 0x0000ffffu
42
+ assert(HAVE_CMPXCHG128);
48
-#define ALL_VECTOR_REGS 0xffff0000u
43
49
-#else
44
mem_idx = cpu_mmu_index(env, false);
50
-#define ALL_GENERAL_REGS 0x000000ffu
45
oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
51
-#define ALL_VECTOR_REGS 0x00ff0000u
46
@@ -XXX,XX +XXX,XX @@ void HELPER(casp_be_parallel)(CPUARMState *env, uint32_t rs, uint64_t addr,
52
-#endif
47
int mem_idx;
48
TCGMemOpIdx oi;
49
50
- if (!HAVE_CMPXCHG128) {
51
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
52
- }
53
+ assert(HAVE_CMPXCHG128);
54
55
mem_idx = cpu_mmu_index(env, false);
56
oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
57
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/translate-a64.c
60
+++ b/target/arm/translate-a64.c
61
@@ -XXX,XX +XXX,XX @@
62
63
#include "trace-tcg.h"
64
#include "translate-a64.h"
65
+#include "qemu/atomic128.h"
66
67
static TCGv_i64 cpu_X[32];
68
static TCGv_i64 cpu_pc;
69
@@ -XXX,XX +XXX,XX @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
70
get_mem_index(s),
71
MO_64 | MO_ALIGN | s->be_data);
72
tcg_gen_setcond_i64(TCG_COND_NE, tmp, tmp, cpu_exclusive_val);
73
- } else if (s->be_data == MO_LE) {
74
- if (tb_cflags(s->base.tb) & CF_PARALLEL) {
75
+ } else if (tb_cflags(s->base.tb) & CF_PARALLEL) {
76
+ if (!HAVE_CMPXCHG128) {
77
+ gen_helper_exit_atomic(cpu_env);
78
+ s->base.is_jmp = DISAS_NORETURN;
79
+ } else if (s->be_data == MO_LE) {
80
gen_helper_paired_cmpxchg64_le_parallel(tmp, cpu_env,
81
cpu_exclusive_addr,
82
cpu_reg(s, rt),
83
cpu_reg(s, rt2));
84
} else {
85
- gen_helper_paired_cmpxchg64_le(tmp, cpu_env, cpu_exclusive_addr,
86
- cpu_reg(s, rt), cpu_reg(s, rt2));
87
- }
88
- } else {
89
- if (tb_cflags(s->base.tb) & CF_PARALLEL) {
90
gen_helper_paired_cmpxchg64_be_parallel(tmp, cpu_env,
91
cpu_exclusive_addr,
92
cpu_reg(s, rt),
93
cpu_reg(s, rt2));
94
- } else {
95
- gen_helper_paired_cmpxchg64_be(tmp, cpu_env, cpu_exclusive_addr,
96
- cpu_reg(s, rt), cpu_reg(s, rt2));
97
}
98
+ } else if (s->be_data == MO_LE) {
99
+ gen_helper_paired_cmpxchg64_le(tmp, cpu_env, cpu_exclusive_addr,
100
+ cpu_reg(s, rt), cpu_reg(s, rt2));
101
+ } else {
102
+ gen_helper_paired_cmpxchg64_be(tmp, cpu_env, cpu_exclusive_addr,
103
+ cpu_reg(s, rt), cpu_reg(s, rt2));
104
}
105
} else {
106
tcg_gen_atomic_cmpxchg_i64(tmp, cpu_exclusive_addr, cpu_exclusive_val,
107
@@ -XXX,XX +XXX,XX @@ static void gen_compare_and_swap_pair(DisasContext *s, int rs, int rt,
108
}
109
tcg_temp_free_i64(cmp);
110
} else if (tb_cflags(s->base.tb) & CF_PARALLEL) {
111
- TCGv_i32 tcg_rs = tcg_const_i32(rs);
112
-
53
-
113
- if (s->be_data == MO_LE) {
54
/* parse target specific constraints */
114
- gen_helper_casp_le_parallel(cpu_env, tcg_rs, addr, t1, t2);
55
static const char *target_parse_constraint(TCGArgConstraint *ct,
115
+ if (HAVE_CMPXCHG128) {
56
const char *ct_str, TCGType type)
116
+ TCGv_i32 tcg_rs = tcg_const_i32(rs);
57
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
117
+ if (s->be_data == MO_LE) {
58
break;
118
+ gen_helper_casp_le_parallel(cpu_env, tcg_rs, addr, t1, t2);
59
case 'q':
119
+ } else {
60
/* A register that can be used as a byte operand. */
120
+ gen_helper_casp_be_parallel(cpu_env, tcg_rs, addr, t1, t2);
61
- ct->regs = TCG_TARGET_REG_BITS == 64 ? 0xffff : 0xf;
121
+ }
62
+ ct->regs |= ALL_BYTEL_REGS;
122
+ tcg_temp_free_i32(tcg_rs);
63
break;
123
} else {
64
case 'Q':
124
- gen_helper_casp_be_parallel(cpu_env, tcg_rs, addr, t1, t2);
65
/* A register with an addressable second byte (e.g. %ah). */
125
+ gen_helper_exit_atomic(cpu_env);
66
- ct->regs = 0xf;
126
+ s->base.is_jmp = DISAS_NORETURN;
67
+ ct->regs |= ALL_BYTEH_REGS;
127
}
68
break;
128
- tcg_temp_free_i32(tcg_rs);
69
case 'r':
129
} else {
70
/* A general register. */
130
TCGv_i64 d1 = tcg_temp_new_i64();
71
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
131
TCGv_i64 d2 = tcg_temp_new_i64();
72
73
case 'L':
74
/* qemu_ld/st data+address constraint */
75
- ct->regs = TCG_TARGET_REG_BITS == 64 ? 0xffff : 0xff;
76
-#ifdef CONFIG_SOFTMMU
77
- tcg_regset_reset_reg(ct->regs, TCG_REG_L0);
78
- tcg_regset_reset_reg(ct->regs, TCG_REG_L1);
79
-#endif
80
+ ct->regs |= ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS;
81
break;
82
case 's':
83
/* qemu_st8_i32 data constraint */
84
- ct->regs = 0xf;
85
-#ifdef CONFIG_SOFTMMU
86
- tcg_regset_reset_reg(ct->regs, TCG_REG_L0);
87
- tcg_regset_reset_reg(ct->regs, TCG_REG_L1);
88
-#endif
89
+ ct->regs |= ALL_BYTEL_REGS & ~SOFTMMU_RESERVE_REGS;
90
break;
91
92
case 'e':
132
--
93
--
133
2.17.2
94
2.25.1
134
95
135
96
diff view generated by jsdifflib
New patch
1
1
This eliminates the target-specific function target_parse_constraint
2
and folds it into the single caller, process_op_defs. Since this is
3
done directly into the switch statement, duplicates are compilation
4
errors rather than silently ignored at runtime.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
9
tcg/i386/tcg-target-con-str.h | 33 +++++++++++++++++
10
tcg/i386/tcg-target.h | 1 +
11
tcg/tcg.c | 33 ++++++++++++++---
12
tcg/i386/tcg-target.c.inc | 69 -----------------------------------
13
4 files changed, 62 insertions(+), 74 deletions(-)
14
create mode 100644 tcg/i386/tcg-target-con-str.h
15
16
diff --git a/tcg/i386/tcg-target-con-str.h b/tcg/i386/tcg-target-con-str.h
17
new file mode 100644
18
index XXXXXXX..XXXXXXX
19
--- /dev/null
20
+++ b/tcg/i386/tcg-target-con-str.h
21
@@ -XXX,XX +XXX,XX @@
22
+/* SPDX-License-Identifier: MIT */
23
+/*
24
+ * Define i386 target-specific operand constraints.
25
+ * Copyright (c) 2021 Linaro
26
+ *
27
+ */
28
+
29
+/*
30
+ * Define constraint letters for register sets:
31
+ * REGS(letter, register_mask)
32
+ */
33
+REGS('a', 1u << TCG_REG_EAX)
34
+REGS('b', 1u << TCG_REG_EBX)
35
+REGS('c', 1u << TCG_REG_ECX)
36
+REGS('d', 1u << TCG_REG_EDX)
37
+REGS('S', 1u << TCG_REG_ESI)
38
+REGS('D', 1u << TCG_REG_EDI)
39
+
40
+REGS('r', ALL_GENERAL_REGS)
41
+REGS('x', ALL_VECTOR_REGS)
42
+REGS('q', ALL_BYTEL_REGS) /* regs that can be used as a byte operand */
43
+REGS('Q', ALL_BYTEH_REGS) /* regs with a second byte (e.g. %ah) */
44
+REGS('L', ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS) /* qemu_ld/st */
45
+REGS('s', ALL_BYTEL_REGS & ~SOFTMMU_RESERVE_REGS) /* qemu_st8_i32 data */
46
+
47
+/*
48
+ * Define constraint letters for constants:
49
+ * CONST(letter, TCG_CT_CONST_* bit set)
50
+ */
51
+CONST('e', TCG_CT_CONST_S32)
52
+CONST('I', TCG_CT_CONST_I32)
53
+CONST('W', TCG_CT_CONST_WSZ)
54
+CONST('Z', TCG_CT_CONST_U32)
55
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
56
index XXXXXXX..XXXXXXX 100644
57
--- a/tcg/i386/tcg-target.h
58
+++ b/tcg/i386/tcg-target.h
59
@@ -XXX,XX +XXX,XX @@ static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
60
#define TCG_TARGET_NEED_LDST_LABELS
61
#endif
62
#define TCG_TARGET_NEED_POOL_LABELS
63
+#define TCG_TARGET_CON_STR_H
64
65
#endif
66
diff --git a/tcg/tcg.c b/tcg/tcg.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/tcg/tcg.c
69
+++ b/tcg/tcg.c
70
@@ -XXX,XX +XXX,XX @@ static void tcg_register_jit_int(const void *buf, size_t size,
71
__attribute__((unused));
72
73
/* Forward declarations for functions declared and used in tcg-target.c.inc. */
74
+#ifndef TCG_TARGET_CON_STR_H
75
static const char *target_parse_constraint(TCGArgConstraint *ct,
76
const char *ct_str, TCGType type);
77
+#endif
78
static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
79
intptr_t arg2);
80
static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
81
@@ -XXX,XX +XXX,XX @@ static void process_op_defs(TCGContext *s)
82
for (op = 0; op < NB_OPS; op++) {
83
TCGOpDef *def = &tcg_op_defs[op];
84
const TCGTargetOpDef *tdefs;
85
- TCGType type;
86
int i, nb_args;
87
88
if (def->flags & TCG_OPF_NOT_PRESENT) {
89
@@ -XXX,XX +XXX,XX @@ static void process_op_defs(TCGContext *s)
90
/* Missing TCGTargetOpDef entry. */
91
tcg_debug_assert(tdefs != NULL);
92
93
- type = (def->flags & TCG_OPF_64BIT ? TCG_TYPE_I64 : TCG_TYPE_I32);
94
for (i = 0; i < nb_args; i++) {
95
const char *ct_str = tdefs->args_ct_str[i];
96
/* Incomplete TCGTargetOpDef entry. */
97
@@ -XXX,XX +XXX,XX @@ static void process_op_defs(TCGContext *s)
98
def->args_ct[i].ct |= TCG_CT_CONST;
99
ct_str++;
100
break;
101
+
102
+#ifdef TCG_TARGET_CON_STR_H
103
+ /* Include all of the target-specific constraints. */
104
+
105
+#undef CONST
106
+#define CONST(CASE, MASK) \
107
+ case CASE: def->args_ct[i].ct |= MASK; ct_str++; break;
108
+#define REGS(CASE, MASK) \
109
+ case CASE: def->args_ct[i].regs |= MASK; ct_str++; break;
110
+
111
+#include "tcg-target-con-str.h"
112
+
113
+#undef REGS
114
+#undef CONST
115
default:
116
- ct_str = target_parse_constraint(&def->args_ct[i],
117
- ct_str, type);
118
/* Typo in TCGTargetOpDef constraint. */
119
- tcg_debug_assert(ct_str != NULL);
120
+ g_assert_not_reached();
121
+#else
122
+ default:
123
+ {
124
+ TCGType type = (def->flags & TCG_OPF_64BIT
125
+ ? TCG_TYPE_I64 : TCG_TYPE_I32);
126
+ ct_str = target_parse_constraint(&def->args_ct[i],
127
+ ct_str, type);
128
+ /* Typo in TCGTargetOpDef constraint. */
129
+ tcg_debug_assert(ct_str != NULL);
130
+ }
131
+#endif
132
}
133
}
134
}
135
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
136
index XXXXXXX..XXXXXXX 100644
137
--- a/tcg/i386/tcg-target.c.inc
138
+++ b/tcg/i386/tcg-target.c.inc
139
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
140
return true;
141
}
142
143
-/* parse target specific constraints */
144
-static const char *target_parse_constraint(TCGArgConstraint *ct,
145
- const char *ct_str, TCGType type)
146
-{
147
- switch(*ct_str++) {
148
- case 'a':
149
- tcg_regset_set_reg(ct->regs, TCG_REG_EAX);
150
- break;
151
- case 'b':
152
- tcg_regset_set_reg(ct->regs, TCG_REG_EBX);
153
- break;
154
- case 'c':
155
- tcg_regset_set_reg(ct->regs, TCG_REG_ECX);
156
- break;
157
- case 'd':
158
- tcg_regset_set_reg(ct->regs, TCG_REG_EDX);
159
- break;
160
- case 'S':
161
- tcg_regset_set_reg(ct->regs, TCG_REG_ESI);
162
- break;
163
- case 'D':
164
- tcg_regset_set_reg(ct->regs, TCG_REG_EDI);
165
- break;
166
- case 'q':
167
- /* A register that can be used as a byte operand. */
168
- ct->regs |= ALL_BYTEL_REGS;
169
- break;
170
- case 'Q':
171
- /* A register with an addressable second byte (e.g. %ah). */
172
- ct->regs |= ALL_BYTEH_REGS;
173
- break;
174
- case 'r':
175
- /* A general register. */
176
- ct->regs |= ALL_GENERAL_REGS;
177
- break;
178
- case 'W':
179
- /* With TZCNT/LZCNT, we can have operand-size as an input. */
180
- ct->ct |= TCG_CT_CONST_WSZ;
181
- break;
182
- case 'x':
183
- /* A vector register. */
184
- ct->regs |= ALL_VECTOR_REGS;
185
- break;
186
-
187
- case 'L':
188
- /* qemu_ld/st data+address constraint */
189
- ct->regs |= ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS;
190
- break;
191
- case 's':
192
- /* qemu_st8_i32 data constraint */
193
- ct->regs |= ALL_BYTEL_REGS & ~SOFTMMU_RESERVE_REGS;
194
- break;
195
-
196
- case 'e':
197
- ct->ct |= TCG_CT_CONST_S32;
198
- break;
199
- case 'Z':
200
- ct->ct |= TCG_CT_CONST_U32;
201
- break;
202
- case 'I':
203
- ct->ct |= TCG_CT_CONST_I32;
204
- break;
205
-
206
- default:
207
- return NULL;
208
- }
209
- return ct_str;
210
-}
211
-
212
/* test if a constant matches the constraint */
213
static inline int tcg_target_const_match(tcg_target_long val, TCGType type,
214
const TCGArgConstraint *arg_ct)
215
--
216
2.25.1
217
218
diff view generated by jsdifflib
1
From: "Emilio G. Cota" <cota@braap.org>
1
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2
3
Paves the way for the addition of a per-TLB lock.
4
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Emilio G. Cota <cota@braap.org>
8
Message-Id: <20181009174557.16125-4-cota@braap.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
3
---
11
include/exec/exec-all.h | 8 ++++++++
4
tcg/arm/tcg-target-con-str.h | 22 +++++++++++
12
accel/tcg/cputlb.c | 4 ++++
5
tcg/arm/tcg-target.h | 1 +
13
exec.c | 1 +
6
tcg/arm/tcg-target.c.inc | 74 +++++++++---------------------------
14
3 files changed, 13 insertions(+)
7
3 files changed, 41 insertions(+), 56 deletions(-)
8
create mode 100644 tcg/arm/tcg-target-con-str.h
15
9
16
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
10
diff --git a/tcg/arm/tcg-target-con-str.h b/tcg/arm/tcg-target-con-str.h
11
new file mode 100644
12
index XXXXXXX..XXXXXXX
13
--- /dev/null
14
+++ b/tcg/arm/tcg-target-con-str.h
15
@@ -XXX,XX +XXX,XX @@
16
+/* SPDX-License-Identifier: MIT */
17
+/*
18
+ * Define Arm target-specific operand constraints.
19
+ * Copyright (c) 2021 Linaro
20
+ */
21
+
22
+/*
23
+ * Define constraint letters for register sets:
24
+ * REGS(letter, register_mask)
25
+ */
26
+REGS('r', ALL_GENERAL_REGS)
27
+REGS('l', ALL_QLOAD_REGS)
28
+REGS('s', ALL_QSTORE_REGS)
29
+
30
+/*
31
+ * Define constraint letters for constants:
32
+ * CONST(letter, TCG_CT_CONST_* bit set)
33
+ */
34
+CONST('I', TCG_CT_CONST_ARM)
35
+CONST('K', TCG_CT_CONST_INV)
36
+CONST('N', TCG_CT_CONST_NEG)
37
+CONST('Z', TCG_CT_CONST_ZERO)
38
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
17
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
18
--- a/include/exec/exec-all.h
40
--- a/tcg/arm/tcg-target.h
19
+++ b/include/exec/exec-all.h
41
+++ b/tcg/arm/tcg-target.h
20
@@ -XXX,XX +XXX,XX @@ void cpu_address_space_init(CPUState *cpu, int asidx,
42
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
21
43
#define TCG_TARGET_NEED_LDST_LABELS
22
#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG)
44
#endif
23
/* cputlb.c */
45
#define TCG_TARGET_NEED_POOL_LABELS
24
+/**
46
+#define TCG_TARGET_CON_STR_H
25
+ * tlb_init - initialize a CPU's TLB
47
26
+ * @cpu: CPU whose TLB should be initialized
48
#endif
49
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
50
index XXXXXXX..XXXXXXX 100644
51
--- a/tcg/arm/tcg-target.c.inc
52
+++ b/tcg/arm/tcg-target.c.inc
53
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
54
#define TCG_CT_CONST_NEG 0x400
55
#define TCG_CT_CONST_ZERO 0x800
56
57
-/* parse target specific constraints */
58
-static const char *target_parse_constraint(TCGArgConstraint *ct,
59
- const char *ct_str, TCGType type)
60
-{
61
- switch (*ct_str++) {
62
- case 'I':
63
- ct->ct |= TCG_CT_CONST_ARM;
64
- break;
65
- case 'K':
66
- ct->ct |= TCG_CT_CONST_INV;
67
- break;
68
- case 'N': /* The gcc constraint letter is L, already used here. */
69
- ct->ct |= TCG_CT_CONST_NEG;
70
- break;
71
- case 'Z':
72
- ct->ct |= TCG_CT_CONST_ZERO;
73
- break;
74
+#define ALL_GENERAL_REGS 0xffffu
75
76
- case 'r':
77
- ct->regs = 0xffff;
78
- break;
79
-
80
- /* qemu_ld address */
81
- case 'l':
82
- ct->regs = 0xffff;
83
+/*
84
+ * r0-r2 will be overwritten when reading the tlb entry (softmmu only)
85
+ * and r0-r1 doing the byte swapping, so don't use these.
86
+ * r3 is removed for softmmu to avoid clashes with helper arguments.
27
+ */
87
+ */
28
+void tlb_init(CPUState *cpu);
88
#ifdef CONFIG_SOFTMMU
29
/**
89
- /* r0-r2,lr will be overwritten when reading the tlb entry,
30
* tlb_flush_page:
90
- so don't use these. */
31
* @cpu: CPU whose TLB should be flushed
91
- tcg_regset_reset_reg(ct->regs, TCG_REG_R0);
32
@@ -XXX,XX +XXX,XX @@ void tlb_set_page(CPUState *cpu, target_ulong vaddr,
92
- tcg_regset_reset_reg(ct->regs, TCG_REG_R1);
33
void probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx,
93
- tcg_regset_reset_reg(ct->regs, TCG_REG_R2);
34
uintptr_t retaddr);
94
- tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
35
#else
95
- tcg_regset_reset_reg(ct->regs, TCG_REG_R14);
36
+static inline void tlb_init(CPUState *cpu)
96
+#define ALL_QLOAD_REGS \
37
+{
97
+ (ALL_GENERAL_REGS & ~((1 << TCG_REG_R0) | (1 << TCG_REG_R1) | \
38
+}
98
+ (1 << TCG_REG_R2) | (1 << TCG_REG_R3) | \
39
static inline void tlb_flush_page(CPUState *cpu, target_ulong addr)
99
+ (1 << TCG_REG_R14)))
100
+#define ALL_QSTORE_REGS \
101
+ (ALL_GENERAL_REGS & ~((1 << TCG_REG_R0) | (1 << TCG_REG_R1) | \
102
+ (1 << TCG_REG_R2) | (1 << TCG_REG_R14) | \
103
+ ((TARGET_LONG_BITS == 64) << TCG_REG_R3)))
104
+#else
105
+#define ALL_QLOAD_REGS ALL_GENERAL_REGS
106
+#define ALL_QSTORE_REGS \
107
+ (ALL_GENERAL_REGS & ~((1 << TCG_REG_R0) | (1 << TCG_REG_R1)))
108
#endif
109
- break;
110
-
111
- /* qemu_st address & data */
112
- case 's':
113
- ct->regs = 0xffff;
114
- /* r0-r2 will be overwritten when reading the tlb entry (softmmu only)
115
- and r0-r1 doing the byte swapping, so don't use these. */
116
- tcg_regset_reset_reg(ct->regs, TCG_REG_R0);
117
- tcg_regset_reset_reg(ct->regs, TCG_REG_R1);
118
-#if defined(CONFIG_SOFTMMU)
119
- /* Avoid clashes with registers being used for helper args */
120
- tcg_regset_reset_reg(ct->regs, TCG_REG_R2);
121
-#if TARGET_LONG_BITS == 64
122
- /* Avoid clashes with registers being used for helper args */
123
- tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
124
-#endif
125
- tcg_regset_reset_reg(ct->regs, TCG_REG_R14);
126
-#endif
127
- break;
128
-
129
- default:
130
- return NULL;
131
- }
132
- return ct_str;
133
-}
134
135
static inline uint32_t rotl(uint32_t val, int n)
40
{
136
{
41
}
42
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/accel/tcg/cputlb.c
45
+++ b/accel/tcg/cputlb.c
46
@@ -XXX,XX +XXX,XX @@ QEMU_BUILD_BUG_ON(sizeof(target_ulong) > sizeof(run_on_cpu_data));
47
QEMU_BUILD_BUG_ON(NB_MMU_MODES > 16);
48
#define ALL_MMUIDX_BITS ((1 << NB_MMU_MODES) - 1)
49
50
+void tlb_init(CPUState *cpu)
51
+{
52
+}
53
+
54
/* flush_all_helper: run fn across all cpus
55
*
56
* If the wait flag is set then the src cpu's helper will be queued as
57
diff --git a/exec.c b/exec.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/exec.c
60
+++ b/exec.c
61
@@ -XXX,XX +XXX,XX @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp)
62
tcg_target_initialized = true;
63
cc->tcg_initialize();
64
}
65
+ tlb_init(cpu);
66
67
#ifndef CONFIG_USER_ONLY
68
if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
69
--
137
--
70
2.17.2
138
2.25.1
71
139
72
140
diff view generated by jsdifflib
1
From: "Emilio G. Cota" <cota@braap.org>
1
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2
3
As far as I can tell tlb_flush does not need to be called
4
this early. tlb_flush is eventually called after the CPU
5
has been realized.
6
7
This change paves the way to the introduction of tlb_init,
8
which will be called from cpu_exec_realizefn.
9
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Signed-off-by: Emilio G. Cota <cota@braap.org>
13
Message-Id: <20181009174557.16125-2-cota@braap.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
---
3
---
16
target/alpha/cpu.c | 1 -
4
tcg/aarch64/tcg-target-con-str.h | 24 +++++++++++++++
17
1 file changed, 1 deletion(-)
5
tcg/aarch64/tcg-target.h | 1 +
6
tcg/aarch64/tcg-target.c.inc | 51 +++++---------------------------
7
3 files changed, 33 insertions(+), 43 deletions(-)
8
create mode 100644 tcg/aarch64/tcg-target-con-str.h
18
9
19
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
10
diff --git a/tcg/aarch64/tcg-target-con-str.h b/tcg/aarch64/tcg-target-con-str.h
11
new file mode 100644
12
index XXXXXXX..XXXXXXX
13
--- /dev/null
14
+++ b/tcg/aarch64/tcg-target-con-str.h
15
@@ -XXX,XX +XXX,XX @@
16
+/* SPDX-License-Identifier: GPL-2.0-or-later */
17
+/*
18
+ * Define AArch64 target-specific operand constraints.
19
+ * Copyright (c) 2021 Linaro
20
+ */
21
+
22
+/*
23
+ * Define constraint letters for register sets:
24
+ * REGS(letter, register_mask)
25
+ */
26
+REGS('r', ALL_GENERAL_REGS)
27
+REGS('l', ALL_QLDST_REGS)
28
+REGS('w', ALL_VECTOR_REGS)
29
+
30
+/*
31
+ * Define constraint letters for constants:
32
+ * CONST(letter, TCG_CT_CONST_* bit set)
33
+ */
34
+CONST('A', TCG_CT_CONST_AIMM)
35
+CONST('L', TCG_CT_CONST_LIMM)
36
+CONST('M', TCG_CT_CONST_MONE)
37
+CONST('O', TCG_CT_CONST_ORRI)
38
+CONST('N', TCG_CT_CONST_ANDI)
39
+CONST('Z', TCG_CT_CONST_ZERO)
40
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
20
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
21
--- a/target/alpha/cpu.c
42
--- a/tcg/aarch64/tcg-target.h
22
+++ b/target/alpha/cpu.c
43
+++ b/tcg/aarch64/tcg-target.h
23
@@ -XXX,XX +XXX,XX @@ static void alpha_cpu_initfn(Object *obj)
44
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
24
CPUAlphaState *env = &cpu->env;
45
#define TCG_TARGET_NEED_LDST_LABELS
25
46
#endif
26
cs->env_ptr = env;
47
#define TCG_TARGET_NEED_POOL_LABELS
27
- tlb_flush(cs);
48
+#define TCG_TARGET_CON_STR_H
28
49
29
env->lock_addr = -1;
50
#endif /* AARCH64_TCG_TARGET_H */
30
#if defined(CONFIG_USER_ONLY)
51
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
52
index XXXXXXX..XXXXXXX 100644
53
--- a/tcg/aarch64/tcg-target.c.inc
54
+++ b/tcg/aarch64/tcg-target.c.inc
55
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
56
#define TCG_CT_CONST_ORRI 0x1000
57
#define TCG_CT_CONST_ANDI 0x2000
58
59
-/* parse target specific constraints */
60
-static const char *target_parse_constraint(TCGArgConstraint *ct,
61
- const char *ct_str, TCGType type)
62
-{
63
- switch (*ct_str++) {
64
- case 'r': /* general registers */
65
- ct->regs |= 0xffffffffu;
66
- break;
67
- case 'w': /* advsimd registers */
68
- ct->regs |= 0xffffffff00000000ull;
69
- break;
70
- case 'l': /* qemu_ld / qemu_st address, data_reg */
71
- ct->regs = 0xffffffffu;
72
+#define ALL_GENERAL_REGS 0xffffffffu
73
+#define ALL_VECTOR_REGS 0xffffffff00000000ull
74
+
75
#ifdef CONFIG_SOFTMMU
76
- /* x0 and x1 will be overwritten when reading the tlb entry,
77
- and x2, and x3 for helper args, better to avoid using them. */
78
- tcg_regset_reset_reg(ct->regs, TCG_REG_X0);
79
- tcg_regset_reset_reg(ct->regs, TCG_REG_X1);
80
- tcg_regset_reset_reg(ct->regs, TCG_REG_X2);
81
- tcg_regset_reset_reg(ct->regs, TCG_REG_X3);
82
+#define ALL_QLDST_REGS \
83
+ (ALL_GENERAL_REGS & ~((1 << TCG_REG_X0) | (1 << TCG_REG_X1) | \
84
+ (1 << TCG_REG_X2) | (1 << TCG_REG_X3)))
85
+#else
86
+#define ALL_QLDST_REGS ALL_GENERAL_REGS
87
#endif
88
- break;
89
- case 'A': /* Valid for arithmetic immediate (positive or negative). */
90
- ct->ct |= TCG_CT_CONST_AIMM;
91
- break;
92
- case 'L': /* Valid for logical immediate. */
93
- ct->ct |= TCG_CT_CONST_LIMM;
94
- break;
95
- case 'M': /* minus one */
96
- ct->ct |= TCG_CT_CONST_MONE;
97
- break;
98
- case 'O': /* vector orr/bic immediate */
99
- ct->ct |= TCG_CT_CONST_ORRI;
100
- break;
101
- case 'N': /* vector orr/bic immediate, inverted */
102
- ct->ct |= TCG_CT_CONST_ANDI;
103
- break;
104
- case 'Z': /* zero */
105
- ct->ct |= TCG_CT_CONST_ZERO;
106
- break;
107
- default:
108
- return NULL;
109
- }
110
- return ct_str;
111
-}
112
113
/* Match a constant valid for addition (12-bit, optionally shifted). */
114
static inline bool is_aimm(uint64_t val)
31
--
115
--
32
2.17.2
116
2.25.1
33
117
34
118
diff view generated by jsdifflib
1
From: "Emilio G. Cota" <cota@braap.org>
1
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2
3
Updates can come from other threads, so readers that do not
4
take tlb_lock must use atomic_read to avoid undefined
5
behaviour (UB).
6
7
This completes the conversion to tlb_lock. This conversion results
8
on average in no performance loss, as the following experiments
9
(run on an Intel i7-6700K CPU @ 4.00GHz) show.
10
11
1. aarch64 bootup+shutdown test:
12
13
- Before:
14
Performance counter stats for 'taskset -c 0 ../img/aarch64/die.sh' (10 runs):
15
16
7487.087786 task-clock (msec) # 0.998 CPUs utilized ( +- 0.12% )
17
31,574,905,303 cycles # 4.217 GHz ( +- 0.12% )
18
57,097,908,812 instructions # 1.81 insns per cycle ( +- 0.08% )
19
10,255,415,367 branches # 1369.747 M/sec ( +- 0.08% )
20
173,278,962 branch-misses # 1.69% of all branches ( +- 0.18% )
21
22
7.504481349 seconds time elapsed ( +- 0.14% )
23
24
- After:
25
Performance counter stats for 'taskset -c 0 ../img/aarch64/die.sh' (10 runs):
26
27
7462.441328 task-clock (msec) # 0.998 CPUs utilized ( +- 0.07% )
28
31,478,476,520 cycles # 4.218 GHz ( +- 0.07% )
29
57,017,330,084 instructions # 1.81 insns per cycle ( +- 0.05% )
30
10,251,929,667 branches # 1373.804 M/sec ( +- 0.05% )
31
173,023,787 branch-misses # 1.69% of all branches ( +- 0.11% )
32
33
7.474970463 seconds time elapsed ( +- 0.07% )
34
35
2. SPEC06int:
36
SPEC06int (test set)
37
[Y axis: Speedup over master]
38
1.15 +-+----+------+------+------+------+------+-------+------+------+------+------+------+------+----+-+
39
| |
40
1.1 +-+.................................+++.............................+ tlb-lock-v2 (m+++x) +-+
41
| +++ | +++ tlb-lock-v3 (spinl|ck) |
42
| +++ | | +++ +++ | | |
43
1.05 +-+....+++...........####.........|####.+++.|......|.....###....+++...........+++....###.........+-+
44
| ### ++#| # |# |# ***### +++### +++#+# | +++ | #|# ### |
45
1 +-+++***+#++++####+++#++#++++++++++#++#+*+*++#++++#+#+****+#++++###++++###++++###++++#+#++++#+#+++-+
46
| *+* # #++# *** # #### *** # * *++# ****+# *| * # ****|# |# # #|# #+# # # |
47
0.95 +-+..*.*.#....#..#.*|*..#...#..#.*|*..#.*.*..#.*|.*.#.*++*.#.*++*+#.****.#....#+#....#.#..++#.#..+-+
48
| * * # # # *|* # # # *|* # * * # *++* # * * # * * # * |* # ++# # # # *** # |
49
| * * # ++# # *+* # # # *|* # * * # * * # * * # * * # *++* # **** # ++# # * * # |
50
0.9 +-+..*.*.#...|#..#.*.*..#.++#..#.*|*..#.*.*..#.*..*.#.*..*.#.*..*.#.*..*.#.*.|*.#...|#.#..*.*.#..+-+
51
| * * # *** # * * # |# # *+* # * * # * * # * * # * * # * * # *++* # |# # * * # |
52
0.85 +-+..*.*.#..*|*..#.*.*..#.***..#.*.*..#.*.*..#.*..*.#.*..*.#.*..*.#.*..*.#.*..*.#.****.#..*.*.#..+-+
53
| * * # *+* # * * # *|* # * * # * * # * * # * * # * * # * * # * * # * |* # * * # |
54
| * * # * * # * * # *+* # * * # * * # * * # * * # * * # * * # * * # * |* # * * # |
55
0.8 +-+..*.*.#..*.*..#.*.*..#.*.*..#.*.*..#.*.*..#.*..*.#.*..*.#.*..*.#.*..*.#.*..*.#.*++*.#..*.*.#..+-+
56
| * * # * * # * * # * * # * * # * * # * * # * * # * * # * * # * * # * * # * * # |
57
0.75 +-+--***##--***###-***###-***###-***###-***###-****##-****##-****##-****##-****##-****##--***##--+-+
58
400.perlben401.bzip2403.gcc429.m445.gob456.hmme45462.libqua464.h26471.omnet473483.xalancbmkgeomean
59
60
png: https://imgur.com/a/BHzpPTW
61
62
Notes:
63
- tlb-lock-v2 corresponds to an implementation with a mutex.
64
- tlb-lock-v3 corresponds to the current implementation, i.e.
65
a spinlock and a single lock acquisition in tlb_set_page_with_attrs.
66
67
Signed-off-by: Emilio G. Cota <cota@braap.org>
68
Message-Id: <20181016153840.25877-1-cota@braap.org>
69
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
70
---
3
---
71
accel/tcg/softmmu_template.h | 12 ++++++------
4
tcg/ppc/tcg-target-con-str.h | 30 +++++++++++++++
72
include/exec/cpu_ldst.h | 11 ++++++++++-
5
tcg/ppc/tcg-target.h | 1 +
73
include/exec/cpu_ldst_template.h | 2 +-
6
tcg/ppc/tcg-target.c.inc | 73 ++++++++----------------------------
74
accel/tcg/cputlb.c | 19 +++++++++++++------
7
3 files changed, 46 insertions(+), 58 deletions(-)
75
4 files changed, 30 insertions(+), 14 deletions(-)
8
create mode 100644 tcg/ppc/tcg-target-con-str.h
76
9
77
diff --git a/accel/tcg/softmmu_template.h b/accel/tcg/softmmu_template.h
10
diff --git a/tcg/ppc/tcg-target-con-str.h b/tcg/ppc/tcg-target-con-str.h
11
new file mode 100644
12
index XXXXXXX..XXXXXXX
13
--- /dev/null
14
+++ b/tcg/ppc/tcg-target-con-str.h
15
@@ -XXX,XX +XXX,XX @@
16
+/* SPDX-License-Identifier: MIT */
17
+/*
18
+ * Define PowerPC target-specific operand constraints.
19
+ * Copyright (c) 2021 Linaro
20
+ */
21
+
22
+/*
23
+ * Define constraint letters for register sets:
24
+ * REGS(letter, register_mask)
25
+ */
26
+REGS('r', ALL_GENERAL_REGS)
27
+REGS('v', ALL_VECTOR_REGS)
28
+REGS('A', 1u << TCG_REG_R3)
29
+REGS('B', 1u << TCG_REG_R4)
30
+REGS('C', 1u << TCG_REG_R5)
31
+REGS('D', 1u << TCG_REG_R6)
32
+REGS('L', ALL_QLOAD_REGS)
33
+REGS('S', ALL_QSTORE_REGS)
34
+
35
+/*
36
+ * Define constraint letters for constants:
37
+ * CONST(letter, TCG_CT_CONST_* bit set)
38
+ */
39
+CONST('I', TCG_CT_CONST_S16)
40
+CONST('J', TCG_CT_CONST_U16)
41
+CONST('M', TCG_CT_CONST_MONE)
42
+CONST('T', TCG_CT_CONST_S32)
43
+CONST('U', TCG_CT_CONST_U32)
44
+CONST('W', TCG_CT_CONST_WSZ)
45
+CONST('Z', TCG_CT_CONST_ZERO)
46
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
78
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
79
--- a/accel/tcg/softmmu_template.h
48
--- a/tcg/ppc/tcg-target.h
80
+++ b/accel/tcg/softmmu_template.h
49
+++ b/tcg/ppc/tcg-target.h
81
@@ -XXX,XX +XXX,XX @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
50
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
82
uintptr_t mmu_idx = get_mmuidx(oi);
51
#define TCG_TARGET_NEED_LDST_LABELS
83
uintptr_t index = tlb_index(env, mmu_idx, addr);
52
#endif
84
CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
53
#define TCG_TARGET_NEED_POOL_LABELS
85
- target_ulong tlb_addr = entry->addr_write;
54
+#define TCG_TARGET_CON_STR_H
86
+ target_ulong tlb_addr = tlb_addr_write(entry);
55
87
unsigned a_bits = get_alignment_bits(get_memop(oi));
56
#endif
88
uintptr_t haddr;
57
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
89
90
@@ -XXX,XX +XXX,XX @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
91
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, MMU_DATA_STORE,
92
mmu_idx, retaddr);
93
}
94
- tlb_addr = entry->addr_write & ~TLB_INVALID_MASK;
95
+ tlb_addr = tlb_addr_write(entry) & ~TLB_INVALID_MASK;
96
}
97
98
/* Handle an IO access. */
99
@@ -XXX,XX +XXX,XX @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
100
cannot evict the first. */
101
page2 = (addr + DATA_SIZE) & TARGET_PAGE_MASK;
102
entry2 = tlb_entry(env, mmu_idx, page2);
103
- if (!tlb_hit_page(entry2->addr_write, page2)
104
+ if (!tlb_hit_page(tlb_addr_write(entry2), page2)
105
&& !VICTIM_TLB_HIT(addr_write, page2)) {
106
tlb_fill(ENV_GET_CPU(env), page2, DATA_SIZE, MMU_DATA_STORE,
107
mmu_idx, retaddr);
108
@@ -XXX,XX +XXX,XX @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
109
uintptr_t mmu_idx = get_mmuidx(oi);
110
uintptr_t index = tlb_index(env, mmu_idx, addr);
111
CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
112
- target_ulong tlb_addr = entry->addr_write;
113
+ target_ulong tlb_addr = tlb_addr_write(entry);
114
unsigned a_bits = get_alignment_bits(get_memop(oi));
115
uintptr_t haddr;
116
117
@@ -XXX,XX +XXX,XX @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
118
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, MMU_DATA_STORE,
119
mmu_idx, retaddr);
120
}
121
- tlb_addr = entry->addr_write & ~TLB_INVALID_MASK;
122
+ tlb_addr = tlb_addr_write(entry) & ~TLB_INVALID_MASK;
123
}
124
125
/* Handle an IO access. */
126
@@ -XXX,XX +XXX,XX @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
127
cannot evict the first. */
128
page2 = (addr + DATA_SIZE) & TARGET_PAGE_MASK;
129
entry2 = tlb_entry(env, mmu_idx, page2);
130
- if (!tlb_hit_page(entry2->addr_write, page2)
131
+ if (!tlb_hit_page(tlb_addr_write(entry2), page2)
132
&& !VICTIM_TLB_HIT(addr_write, page2)) {
133
tlb_fill(ENV_GET_CPU(env), page2, DATA_SIZE, MMU_DATA_STORE,
134
mmu_idx, retaddr);
135
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
136
index XXXXXXX..XXXXXXX 100644
58
index XXXXXXX..XXXXXXX 100644
137
--- a/include/exec/cpu_ldst.h
59
--- a/tcg/ppc/tcg-target.c.inc
138
+++ b/include/exec/cpu_ldst.h
60
+++ b/tcg/ppc/tcg-target.c.inc
139
@@ -XXX,XX +XXX,XX @@ extern __thread uintptr_t helper_retaddr;
61
@@ -XXX,XX +XXX,XX @@
140
/* The memory helpers for tcg-generated code need tcg_target_long etc. */
62
#define TCG_CT_CONST_MONE 0x2000
141
#include "tcg.h"
63
#define TCG_CT_CONST_WSZ 0x4000
142
64
143
+static inline target_ulong tlb_addr_write(const CPUTLBEntry *entry)
65
+#define ALL_GENERAL_REGS 0xffffffffu
144
+{
66
+#define ALL_VECTOR_REGS 0xffffffff00000000ull
145
+#if TCG_OVERSIZED_GUEST
67
+
146
+ return entry->addr_write;
68
+#ifdef CONFIG_SOFTMMU
69
+#define ALL_QLOAD_REGS \
70
+ (ALL_GENERAL_REGS & \
71
+ ~((1 << TCG_REG_R3) | (1 << TCG_REG_R4) | (1 << TCG_REG_R5)))
72
+#define ALL_QSTORE_REGS \
73
+ (ALL_GENERAL_REGS & ~((1 << TCG_REG_R3) | (1 << TCG_REG_R4) | \
74
+ (1 << TCG_REG_R5) | (1 << TCG_REG_R6)))
147
+#else
75
+#else
148
+ return atomic_read(&entry->addr_write);
76
+#define ALL_QLOAD_REGS (ALL_GENERAL_REGS & ~(1 << TCG_REG_R3))
77
+#define ALL_QSTORE_REGS ALL_QLOAD_REGS
149
+#endif
78
+#endif
150
+}
151
+
79
+
152
/* Find the TLB index corresponding to the mmu_idx + address pair. */
80
TCGPowerISA have_isa;
153
static inline uintptr_t tlb_index(CPUArchState *env, uintptr_t mmu_idx,
81
static bool have_isel;
154
target_ulong addr)
82
bool have_altivec;
155
@@ -XXX,XX +XXX,XX @@ static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
83
@@ -XXX,XX +XXX,XX @@ static bool reloc_pc14(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
156
tlb_addr = tlbentry->addr_read;
84
return false;
157
break;
158
case 1:
159
- tlb_addr = tlbentry->addr_write;
160
+ tlb_addr = tlb_addr_write(tlbentry);
161
break;
162
case 2:
163
tlb_addr = tlbentry->addr_code;
164
diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_template.h
165
index XXXXXXX..XXXXXXX 100644
166
--- a/include/exec/cpu_ldst_template.h
167
+++ b/include/exec/cpu_ldst_template.h
168
@@ -XXX,XX +XXX,XX @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
169
addr = ptr;
170
mmu_idx = CPU_MMU_INDEX;
171
entry = tlb_entry(env, mmu_idx, addr);
172
- if (unlikely(entry->addr_write !=
173
+ if (unlikely(tlb_addr_write(entry) !=
174
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
175
oi = make_memop_idx(SHIFT, mmu_idx);
176
glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, v, oi,
177
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
178
index XXXXXXX..XXXXXXX 100644
179
--- a/accel/tcg/cputlb.c
180
+++ b/accel/tcg/cputlb.c
181
@@ -XXX,XX +XXX,XX @@ static inline bool tlb_hit_page_anyprot(CPUTLBEntry *tlb_entry,
182
target_ulong page)
183
{
184
return tlb_hit_page(tlb_entry->addr_read, page) ||
185
- tlb_hit_page(tlb_entry->addr_write, page) ||
186
+ tlb_hit_page(tlb_addr_write(tlb_entry), page) ||
187
tlb_hit_page(tlb_entry->addr_code, page);
188
}
85
}
189
86
190
@@ -XXX,XX +XXX,XX @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
87
-/* parse target specific constraints */
191
tlb_fill(cpu, addr, size, MMU_DATA_STORE, mmu_idx, retaddr);
88
-static const char *target_parse_constraint(TCGArgConstraint *ct,
192
89
- const char *ct_str, TCGType type)
193
entry = tlb_entry(env, mmu_idx, addr);
90
-{
194
- tlb_addr = entry->addr_write;
91
- switch (*ct_str++) {
195
+ tlb_addr = tlb_addr_write(entry);
92
- case 'A': case 'B': case 'C': case 'D':
196
if (!(tlb_addr & ~(TARGET_PAGE_MASK | TLB_RECHECK))) {
93
- tcg_regset_set_reg(ct->regs, 3 + ct_str[0] - 'A');
197
/* RAM access */
94
- break;
198
uintptr_t haddr = addr + entry->addend;
95
- case 'r':
199
@@ -XXX,XX +XXX,XX @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
96
- ct->regs = 0xffffffff;
200
assert_cpu_is_self(ENV_GET_CPU(env));
97
- break;
201
for (vidx = 0; vidx < CPU_VTLB_SIZE; ++vidx) {
98
- case 'v':
202
CPUTLBEntry *vtlb = &env->tlb_v_table[mmu_idx][vidx];
99
- ct->regs = 0xffffffff00000000ull;
203
- target_ulong cmp = *(target_ulong *)((uintptr_t)vtlb + elt_ofs);
100
- break;
204
+ target_ulong cmp;
101
- case 'L': /* qemu_ld constraint */
205
+
102
- ct->regs = 0xffffffff;
206
+ /* elt_ofs might correspond to .addr_write, so use atomic_read */
103
- tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
207
+#if TCG_OVERSIZED_GUEST
104
-#ifdef CONFIG_SOFTMMU
208
+ cmp = *(target_ulong *)((uintptr_t)vtlb + elt_ofs);
105
- tcg_regset_reset_reg(ct->regs, TCG_REG_R4);
209
+#else
106
- tcg_regset_reset_reg(ct->regs, TCG_REG_R5);
210
+ cmp = atomic_read((target_ulong *)((uintptr_t)vtlb + elt_ofs));
107
-#endif
211
+#endif
108
- break;
212
109
- case 'S': /* qemu_st constraint */
213
if (cmp == page) {
110
- ct->regs = 0xffffffff;
214
/* Found entry in victim tlb, swap tlb and iotlb. */
111
- tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
215
@@ -XXX,XX +XXX,XX @@ void probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx,
112
-#ifdef CONFIG_SOFTMMU
216
uintptr_t index = tlb_index(env, mmu_idx, addr);
113
- tcg_regset_reset_reg(ct->regs, TCG_REG_R4);
217
CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
114
- tcg_regset_reset_reg(ct->regs, TCG_REG_R5);
218
115
- tcg_regset_reset_reg(ct->regs, TCG_REG_R6);
219
- if (!tlb_hit(entry->addr_write, addr)) {
116
-#endif
220
+ if (!tlb_hit(tlb_addr_write(entry), addr)) {
117
- break;
221
/* TLB entry is for a different page */
118
- case 'I':
222
if (!VICTIM_TLB_HIT(addr_write, addr)) {
119
- ct->ct |= TCG_CT_CONST_S16;
223
tlb_fill(ENV_GET_CPU(env), addr, size, MMU_DATA_STORE,
120
- break;
224
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
121
- case 'J':
225
size_t mmu_idx = get_mmuidx(oi);
122
- ct->ct |= TCG_CT_CONST_U16;
226
uintptr_t index = tlb_index(env, mmu_idx, addr);
123
- break;
227
CPUTLBEntry *tlbe = tlb_entry(env, mmu_idx, addr);
124
- case 'M':
228
- target_ulong tlb_addr = tlbe->addr_write;
125
- ct->ct |= TCG_CT_CONST_MONE;
229
+ target_ulong tlb_addr = tlb_addr_write(tlbe);
126
- break;
230
TCGMemOp mop = get_memop(oi);
127
- case 'T':
231
int a_bits = get_alignment_bits(mop);
128
- ct->ct |= TCG_CT_CONST_S32;
232
int s_bits = mop & MO_SIZE;
129
- break;
233
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
130
- case 'U':
234
tlb_fill(ENV_GET_CPU(env), addr, 1 << s_bits, MMU_DATA_STORE,
131
- ct->ct |= TCG_CT_CONST_U32;
235
mmu_idx, retaddr);
132
- break;
236
}
133
- case 'W':
237
- tlb_addr = tlbe->addr_write & ~TLB_INVALID_MASK;
134
- ct->ct |= TCG_CT_CONST_WSZ;
238
+ tlb_addr = tlb_addr_write(tlbe) & ~TLB_INVALID_MASK;
135
- break;
239
}
136
- case 'Z':
240
137
- ct->ct |= TCG_CT_CONST_ZERO;
241
/* Notice an IO access or a needs-MMU-lookup access */
138
- break;
139
- default:
140
- return NULL;
141
- }
142
- return ct_str;
143
-}
144
-
145
/* test if a constant matches the constraint */
146
static int tcg_target_const_match(tcg_target_long val, TCGType type,
147
const TCGArgConstraint *arg_ct)
242
--
148
--
243
2.17.2
149
2.25.1
244
150
245
151
diff view generated by jsdifflib
1
Reviewed-by: David Hildenbrand <david@redhat.com>
1
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
---
4
target/s390x/mem_helper.c | 128 ++++++++++++++++++--------------------
5
tcg/tci/tcg-target-con-str.h | 11 +++++++++++
5
1 file changed, 61 insertions(+), 67 deletions(-)
6
tcg/tci/tcg-target.h | 2 ++
7
tcg/tci/tcg-target.c.inc | 14 --------------
8
3 files changed, 13 insertions(+), 14 deletions(-)
9
create mode 100644 tcg/tci/tcg-target-con-str.h
6
10
7
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
11
diff --git a/tcg/tci/tcg-target-con-str.h b/tcg/tci/tcg-target-con-str.h
12
new file mode 100644
13
index XXXXXXX..XXXXXXX
14
--- /dev/null
15
+++ b/tcg/tci/tcg-target-con-str.h
16
@@ -XXX,XX +XXX,XX @@
17
+/* SPDX-License-Identifier: MIT */
18
+/*
19
+ * Define TCI target-specific operand constraints.
20
+ * Copyright (c) 2021 Linaro
21
+ */
22
+
23
+/*
24
+ * Define constraint letters for register sets:
25
+ * REGS(letter, register_mask)
26
+ */
27
+REGS('r', MAKE_64BIT_MASK(0, TCG_TARGET_NB_REGS))
28
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
8
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
9
--- a/target/s390x/mem_helper.c
30
--- a/tcg/tci/tcg-target.h
10
+++ b/target/s390x/mem_helper.c
31
+++ b/tcg/tci/tcg-target.h
11
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(trXX)(CPUS390XState *env, uint32_t r1, uint32_t r2,
32
@@ -XXX,XX +XXX,XX @@ static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
12
return cc;
33
/* no need to flush icache explicitly */
13
}
34
}
14
35
15
-static void do_cdsg(CPUS390XState *env, uint64_t addr,
36
+#define TCG_TARGET_CON_STR_H
16
- uint32_t r1, uint32_t r3, bool parallel)
17
+void HELPER(cdsg)(CPUS390XState *env, uint64_t addr,
18
+ uint32_t r1, uint32_t r3)
19
{
20
uintptr_t ra = GETPC();
21
Int128 cmpv = int128_make128(env->regs[r1 + 1], env->regs[r1]);
22
Int128 newv = int128_make128(env->regs[r3 + 1], env->regs[r3]);
23
Int128 oldv;
24
+ uint64_t oldh, oldl;
25
bool fail;
26
27
- if (parallel) {
28
-#if !HAVE_CMPXCHG128
29
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
30
-#else
31
- int mem_idx = cpu_mmu_index(env, false);
32
- TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
33
- oldv = helper_atomic_cmpxchgo_be_mmu(env, addr, cmpv, newv, oi, ra);
34
- fail = !int128_eq(oldv, cmpv);
35
-#endif
36
- } else {
37
- uint64_t oldh, oldl;
38
+ check_alignment(env, addr, 16, ra);
39
40
- check_alignment(env, addr, 16, ra);
41
+ oldh = cpu_ldq_data_ra(env, addr + 0, ra);
42
+ oldl = cpu_ldq_data_ra(env, addr + 8, ra);
43
44
- oldh = cpu_ldq_data_ra(env, addr + 0, ra);
45
- oldl = cpu_ldq_data_ra(env, addr + 8, ra);
46
-
47
- oldv = int128_make128(oldl, oldh);
48
- fail = !int128_eq(oldv, cmpv);
49
- if (fail) {
50
- newv = oldv;
51
- }
52
-
53
- cpu_stq_data_ra(env, addr + 0, int128_gethi(newv), ra);
54
- cpu_stq_data_ra(env, addr + 8, int128_getlo(newv), ra);
55
+ oldv = int128_make128(oldl, oldh);
56
+ fail = !int128_eq(oldv, cmpv);
57
+ if (fail) {
58
+ newv = oldv;
59
}
60
61
+ cpu_stq_data_ra(env, addr + 0, int128_gethi(newv), ra);
62
+ cpu_stq_data_ra(env, addr + 8, int128_getlo(newv), ra);
63
+
37
+
64
env->cc_op = fail;
38
#endif /* TCG_TARGET_H */
65
env->regs[r1] = int128_gethi(oldv);
39
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
66
env->regs[r1 + 1] = int128_getlo(oldv);
40
index XXXXXXX..XXXXXXX 100644
41
--- a/tcg/tci/tcg-target.c.inc
42
+++ b/tcg/tci/tcg-target.c.inc
43
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
44
return true;
67
}
45
}
68
46
69
-void HELPER(cdsg)(CPUS390XState *env, uint64_t addr,
47
-/* Parse target specific constraints. */
70
- uint32_t r1, uint32_t r3)
48
-static const char *target_parse_constraint(TCGArgConstraint *ct,
49
- const char *ct_str, TCGType type)
71
-{
50
-{
72
- do_cdsg(env, addr, r1, r3, false);
51
- switch (*ct_str++) {
52
- case 'r':
53
- ct->regs = BIT(TCG_TARGET_NB_REGS) - 1;
54
- break;
55
- default:
56
- return NULL;
57
- }
58
- return ct_str;
73
-}
59
-}
74
-
60
-
75
void HELPER(cdsg_parallel)(CPUS390XState *env, uint64_t addr,
61
#if defined(CONFIG_DEBUG_TCG_INTERPRETER)
76
uint32_t r1, uint32_t r3)
62
/* Show current bytecode. Used by tcg interpreter. */
77
{
63
void tci_disas(uint8_t opc)
78
- do_cdsg(env, addr, r1, r3, true);
79
+ uintptr_t ra = GETPC();
80
+ Int128 cmpv = int128_make128(env->regs[r1 + 1], env->regs[r1]);
81
+ Int128 newv = int128_make128(env->regs[r3 + 1], env->regs[r3]);
82
+ int mem_idx;
83
+ TCGMemOpIdx oi;
84
+ Int128 oldv;
85
+ bool fail;
86
+
87
+ if (!HAVE_CMPXCHG128) {
88
+ cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
89
+ }
90
+
91
+ mem_idx = cpu_mmu_index(env, false);
92
+ oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
93
+ oldv = helper_atomic_cmpxchgo_be_mmu(env, addr, cmpv, newv, oi, ra);
94
+ fail = !int128_eq(oldv, cmpv);
95
+
96
+ env->cc_op = fail;
97
+ env->regs[r1] = int128_gethi(oldv);
98
+ env->regs[r1 + 1] = int128_getlo(oldv);
99
}
100
101
static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
102
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
103
#endif
104
105
/* load pair from quadword */
106
-static uint64_t do_lpq(CPUS390XState *env, uint64_t addr, bool parallel)
107
+uint64_t HELPER(lpq)(CPUS390XState *env, uint64_t addr)
108
{
109
uintptr_t ra = GETPC();
110
uint64_t hi, lo;
111
112
- if (!parallel) {
113
- check_alignment(env, addr, 16, ra);
114
- hi = cpu_ldq_data_ra(env, addr + 0, ra);
115
- lo = cpu_ldq_data_ra(env, addr + 8, ra);
116
- } else if (HAVE_ATOMIC128) {
117
+ check_alignment(env, addr, 16, ra);
118
+ hi = cpu_ldq_data_ra(env, addr + 0, ra);
119
+ lo = cpu_ldq_data_ra(env, addr + 8, ra);
120
+
121
+ env->retxl = lo;
122
+ return hi;
123
+}
124
+
125
+uint64_t HELPER(lpq_parallel)(CPUS390XState *env, uint64_t addr)
126
+{
127
+ uintptr_t ra = GETPC();
128
+ uint64_t hi, lo;
129
+
130
+ if (HAVE_ATOMIC128) {
131
int mem_idx = cpu_mmu_index(env, false);
132
TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
133
Int128 v = helper_atomic_ldo_be_mmu(env, addr, oi, ra);
134
@@ -XXX,XX +XXX,XX @@ static uint64_t do_lpq(CPUS390XState *env, uint64_t addr, bool parallel)
135
return hi;
136
}
137
138
-uint64_t HELPER(lpq)(CPUS390XState *env, uint64_t addr)
139
-{
140
- return do_lpq(env, addr, false);
141
-}
142
-
143
-uint64_t HELPER(lpq_parallel)(CPUS390XState *env, uint64_t addr)
144
-{
145
- return do_lpq(env, addr, true);
146
-}
147
-
148
/* store pair to quadword */
149
-static void do_stpq(CPUS390XState *env, uint64_t addr,
150
- uint64_t low, uint64_t high, bool parallel)
151
+void HELPER(stpq)(CPUS390XState *env, uint64_t addr,
152
+ uint64_t low, uint64_t high)
153
{
154
uintptr_t ra = GETPC();
155
156
- if (!parallel) {
157
- check_alignment(env, addr, 16, ra);
158
- cpu_stq_data_ra(env, addr + 0, high, ra);
159
- cpu_stq_data_ra(env, addr + 8, low, ra);
160
- } else if (HAVE_ATOMIC128) {
161
+ check_alignment(env, addr, 16, ra);
162
+ cpu_stq_data_ra(env, addr + 0, high, ra);
163
+ cpu_stq_data_ra(env, addr + 8, low, ra);
164
+}
165
+
166
+void HELPER(stpq_parallel)(CPUS390XState *env, uint64_t addr,
167
+ uint64_t low, uint64_t high)
168
+{
169
+ uintptr_t ra = GETPC();
170
+
171
+ if (HAVE_ATOMIC128) {
172
int mem_idx = cpu_mmu_index(env, false);
173
TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
174
Int128 v = int128_make128(low, high);
175
@@ -XXX,XX +XXX,XX @@ static void do_stpq(CPUS390XState *env, uint64_t addr,
176
}
177
}
178
179
-void HELPER(stpq)(CPUS390XState *env, uint64_t addr,
180
- uint64_t low, uint64_t high)
181
-{
182
- do_stpq(env, addr, low, high, false);
183
-}
184
-
185
-void HELPER(stpq_parallel)(CPUS390XState *env, uint64_t addr,
186
- uint64_t low, uint64_t high)
187
-{
188
- do_stpq(env, addr, low, high, true);
189
-}
190
-
191
/* Execute instruction. This instruction executes an insn modified with
192
the contents of r1. It does not change the executed instruction in memory;
193
it does not change the program counter.
194
--
64
--
195
2.17.2
65
2.25.1
196
66
197
67
diff view generated by jsdifflib
1
Reviewed-by: Emilio G. Cota <cota@braap.org>
1
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
---
4
target/arm/helper-a64.c | 259 +++++++++++++++++++++-------------------
5
tcg/mips/tcg-target-con-str.h | 24 +++++++++++
5
1 file changed, 133 insertions(+), 126 deletions(-)
6
tcg/mips/tcg-target.h | 1 +
7
tcg/mips/tcg-target.c.inc | 77 ++++++++++-------------------------
8
3 files changed, 46 insertions(+), 56 deletions(-)
9
create mode 100644 tcg/mips/tcg-target-con-str.h
6
10
7
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
11
diff --git a/tcg/mips/tcg-target-con-str.h b/tcg/mips/tcg-target-con-str.h
12
new file mode 100644
13
index XXXXXXX..XXXXXXX
14
--- /dev/null
15
+++ b/tcg/mips/tcg-target-con-str.h
16
@@ -XXX,XX +XXX,XX @@
17
+/* SPDX-License-Identifier: MIT */
18
+/*
19
+ * Define MIPS target-specific operand constraints.
20
+ * Copyright (c) 2021 Linaro
21
+ */
22
+
23
+/*
24
+ * Define constraint letters for register sets:
25
+ * REGS(letter, register_mask)
26
+ */
27
+REGS('r', ALL_GENERAL_REGS)
28
+REGS('L', ALL_QLOAD_REGS)
29
+REGS('S', ALL_QSTORE_REGS)
30
+
31
+/*
32
+ * Define constraint letters for constants:
33
+ * CONST(letter, TCG_CT_CONST_* bit set)
34
+ */
35
+CONST('I', TCG_CT_CONST_U16)
36
+CONST('J', TCG_CT_CONST_S16)
37
+CONST('K', TCG_CT_CONST_P2M1)
38
+CONST('N', TCG_CT_CONST_N16)
39
+CONST('W', TCG_CT_CONST_WSZ)
40
+CONST('Z', TCG_CT_CONST_ZERO)
41
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
8
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
9
--- a/target/arm/helper-a64.c
43
--- a/tcg/mips/tcg-target.h
10
+++ b/target/arm/helper-a64.c
44
+++ b/tcg/mips/tcg-target.h
11
@@ -XXX,XX +XXX,XX @@
45
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
12
#include "exec/exec-all.h"
46
#ifdef CONFIG_SOFTMMU
13
#include "exec/cpu_ldst.h"
47
#define TCG_TARGET_NEED_LDST_LABELS
14
#include "qemu/int128.h"
48
#endif
15
+#include "qemu/atomic128.h"
49
+#define TCG_TARGET_CON_STR_H
16
#include "tcg.h"
50
17
#include "fpu/softfloat.h"
51
#endif
18
#include <zlib.h> /* For crc32 */
52
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
19
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(crc32c_64)(uint64_t acc, uint64_t val, uint32_t bytes)
53
index XXXXXXX..XXXXXXX 100644
20
return crc32c(acc, buf, bytes) ^ 0xffffffff;
54
--- a/tcg/mips/tcg-target.c.inc
55
+++ b/tcg/mips/tcg-target.c.inc
56
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
57
#define TCG_CT_CONST_N16 0x1000 /* "Negatable" 16-bit: -32767 - 32767 */
58
#define TCG_CT_CONST_WSZ 0x2000 /* word size */
59
60
+#define ALL_GENERAL_REGS 0xffffffffu
61
+#define NOA0_REGS (ALL_GENERAL_REGS & ~(1 << TCG_REG_A0))
62
+
63
+#ifdef CONFIG_SOFTMMU
64
+#define ALL_QLOAD_REGS \
65
+ (NOA0_REGS & ~((TCG_TARGET_REG_BITS < TARGET_LONG_BITS) << TCG_REG_A2))
66
+#define ALL_QSTORE_REGS \
67
+ (NOA0_REGS & ~(TCG_TARGET_REG_BITS < TARGET_LONG_BITS \
68
+ ? (1 << TCG_REG_A2) | (1 << TCG_REG_A3) \
69
+ : (1 << TCG_REG_A1)))
70
+#else
71
+#define ALL_QLOAD_REGS NOA0_REGS
72
+#define ALL_QSTORE_REGS NOA0_REGS
73
+#endif
74
+
75
+
76
static inline bool is_p2m1(tcg_target_long val)
77
{
78
return val && ((val + 1) & val) == 0;
21
}
79
}
22
80
23
-/* Returns 0 on success; 1 otherwise. */
81
-/* parse target specific constraints */
24
-static uint64_t do_paired_cmpxchg64_le(CPUARMState *env, uint64_t addr,
82
-static const char *target_parse_constraint(TCGArgConstraint *ct,
25
- uint64_t new_lo, uint64_t new_hi,
83
- const char *ct_str, TCGType type)
26
- bool parallel, uintptr_t ra)
84
-{
27
+uint64_t HELPER(paired_cmpxchg64_le)(CPUARMState *env, uint64_t addr,
85
- switch(*ct_str++) {
28
+ uint64_t new_lo, uint64_t new_hi)
86
- case 'r':
29
{
87
- ct->regs = 0xffffffff;
30
- Int128 oldv, cmpv, newv;
88
- break;
31
+ Int128 cmpv = int128_make128(env->exclusive_val, env->exclusive_high);
89
- case 'L': /* qemu_ld input arg constraint */
32
+ Int128 newv = int128_make128(new_lo, new_hi);
90
- ct->regs = 0xffffffff;
33
+ Int128 oldv;
91
- tcg_regset_reset_reg(ct->regs, TCG_REG_A0);
34
+ uintptr_t ra = GETPC();
92
-#if defined(CONFIG_SOFTMMU)
35
+ uint64_t o0, o1;
93
- if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
36
bool success;
94
- tcg_regset_reset_reg(ct->regs, TCG_REG_A2);
37
38
- cmpv = int128_make128(env->exclusive_val, env->exclusive_high);
39
- newv = int128_make128(new_lo, new_hi);
40
-
41
- if (parallel) {
42
-#ifndef CONFIG_ATOMIC128
43
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
44
-#else
45
- int mem_idx = cpu_mmu_index(env, false);
46
- TCGMemOpIdx oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
47
- oldv = helper_atomic_cmpxchgo_le_mmu(env, addr, cmpv, newv, oi, ra);
48
- success = int128_eq(oldv, cmpv);
49
-#endif
50
- } else {
51
- uint64_t o0, o1;
52
-
53
#ifdef CONFIG_USER_ONLY
54
- /* ??? Enforce alignment. */
55
- uint64_t *haddr = g2h(addr);
56
+ /* ??? Enforce alignment. */
57
+ uint64_t *haddr = g2h(addr);
58
59
- helper_retaddr = ra;
60
- o0 = ldq_le_p(haddr + 0);
61
- o1 = ldq_le_p(haddr + 1);
62
- oldv = int128_make128(o0, o1);
63
+ helper_retaddr = ra;
64
+ o0 = ldq_le_p(haddr + 0);
65
+ o1 = ldq_le_p(haddr + 1);
66
+ oldv = int128_make128(o0, o1);
67
68
- success = int128_eq(oldv, cmpv);
69
- if (success) {
70
- stq_le_p(haddr + 0, int128_getlo(newv));
71
- stq_le_p(haddr + 1, int128_gethi(newv));
72
- }
73
- helper_retaddr = 0;
74
-#else
75
- int mem_idx = cpu_mmu_index(env, false);
76
- TCGMemOpIdx oi0 = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
77
- TCGMemOpIdx oi1 = make_memop_idx(MO_LEQ, mem_idx);
78
-
79
- o0 = helper_le_ldq_mmu(env, addr + 0, oi0, ra);
80
- o1 = helper_le_ldq_mmu(env, addr + 8, oi1, ra);
81
- oldv = int128_make128(o0, o1);
82
-
83
- success = int128_eq(oldv, cmpv);
84
- if (success) {
85
- helper_le_stq_mmu(env, addr + 0, int128_getlo(newv), oi1, ra);
86
- helper_le_stq_mmu(env, addr + 8, int128_gethi(newv), oi1, ra);
87
- }
95
- }
88
-#endif
96
-#endif
89
+ success = int128_eq(oldv, cmpv);
97
- break;
90
+ if (success) {
98
- case 'S': /* qemu_st constraint */
91
+ stq_le_p(haddr + 0, int128_getlo(newv));
99
- ct->regs = 0xffffffff;
92
+ stq_le_p(haddr + 1, int128_gethi(newv));
100
- tcg_regset_reset_reg(ct->regs, TCG_REG_A0);
93
}
101
-#if defined(CONFIG_SOFTMMU)
94
+ helper_retaddr = 0;
102
- if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
95
+#else
103
- tcg_regset_reset_reg(ct->regs, TCG_REG_A2);
96
+ int mem_idx = cpu_mmu_index(env, false);
104
- tcg_regset_reset_reg(ct->regs, TCG_REG_A3);
97
+ TCGMemOpIdx oi0 = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
105
- } else {
98
+ TCGMemOpIdx oi1 = make_memop_idx(MO_LEQ, mem_idx);
106
- tcg_regset_reset_reg(ct->regs, TCG_REG_A1);
99
+
107
- }
100
+ o0 = helper_le_ldq_mmu(env, addr + 0, oi0, ra);
108
-#endif
101
+ o1 = helper_le_ldq_mmu(env, addr + 8, oi1, ra);
109
- break;
102
+ oldv = int128_make128(o0, o1);
110
- case 'I':
103
+
111
- ct->ct |= TCG_CT_CONST_U16;
104
+ success = int128_eq(oldv, cmpv);
112
- break;
105
+ if (success) {
113
- case 'J':
106
+ helper_le_stq_mmu(env, addr + 0, int128_getlo(newv), oi1, ra);
114
- ct->ct |= TCG_CT_CONST_S16;
107
+ helper_le_stq_mmu(env, addr + 8, int128_gethi(newv), oi1, ra);
115
- break;
108
+ }
116
- case 'K':
109
+#endif
117
- ct->ct |= TCG_CT_CONST_P2M1;
110
118
- break;
111
return !success;
119
- case 'N':
112
}
120
- ct->ct |= TCG_CT_CONST_N16;
113
121
- break;
114
-uint64_t HELPER(paired_cmpxchg64_le)(CPUARMState *env, uint64_t addr,
122
- case 'W':
115
- uint64_t new_lo, uint64_t new_hi)
123
- ct->ct |= TCG_CT_CONST_WSZ;
116
-{
124
- break;
117
- return do_paired_cmpxchg64_le(env, addr, new_lo, new_hi, false, GETPC());
125
- case 'Z':
126
- /* We are cheating a bit here, using the fact that the register
127
- ZERO is also the register number 0. Hence there is no need
128
- to check for const_args in each instruction. */
129
- ct->ct |= TCG_CT_CONST_ZERO;
130
- break;
131
- default:
132
- return NULL;
133
- }
134
- return ct_str;
118
-}
135
-}
119
-
136
-
120
uint64_t HELPER(paired_cmpxchg64_le_parallel)(CPUARMState *env, uint64_t addr,
137
/* test if a constant matches the constraint */
121
uint64_t new_lo, uint64_t new_hi)
138
static inline int tcg_target_const_match(tcg_target_long val, TCGType type,
122
-{
139
const TCGArgConstraint *arg_ct)
123
- return do_paired_cmpxchg64_le(env, addr, new_lo, new_hi, true, GETPC());
140
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
124
-}
141
TCGArg a0, a1, a2;
125
-
142
int c2;
126
-static uint64_t do_paired_cmpxchg64_be(CPUARMState *env, uint64_t addr,
143
127
- uint64_t new_lo, uint64_t new_hi,
128
- bool parallel, uintptr_t ra)
129
{
130
Int128 oldv, cmpv, newv;
131
+ uintptr_t ra = GETPC();
132
bool success;
133
+ int mem_idx;
134
+ TCGMemOpIdx oi;
135
136
- /* high and low need to be switched here because this is not actually a
137
- * 128bit store but two doublewords stored consecutively
138
- */
139
- cmpv = int128_make128(env->exclusive_high, env->exclusive_val);
140
- newv = int128_make128(new_hi, new_lo);
141
-
142
- if (parallel) {
143
-#ifndef CONFIG_ATOMIC128
144
+ if (!HAVE_CMPXCHG128) {
145
cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
146
-#else
147
- int mem_idx = cpu_mmu_index(env, false);
148
- TCGMemOpIdx oi = make_memop_idx(MO_BEQ | MO_ALIGN_16, mem_idx);
149
- oldv = helper_atomic_cmpxchgo_be_mmu(env, addr, cmpv, newv, oi, ra);
150
- success = int128_eq(oldv, cmpv);
151
-#endif
152
- } else {
153
- uint64_t o0, o1;
154
-
155
-#ifdef CONFIG_USER_ONLY
156
- /* ??? Enforce alignment. */
157
- uint64_t *haddr = g2h(addr);
158
-
159
- helper_retaddr = ra;
160
- o1 = ldq_be_p(haddr + 0);
161
- o0 = ldq_be_p(haddr + 1);
162
- oldv = int128_make128(o0, o1);
163
-
164
- success = int128_eq(oldv, cmpv);
165
- if (success) {
166
- stq_be_p(haddr + 0, int128_gethi(newv));
167
- stq_be_p(haddr + 1, int128_getlo(newv));
168
- }
169
- helper_retaddr = 0;
170
-#else
171
- int mem_idx = cpu_mmu_index(env, false);
172
- TCGMemOpIdx oi0 = make_memop_idx(MO_BEQ | MO_ALIGN_16, mem_idx);
173
- TCGMemOpIdx oi1 = make_memop_idx(MO_BEQ, mem_idx);
174
-
175
- o1 = helper_be_ldq_mmu(env, addr + 0, oi0, ra);
176
- o0 = helper_be_ldq_mmu(env, addr + 8, oi1, ra);
177
- oldv = int128_make128(o0, o1);
178
-
179
- success = int128_eq(oldv, cmpv);
180
- if (success) {
181
- helper_be_stq_mmu(env, addr + 0, int128_gethi(newv), oi1, ra);
182
- helper_be_stq_mmu(env, addr + 8, int128_getlo(newv), oi1, ra);
183
- }
184
-#endif
185
}
186
187
+ mem_idx = cpu_mmu_index(env, false);
188
+ oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
189
+
190
+ cmpv = int128_make128(env->exclusive_val, env->exclusive_high);
191
+ newv = int128_make128(new_lo, new_hi);
192
+ oldv = helper_atomic_cmpxchgo_le_mmu(env, addr, cmpv, newv, oi, ra);
193
+
194
+ success = int128_eq(oldv, cmpv);
195
return !success;
196
}
197
198
uint64_t HELPER(paired_cmpxchg64_be)(CPUARMState *env, uint64_t addr,
199
uint64_t new_lo, uint64_t new_hi)
200
{
201
- return do_paired_cmpxchg64_be(env, addr, new_lo, new_hi, false, GETPC());
202
+ /*
144
+ /*
203
+ * High and low need to be switched here because this is not actually a
145
+ * Note that many operands use the constraint set "rZ".
204
+ * 128bit store but two doublewords stored consecutively
146
+ * We make use of the fact that 0 is the ZERO register,
147
+ * and hence such cases need not check for const_args.
205
+ */
148
+ */
206
+ Int128 cmpv = int128_make128(env->exclusive_val, env->exclusive_high);
149
a0 = args[0];
207
+ Int128 newv = int128_make128(new_lo, new_hi);
150
a1 = args[1];
208
+ Int128 oldv;
151
a2 = args[2];
209
+ uintptr_t ra = GETPC();
210
+ uint64_t o0, o1;
211
+ bool success;
212
+
213
+#ifdef CONFIG_USER_ONLY
214
+ /* ??? Enforce alignment. */
215
+ uint64_t *haddr = g2h(addr);
216
+
217
+ helper_retaddr = ra;
218
+ o1 = ldq_be_p(haddr + 0);
219
+ o0 = ldq_be_p(haddr + 1);
220
+ oldv = int128_make128(o0, o1);
221
+
222
+ success = int128_eq(oldv, cmpv);
223
+ if (success) {
224
+ stq_be_p(haddr + 0, int128_gethi(newv));
225
+ stq_be_p(haddr + 1, int128_getlo(newv));
226
+ }
227
+ helper_retaddr = 0;
228
+#else
229
+ int mem_idx = cpu_mmu_index(env, false);
230
+ TCGMemOpIdx oi0 = make_memop_idx(MO_BEQ | MO_ALIGN_16, mem_idx);
231
+ TCGMemOpIdx oi1 = make_memop_idx(MO_BEQ, mem_idx);
232
+
233
+ o1 = helper_be_ldq_mmu(env, addr + 0, oi0, ra);
234
+ o0 = helper_be_ldq_mmu(env, addr + 8, oi1, ra);
235
+ oldv = int128_make128(o0, o1);
236
+
237
+ success = int128_eq(oldv, cmpv);
238
+ if (success) {
239
+ helper_be_stq_mmu(env, addr + 0, int128_gethi(newv), oi1, ra);
240
+ helper_be_stq_mmu(env, addr + 8, int128_getlo(newv), oi1, ra);
241
+ }
242
+#endif
243
+
244
+ return !success;
245
}
246
247
uint64_t HELPER(paired_cmpxchg64_be_parallel)(CPUARMState *env, uint64_t addr,
248
- uint64_t new_lo, uint64_t new_hi)
249
+ uint64_t new_lo, uint64_t new_hi)
250
{
251
- return do_paired_cmpxchg64_be(env, addr, new_lo, new_hi, true, GETPC());
252
+ Int128 oldv, cmpv, newv;
253
+ uintptr_t ra = GETPC();
254
+ bool success;
255
+ int mem_idx;
256
+ TCGMemOpIdx oi;
257
+
258
+ if (!HAVE_CMPXCHG128) {
259
+ cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
260
+ }
261
+
262
+ mem_idx = cpu_mmu_index(env, false);
263
+ oi = make_memop_idx(MO_BEQ | MO_ALIGN_16, mem_idx);
264
+
265
+ /*
266
+ * High and low need to be switched here because this is not actually a
267
+ * 128bit store but two doublewords stored consecutively
268
+ */
269
+ cmpv = int128_make128(env->exclusive_high, env->exclusive_val);
270
+ newv = int128_make128(new_hi, new_lo);
271
+ oldv = helper_atomic_cmpxchgo_be_mmu(env, addr, cmpv, newv, oi, ra);
272
+
273
+ success = int128_eq(oldv, cmpv);
274
+ return !success;
275
}
276
277
/* Writes back the old data into Rs. */
278
void HELPER(casp_le_parallel)(CPUARMState *env, uint32_t rs, uint64_t addr,
279
uint64_t new_lo, uint64_t new_hi)
280
{
281
- uintptr_t ra = GETPC();
282
-#ifndef CONFIG_ATOMIC128
283
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
284
-#else
285
Int128 oldv, cmpv, newv;
286
+ uintptr_t ra = GETPC();
287
+ int mem_idx;
288
+ TCGMemOpIdx oi;
289
+
290
+ if (!HAVE_CMPXCHG128) {
291
+ cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
292
+ }
293
+
294
+ mem_idx = cpu_mmu_index(env, false);
295
+ oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
296
297
cmpv = int128_make128(env->xregs[rs], env->xregs[rs + 1]);
298
newv = int128_make128(new_lo, new_hi);
299
-
300
- int mem_idx = cpu_mmu_index(env, false);
301
- TCGMemOpIdx oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
302
oldv = helper_atomic_cmpxchgo_le_mmu(env, addr, cmpv, newv, oi, ra);
303
304
env->xregs[rs] = int128_getlo(oldv);
305
env->xregs[rs + 1] = int128_gethi(oldv);
306
-#endif
307
}
308
309
void HELPER(casp_be_parallel)(CPUARMState *env, uint32_t rs, uint64_t addr,
310
uint64_t new_hi, uint64_t new_lo)
311
{
312
- uintptr_t ra = GETPC();
313
-#ifndef CONFIG_ATOMIC128
314
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
315
-#else
316
Int128 oldv, cmpv, newv;
317
+ uintptr_t ra = GETPC();
318
+ int mem_idx;
319
+ TCGMemOpIdx oi;
320
+
321
+ if (!HAVE_CMPXCHG128) {
322
+ cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
323
+ }
324
+
325
+ mem_idx = cpu_mmu_index(env, false);
326
+ oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
327
328
cmpv = int128_make128(env->xregs[rs + 1], env->xregs[rs]);
329
newv = int128_make128(new_lo, new_hi);
330
-
331
- int mem_idx = cpu_mmu_index(env, false);
332
- TCGMemOpIdx oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
333
oldv = helper_atomic_cmpxchgo_be_mmu(env, addr, cmpv, newv, oi, ra);
334
335
env->xregs[rs + 1] = int128_getlo(oldv);
336
env->xregs[rs] = int128_gethi(oldv);
337
-#endif
338
}
339
340
/*
341
--
152
--
342
2.17.2
153
2.25.1
343
154
344
155
diff view generated by jsdifflib
1
Reviewed-by: Emilio G. Cota <cota@braap.org>
1
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
3
---
4
target/ppc/helper.h | 2 +-
4
tcg/riscv/tcg-target-con-str.h | 21 ++++++++++++++
5
target/ppc/mem_helper.c | 33 ++++++++++--
5
tcg/riscv/tcg-target.h | 1 +
6
target/ppc/translate.c | 115 +++++++++++++++++++++-------------------
6
tcg/riscv/tcg-target.c.inc | 52 +++++++++-------------------------
7
3 files changed, 88 insertions(+), 62 deletions(-)
7
3 files changed, 35 insertions(+), 39 deletions(-)
8
create mode 100644 tcg/riscv/tcg-target-con-str.h
8
9
9
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
10
diff --git a/tcg/riscv/tcg-target-con-str.h b/tcg/riscv/tcg-target-con-str.h
11
new file mode 100644
12
index XXXXXXX..XXXXXXX
13
--- /dev/null
14
+++ b/tcg/riscv/tcg-target-con-str.h
15
@@ -XXX,XX +XXX,XX @@
16
+/* SPDX-License-Identifier: MIT */
17
+/*
18
+ * Define RISC-V target-specific operand constraints.
19
+ * Copyright (c) 2021 Linaro
20
+ */
21
+
22
+/*
23
+ * Define constraint letters for register sets:
24
+ * REGS(letter, register_mask)
25
+ */
26
+REGS('r', ALL_GENERAL_REGS)
27
+REGS('L', ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS)
28
+
29
+/*
30
+ * Define constraint letters for constants:
31
+ * CONST(letter, TCG_CT_CONST_* bit set)
32
+ */
33
+CONST('I', TCG_CT_CONST_S12)
34
+CONST('N', TCG_CT_CONST_N12)
35
+CONST('M', TCG_CT_CONST_M12)
36
+CONST('Z', TCG_CT_CONST_ZERO)
37
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
10
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
11
--- a/target/ppc/helper.h
39
--- a/tcg/riscv/tcg-target.h
12
+++ b/target/ppc/helper.h
40
+++ b/tcg/riscv/tcg-target.h
13
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_4(dscliq, void, env, fprp, fprp, i32)
41
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
14
DEF_HELPER_1(tbegin, void, env)
42
#define TCG_TARGET_NEED_POOL_LABELS
15
DEF_HELPER_FLAGS_1(fixup_thrm, TCG_CALL_NO_RWG, void, env)
43
16
44
#define TCG_TARGET_HAS_MEMORY_BSWAP 0
17
-#if defined(TARGET_PPC64) && defined(CONFIG_ATOMIC128)
45
+#define TCG_TARGET_CON_STR_H
18
+#ifdef TARGET_PPC64
46
19
DEF_HELPER_FLAGS_3(lq_le_parallel, TCG_CALL_NO_WG, i64, env, tl, i32)
47
#endif
20
DEF_HELPER_FLAGS_3(lq_be_parallel, TCG_CALL_NO_WG, i64, env, tl, i32)
48
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
21
DEF_HELPER_FLAGS_5(stq_le_parallel, TCG_CALL_NO_WG,
22
diff --git a/target/ppc/mem_helper.c b/target/ppc/mem_helper.c
23
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
24
--- a/target/ppc/mem_helper.c
50
--- a/tcg/riscv/tcg-target.c.inc
25
+++ b/target/ppc/mem_helper.c
51
+++ b/tcg/riscv/tcg-target.c.inc
26
@@ -XXX,XX +XXX,XX @@
52
@@ -XXX,XX +XXX,XX @@ static const int tcg_target_call_oarg_regs[] = {
27
#include "exec/cpu_ldst.h"
53
#define TCG_CT_CONST_N12 0x400
28
#include "tcg.h"
54
#define TCG_CT_CONST_M12 0x800
29
#include "internal.h"
55
30
+#include "qemu/atomic128.h"
56
+#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32)
31
57
+/*
32
//#define DEBUG_OP
58
+ * For softmmu, we need to avoid conflicts with the first 5
33
59
+ * argument registers to call the helper. Some of these are
34
@@ -XXX,XX +XXX,XX @@ target_ulong helper_lscbx(CPUPPCState *env, target_ulong addr, uint32_t reg,
60
+ * also used for the tlb lookup.
35
return i;
61
+ */
62
+#ifdef CONFIG_SOFTMMU
63
+#define SOFTMMU_RESERVE_REGS MAKE_64BIT_MASK(TCG_REG_A0, 5)
64
+#else
65
+#define SOFTMMU_RESERVE_REGS 0
66
+#endif
67
+
68
+
69
static inline tcg_target_long sextreg(tcg_target_long val, int pos, int len)
70
{
71
if (TCG_TARGET_REG_BITS == 32) {
72
@@ -XXX,XX +XXX,XX @@ static inline tcg_target_long sextreg(tcg_target_long val, int pos, int len)
73
}
36
}
74
}
37
75
38
-#if defined(TARGET_PPC64) && defined(CONFIG_ATOMIC128)
76
-/* parse target specific constraints */
39
+#ifdef TARGET_PPC64
77
-static const char *target_parse_constraint(TCGArgConstraint *ct,
40
uint64_t helper_lq_le_parallel(CPUPPCState *env, target_ulong addr,
78
- const char *ct_str, TCGType type)
41
uint32_t opidx)
79
-{
42
{
80
- switch (*ct_str++) {
43
- Int128 ret = helper_atomic_ldo_le_mmu(env, addr, opidx, GETPC());
81
- case 'r':
44
+ Int128 ret;
82
- ct->regs = 0xffffffff;
45
+
83
- break;
46
+ /* We will have raised EXCP_ATOMIC from the translator. */
84
- case 'L':
47
+ assert(HAVE_ATOMIC128);
85
- /* qemu_ld/qemu_st constraint */
48
+ ret = helper_atomic_ldo_le_mmu(env, addr, opidx, GETPC());
86
- ct->regs = 0xffffffff;
49
env->retxh = int128_gethi(ret);
87
- /* qemu_ld/qemu_st uses TCG_REG_TMP0 */
50
return int128_getlo(ret);
88
-#if defined(CONFIG_SOFTMMU)
51
}
89
- tcg_regset_reset_reg(ct->regs, tcg_target_call_iarg_regs[0]);
52
@@ -XXX,XX +XXX,XX @@ uint64_t helper_lq_le_parallel(CPUPPCState *env, target_ulong addr,
90
- tcg_regset_reset_reg(ct->regs, tcg_target_call_iarg_regs[1]);
53
uint64_t helper_lq_be_parallel(CPUPPCState *env, target_ulong addr,
91
- tcg_regset_reset_reg(ct->regs, tcg_target_call_iarg_regs[2]);
54
uint32_t opidx)
92
- tcg_regset_reset_reg(ct->regs, tcg_target_call_iarg_regs[3]);
55
{
93
- tcg_regset_reset_reg(ct->regs, tcg_target_call_iarg_regs[4]);
56
- Int128 ret = helper_atomic_ldo_be_mmu(env, addr, opidx, GETPC());
57
+ Int128 ret;
58
+
59
+ /* We will have raised EXCP_ATOMIC from the translator. */
60
+ assert(HAVE_ATOMIC128);
61
+ ret = helper_atomic_ldo_be_mmu(env, addr, opidx, GETPC());
62
env->retxh = int128_gethi(ret);
63
return int128_getlo(ret);
64
}
65
@@ -XXX,XX +XXX,XX @@ uint64_t helper_lq_be_parallel(CPUPPCState *env, target_ulong addr,
66
void helper_stq_le_parallel(CPUPPCState *env, target_ulong addr,
67
uint64_t lo, uint64_t hi, uint32_t opidx)
68
{
69
- Int128 val = int128_make128(lo, hi);
70
+ Int128 val;
71
+
72
+ /* We will have raised EXCP_ATOMIC from the translator. */
73
+ assert(HAVE_ATOMIC128);
74
+ val = int128_make128(lo, hi);
75
helper_atomic_sto_le_mmu(env, addr, val, opidx, GETPC());
76
}
77
78
void helper_stq_be_parallel(CPUPPCState *env, target_ulong addr,
79
uint64_t lo, uint64_t hi, uint32_t opidx)
80
{
81
- Int128 val = int128_make128(lo, hi);
82
+ Int128 val;
83
+
84
+ /* We will have raised EXCP_ATOMIC from the translator. */
85
+ assert(HAVE_ATOMIC128);
86
+ val = int128_make128(lo, hi);
87
helper_atomic_sto_be_mmu(env, addr, val, opidx, GETPC());
88
}
89
90
@@ -XXX,XX +XXX,XX @@ uint32_t helper_stqcx_le_parallel(CPUPPCState *env, target_ulong addr,
91
{
92
bool success = false;
93
94
+ /* We will have raised EXCP_ATOMIC from the translator. */
95
+ assert(HAVE_CMPXCHG128);
96
+
97
if (likely(addr == env->reserve_addr)) {
98
Int128 oldv, cmpv, newv;
99
100
@@ -XXX,XX +XXX,XX @@ uint32_t helper_stqcx_be_parallel(CPUPPCState *env, target_ulong addr,
101
{
102
bool success = false;
103
104
+ /* We will have raised EXCP_ATOMIC from the translator. */
105
+ assert(HAVE_CMPXCHG128);
106
+
107
if (likely(addr == env->reserve_addr)) {
108
Int128 oldv, cmpv, newv;
109
110
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/target/ppc/translate.c
113
+++ b/target/ppc/translate.c
114
@@ -XXX,XX +XXX,XX @@
115
#include "trace-tcg.h"
116
#include "exec/translator.h"
117
#include "exec/log.h"
118
+#include "qemu/atomic128.h"
119
120
121
#define CPU_SINGLE_STEP 0x1
122
@@ -XXX,XX +XXX,XX @@ static void gen_lq(DisasContext *ctx)
123
hi = cpu_gpr[rd];
124
125
if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
126
-#ifdef CONFIG_ATOMIC128
127
- TCGv_i32 oi = tcg_temp_new_i32();
128
- if (ctx->le_mode) {
129
- tcg_gen_movi_i32(oi, make_memop_idx(MO_LEQ, ctx->mem_idx));
130
- gen_helper_lq_le_parallel(lo, cpu_env, EA, oi);
131
+ if (HAVE_ATOMIC128) {
132
+ TCGv_i32 oi = tcg_temp_new_i32();
133
+ if (ctx->le_mode) {
134
+ tcg_gen_movi_i32(oi, make_memop_idx(MO_LEQ, ctx->mem_idx));
135
+ gen_helper_lq_le_parallel(lo, cpu_env, EA, oi);
136
+ } else {
137
+ tcg_gen_movi_i32(oi, make_memop_idx(MO_BEQ, ctx->mem_idx));
138
+ gen_helper_lq_be_parallel(lo, cpu_env, EA, oi);
139
+ }
140
+ tcg_temp_free_i32(oi);
141
+ tcg_gen_ld_i64(hi, cpu_env, offsetof(CPUPPCState, retxh));
142
} else {
143
- tcg_gen_movi_i32(oi, make_memop_idx(MO_BEQ, ctx->mem_idx));
144
- gen_helper_lq_be_parallel(lo, cpu_env, EA, oi);
145
+ /* Restart with exclusive lock. */
146
+ gen_helper_exit_atomic(cpu_env);
147
+ ctx->base.is_jmp = DISAS_NORETURN;
148
}
149
- tcg_temp_free_i32(oi);
150
- tcg_gen_ld_i64(hi, cpu_env, offsetof(CPUPPCState, retxh));
151
-#else
152
- /* Restart with exclusive lock. */
153
- gen_helper_exit_atomic(cpu_env);
154
- ctx->base.is_jmp = DISAS_NORETURN;
155
-#endif
94
-#endif
156
} else if (ctx->le_mode) {
95
- break;
157
tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_LEQ);
96
- case 'I':
158
gen_addr_add(ctx, EA, EA, 8);
97
- ct->ct |= TCG_CT_CONST_S12;
159
@@ -XXX,XX +XXX,XX @@ static void gen_std(DisasContext *ctx)
98
- break;
160
hi = cpu_gpr[rs];
99
- case 'N':
161
100
- ct->ct |= TCG_CT_CONST_N12;
162
if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
101
- break;
163
-#ifdef CONFIG_ATOMIC128
102
- case 'M':
164
- TCGv_i32 oi = tcg_temp_new_i32();
103
- ct->ct |= TCG_CT_CONST_M12;
165
- if (ctx->le_mode) {
104
- break;
166
- tcg_gen_movi_i32(oi, make_memop_idx(MO_LEQ, ctx->mem_idx));
105
- case 'Z':
167
- gen_helper_stq_le_parallel(cpu_env, EA, lo, hi, oi);
106
- /* we can use a zero immediate as a zero register argument. */
168
+ if (HAVE_ATOMIC128) {
107
- ct->ct |= TCG_CT_CONST_ZERO;
169
+ TCGv_i32 oi = tcg_temp_new_i32();
108
- break;
170
+ if (ctx->le_mode) {
109
- default:
171
+ tcg_gen_movi_i32(oi, make_memop_idx(MO_LEQ, ctx->mem_idx));
110
- return NULL;
172
+ gen_helper_stq_le_parallel(cpu_env, EA, lo, hi, oi);
111
- }
173
+ } else {
112
- return ct_str;
174
+ tcg_gen_movi_i32(oi, make_memop_idx(MO_BEQ, ctx->mem_idx));
113
-}
175
+ gen_helper_stq_be_parallel(cpu_env, EA, lo, hi, oi);
114
-
176
+ }
115
/* test if a constant matches the constraint */
177
+ tcg_temp_free_i32(oi);
116
static int tcg_target_const_match(tcg_target_long val, TCGType type,
178
} else {
117
const TCGArgConstraint *arg_ct)
179
- tcg_gen_movi_i32(oi, make_memop_idx(MO_BEQ, ctx->mem_idx));
180
- gen_helper_stq_be_parallel(cpu_env, EA, lo, hi, oi);
181
+ /* Restart with exclusive lock. */
182
+ gen_helper_exit_atomic(cpu_env);
183
+ ctx->base.is_jmp = DISAS_NORETURN;
184
}
185
- tcg_temp_free_i32(oi);
186
-#else
187
- /* Restart with exclusive lock. */
188
- gen_helper_exit_atomic(cpu_env);
189
- ctx->base.is_jmp = DISAS_NORETURN;
190
-#endif
191
} else if (ctx->le_mode) {
192
tcg_gen_qemu_st_i64(lo, EA, ctx->mem_idx, MO_LEQ);
193
gen_addr_add(ctx, EA, EA, 8);
194
@@ -XXX,XX +XXX,XX @@ static void gen_lqarx(DisasContext *ctx)
195
hi = cpu_gpr[rd];
196
197
if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
198
-#ifdef CONFIG_ATOMIC128
199
- TCGv_i32 oi = tcg_temp_new_i32();
200
- if (ctx->le_mode) {
201
- tcg_gen_movi_i32(oi, make_memop_idx(MO_LEQ | MO_ALIGN_16,
202
- ctx->mem_idx));
203
- gen_helper_lq_le_parallel(lo, cpu_env, EA, oi);
204
+ if (HAVE_ATOMIC128) {
205
+ TCGv_i32 oi = tcg_temp_new_i32();
206
+ if (ctx->le_mode) {
207
+ tcg_gen_movi_i32(oi, make_memop_idx(MO_LEQ | MO_ALIGN_16,
208
+ ctx->mem_idx));
209
+ gen_helper_lq_le_parallel(lo, cpu_env, EA, oi);
210
+ } else {
211
+ tcg_gen_movi_i32(oi, make_memop_idx(MO_BEQ | MO_ALIGN_16,
212
+ ctx->mem_idx));
213
+ gen_helper_lq_be_parallel(lo, cpu_env, EA, oi);
214
+ }
215
+ tcg_temp_free_i32(oi);
216
+ tcg_gen_ld_i64(hi, cpu_env, offsetof(CPUPPCState, retxh));
217
} else {
218
- tcg_gen_movi_i32(oi, make_memop_idx(MO_BEQ | MO_ALIGN_16,
219
- ctx->mem_idx));
220
- gen_helper_lq_be_parallel(lo, cpu_env, EA, oi);
221
+ /* Restart with exclusive lock. */
222
+ gen_helper_exit_atomic(cpu_env);
223
+ ctx->base.is_jmp = DISAS_NORETURN;
224
+ tcg_temp_free(EA);
225
+ return;
226
}
227
- tcg_temp_free_i32(oi);
228
- tcg_gen_ld_i64(hi, cpu_env, offsetof(CPUPPCState, retxh));
229
-#else
230
- /* Restart with exclusive lock. */
231
- gen_helper_exit_atomic(cpu_env);
232
- ctx->base.is_jmp = DISAS_NORETURN;
233
- tcg_temp_free(EA);
234
- return;
235
-#endif
236
} else if (ctx->le_mode) {
237
tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_LEQ | MO_ALIGN_16);
238
tcg_gen_mov_tl(cpu_reserve, EA);
239
@@ -XXX,XX +XXX,XX @@ static void gen_stqcx_(DisasContext *ctx)
240
hi = cpu_gpr[rs];
241
242
if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
243
- TCGv_i32 oi = tcg_const_i32(DEF_MEMOP(MO_Q) | MO_ALIGN_16);
244
-#ifdef CONFIG_ATOMIC128
245
- if (ctx->le_mode) {
246
- gen_helper_stqcx_le_parallel(cpu_crf[0], cpu_env, EA, lo, hi, oi);
247
+ if (HAVE_CMPXCHG128) {
248
+ TCGv_i32 oi = tcg_const_i32(DEF_MEMOP(MO_Q) | MO_ALIGN_16);
249
+ if (ctx->le_mode) {
250
+ gen_helper_stqcx_le_parallel(cpu_crf[0], cpu_env,
251
+ EA, lo, hi, oi);
252
+ } else {
253
+ gen_helper_stqcx_be_parallel(cpu_crf[0], cpu_env,
254
+ EA, lo, hi, oi);
255
+ }
256
+ tcg_temp_free_i32(oi);
257
} else {
258
- gen_helper_stqcx_le_parallel(cpu_crf[0], cpu_env, EA, lo, hi, oi);
259
+ /* Restart with exclusive lock. */
260
+ gen_helper_exit_atomic(cpu_env);
261
+ ctx->base.is_jmp = DISAS_NORETURN;
262
}
263
-#else
264
- /* Restart with exclusive lock. */
265
- gen_helper_exit_atomic(cpu_env);
266
- ctx->base.is_jmp = DISAS_NORETURN;
267
-#endif
268
tcg_temp_free(EA);
269
- tcg_temp_free_i32(oi);
270
} else {
271
TCGLabel *lab_fail = gen_new_label();
272
TCGLabel *lab_over = gen_new_label();
273
--
118
--
274
2.17.2
119
2.25.1
275
120
276
121
diff view generated by jsdifflib
1
GCC7+ will no longer advertise support for 16-byte __atomic operations
1
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2
if only cmpxchg is supported, as for x86_64. Fortunately, x86_64 still
3
has support for __sync_compare_and_swap_16 and we can make use of that.
4
AArch64 does not have, nor ever has had such support, so open-code it.
5
6
Reviewed-by: Emilio G. Cota <cota@braap.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
3
---
9
accel/tcg/atomic_template.h | 20 ++++-
4
tcg/s390/tcg-target-con-str.h | 28 ++++++++++++++++++
10
include/qemu/atomic128.h | 155 ++++++++++++++++++++++++++++++++++++
5
tcg/s390/tcg-target.h | 1 +
11
tcg/tcg.h | 16 ++--
6
tcg/s390/tcg-target.c.inc | 53 +++++++++--------------------------
12
accel/tcg/cputlb.c | 3 +-
7
3 files changed, 42 insertions(+), 40 deletions(-)
13
accel/tcg/user-exec.c | 5 +-
8
create mode 100644 tcg/s390/tcg-target-con-str.h
14
configure | 19 +++++
15
6 files changed, 204 insertions(+), 14 deletions(-)
16
create mode 100644 include/qemu/atomic128.h
17
9
18
diff --git a/accel/tcg/atomic_template.h b/accel/tcg/atomic_template.h
10
diff --git a/tcg/s390/tcg-target-con-str.h b/tcg/s390/tcg-target-con-str.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/accel/tcg/atomic_template.h
21
+++ b/accel/tcg/atomic_template.h
22
@@ -XXX,XX +XXX,XX @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
23
DATA_TYPE ret;
24
25
ATOMIC_TRACE_RMW;
26
+#if DATA_SIZE == 16
27
+ ret = atomic16_cmpxchg(haddr, cmpv, newv);
28
+#else
29
ret = atomic_cmpxchg__nocheck(haddr, cmpv, newv);
30
+#endif
31
ATOMIC_MMU_CLEANUP;
32
return ret;
33
}
34
35
#if DATA_SIZE >= 16
36
+#if HAVE_ATOMIC128
37
ABI_TYPE ATOMIC_NAME(ld)(CPUArchState *env, target_ulong addr EXTRA_ARGS)
38
{
39
ATOMIC_MMU_DECLS;
40
DATA_TYPE val, *haddr = ATOMIC_MMU_LOOKUP;
41
42
ATOMIC_TRACE_LD;
43
- __atomic_load(haddr, &val, __ATOMIC_RELAXED);
44
+ val = atomic16_read(haddr);
45
ATOMIC_MMU_CLEANUP;
46
return val;
47
}
48
@@ -XXX,XX +XXX,XX @@ void ATOMIC_NAME(st)(CPUArchState *env, target_ulong addr,
49
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
50
51
ATOMIC_TRACE_ST;
52
- __atomic_store(haddr, &val, __ATOMIC_RELAXED);
53
+ atomic16_set(haddr, val);
54
ATOMIC_MMU_CLEANUP;
55
}
56
+#endif
57
#else
58
ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr,
59
ABI_TYPE val EXTRA_ARGS)
60
@@ -XXX,XX +XXX,XX @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
61
DATA_TYPE ret;
62
63
ATOMIC_TRACE_RMW;
64
+#if DATA_SIZE == 16
65
+ ret = atomic16_cmpxchg(haddr, BSWAP(cmpv), BSWAP(newv));
66
+#else
67
ret = atomic_cmpxchg__nocheck(haddr, BSWAP(cmpv), BSWAP(newv));
68
+#endif
69
ATOMIC_MMU_CLEANUP;
70
return BSWAP(ret);
71
}
72
73
#if DATA_SIZE >= 16
74
+#if HAVE_ATOMIC128
75
ABI_TYPE ATOMIC_NAME(ld)(CPUArchState *env, target_ulong addr EXTRA_ARGS)
76
{
77
ATOMIC_MMU_DECLS;
78
DATA_TYPE val, *haddr = ATOMIC_MMU_LOOKUP;
79
80
ATOMIC_TRACE_LD;
81
- __atomic_load(haddr, &val, __ATOMIC_RELAXED);
82
+ val = atomic16_read(haddr);
83
ATOMIC_MMU_CLEANUP;
84
return BSWAP(val);
85
}
86
@@ -XXX,XX +XXX,XX @@ void ATOMIC_NAME(st)(CPUArchState *env, target_ulong addr,
87
88
ATOMIC_TRACE_ST;
89
val = BSWAP(val);
90
- __atomic_store(haddr, &val, __ATOMIC_RELAXED);
91
+ atomic16_set(haddr, val);
92
ATOMIC_MMU_CLEANUP;
93
}
94
+#endif
95
#else
96
ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr,
97
ABI_TYPE val EXTRA_ARGS)
98
diff --git a/include/qemu/atomic128.h b/include/qemu/atomic128.h
99
new file mode 100644
11
new file mode 100644
100
index XXXXXXX..XXXXXXX
12
index XXXXXXX..XXXXXXX
101
--- /dev/null
13
--- /dev/null
102
+++ b/include/qemu/atomic128.h
14
+++ b/tcg/s390/tcg-target-con-str.h
103
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@
16
+/* SPDX-License-Identifier: MIT */
104
+/*
17
+/*
105
+ * Simple interface for 128-bit atomic operations.
18
+ * Define S390 target-specific operand constraints.
106
+ *
19
+ * Copyright (c) 2021 Linaro
107
+ * Copyright (C) 2018 Linaro, Ltd.
108
+ *
109
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
110
+ * See the COPYING file in the top-level directory.
111
+ *
112
+ * See docs/devel/atomics.txt for discussion about the guarantees each
113
+ * atomic primitive is meant to provide.
114
+ */
20
+ */
115
+
21
+
116
+#ifndef QEMU_ATOMIC128_H
22
+/*
117
+#define QEMU_ATOMIC128_H
23
+ * Define constraint letters for register sets:
24
+ * REGS(letter, register_mask)
25
+ */
26
+REGS('r', ALL_GENERAL_REGS)
27
+REGS('L', ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS)
28
+/*
29
+ * A (single) even/odd pair for division.
30
+ * TODO: Add something to the register allocator to allow
31
+ * this kind of regno+1 pairing to be done more generally.
32
+ */
33
+REGS('a', 1u << TCG_REG_R2)
34
+REGS('b', 1u << TCG_REG_R3)
118
+
35
+
119
+/*
36
+/*
120
+ * GCC is a house divided about supporting large atomic operations.
37
+ * Define constraint letters for constants:
121
+ *
38
+ * CONST(letter, TCG_CT_CONST_* bit set)
122
+ * For hosts that only have large compare-and-swap, a legalistic reading
123
+ * of the C++ standard means that one cannot implement __atomic_read on
124
+ * read-only memory, and thus all atomic operations must synchronize
125
+ * through libatomic.
126
+ *
127
+ * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80878
128
+ *
129
+ * This interpretation is not especially helpful for QEMU.
130
+ * For softmmu, all RAM is always read/write from the hypervisor.
131
+ * For user-only, if the guest doesn't implement such an __atomic_read
132
+ * then the host need not worry about it either.
133
+ *
134
+ * Moreover, using libatomic is not an option, because its interface is
135
+ * built for std::atomic<T>, and requires that *all* accesses to such an
136
+ * object go through the library. In our case we do not have an object
137
+ * in the C/C++ sense, but a view of memory as seen by the guest.
138
+ * The guest may issue a large atomic operation and then access those
139
+ * pieces using word-sized accesses. From the hypervisor, we have no
140
+ * way to connect those two actions.
141
+ *
142
+ * Therefore, special case each platform.
143
+ */
39
+ */
144
+
40
+CONST('A', TCG_CT_CONST_S33)
145
+#if defined(CONFIG_ATOMIC128)
41
+CONST('I', TCG_CT_CONST_S16)
146
+static inline Int128 atomic16_cmpxchg(Int128 *ptr, Int128 cmp, Int128 new)
42
+CONST('J', TCG_CT_CONST_S32)
147
+{
43
+CONST('Z', TCG_CT_CONST_ZERO)
148
+ return atomic_cmpxchg__nocheck(ptr, cmp, new);
44
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
149
+}
45
index XXXXXXX..XXXXXXX 100644
150
+# define HAVE_CMPXCHG128 1
46
--- a/tcg/s390/tcg-target.h
151
+#elif defined(CONFIG_CMPXCHG128)
47
+++ b/tcg/s390/tcg-target.h
152
+static inline Int128 atomic16_cmpxchg(Int128 *ptr, Int128 cmp, Int128 new)
48
@@ -XXX,XX +XXX,XX @@ static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
153
+{
49
#define TCG_TARGET_NEED_LDST_LABELS
154
+ return __sync_val_compare_and_swap_16(ptr, cmp, new);
50
#endif
155
+}
51
#define TCG_TARGET_NEED_POOL_LABELS
156
+# define HAVE_CMPXCHG128 1
52
+#define TCG_TARGET_CON_STR_H
157
+#elif defined(__aarch64__)
53
158
+/* Through gcc 8, aarch64 has no support for 128-bit at all. */
54
#endif
159
+static inline Int128 atomic16_cmpxchg(Int128 *ptr, Int128 cmp, Int128 new)
55
diff --git a/tcg/s390/tcg-target.c.inc b/tcg/s390/tcg-target.c.inc
160
+{
56
index XXXXXXX..XXXXXXX 100644
161
+ uint64_t cmpl = int128_getlo(cmp), cmph = int128_gethi(cmp);
57
--- a/tcg/s390/tcg-target.c.inc
162
+ uint64_t newl = int128_getlo(new), newh = int128_gethi(new);
58
+++ b/tcg/s390/tcg-target.c.inc
163
+ uint64_t oldl, oldh;
59
@@ -XXX,XX +XXX,XX @@
164
+ uint32_t tmp;
60
#define TCG_CT_CONST_S33 0x400
165
+
61
#define TCG_CT_CONST_ZERO 0x800
166
+ asm("0: ldaxp %[oldl], %[oldh], %[mem]\n\t"
62
167
+ "cmp %[oldl], %[cmpl]\n\t"
63
+#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 16)
168
+ "ccmp %[oldh], %[cmph], #0, eq\n\t"
64
+/*
169
+ "b.ne 1f\n\t"
65
+ * For softmmu, we need to avoid conflicts with the first 3
170
+ "stlxp %w[tmp], %[newl], %[newh], %[mem]\n\t"
66
+ * argument registers to perform the tlb lookup, and to call
171
+ "cbnz %w[tmp], 0b\n"
67
+ * the helper function.
172
+ "1:"
68
+ */
173
+ : [mem] "+m"(*ptr), [tmp] "=&r"(tmp),
69
+#ifdef CONFIG_SOFTMMU
174
+ [oldl] "=&r"(oldl), [oldh] "=r"(oldh)
70
+#define SOFTMMU_RESERVE_REGS MAKE_64BIT_MASK(TCG_REG_R2, 3)
175
+ : [cmpl] "r"(cmpl), [cmph] "r"(cmph),
176
+ [newl] "r"(newl), [newh] "r"(newh)
177
+ : "memory", "cc");
178
+
179
+ return int128_make128(oldl, oldh);
180
+}
181
+# define HAVE_CMPXCHG128 1
182
+#else
71
+#else
183
+/* Fallback definition that must be optimized away, or error. */
72
+#define SOFTMMU_RESERVE_REGS 0
184
+Int128 __attribute__((error("unsupported atomic")))
73
+#endif
185
+ atomic16_cmpxchg(Int128 *ptr, Int128 cmp, Int128 new);
186
+# define HAVE_CMPXCHG128 0
187
+#endif /* Some definition for HAVE_CMPXCHG128 */
188
+
74
+
189
+
75
+
190
+#if defined(CONFIG_ATOMIC128)
76
/* Several places within the instruction set 0 means "no register"
191
+static inline Int128 atomic16_read(Int128 *ptr)
77
rather than TCG_REG_R0. */
192
+{
78
#define TCG_REG_NONE 0
193
+ return atomic_read__nocheck(ptr);
79
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *src_rw, int type,
194
+}
80
return false;
195
+
81
}
196
+static inline void atomic16_set(Int128 *ptr, Int128 val)
82
197
+{
83
-/* parse target specific constraints */
198
+ atomic_set__nocheck(ptr, val);
84
-static const char *target_parse_constraint(TCGArgConstraint *ct,
199
+}
85
- const char *ct_str, TCGType type)
200
+
86
-{
201
+# define HAVE_ATOMIC128 1
87
- switch (*ct_str++) {
202
+#elif !defined(CONFIG_USER_ONLY) && defined(__aarch64__)
88
- case 'r': /* all registers */
203
+/* We can do better than cmpxchg for AArch64. */
89
- ct->regs = 0xffff;
204
+static inline Int128 atomic16_read(Int128 *ptr)
90
- break;
205
+{
91
- case 'L': /* qemu_ld/st constraint */
206
+ uint64_t l, h;
92
- ct->regs = 0xffff;
207
+ uint32_t tmp;
93
- tcg_regset_reset_reg(ct->regs, TCG_REG_R2);
208
+
94
- tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
209
+ /* The load must be paired with the store to guarantee not tearing. */
95
- tcg_regset_reset_reg(ct->regs, TCG_REG_R4);
210
+ asm("0: ldxp %[l], %[h], %[mem]\n\t"
96
- break;
211
+ "stxp %w[tmp], %[l], %[h], %[mem]\n\t"
97
- case 'a': /* force R2 for division */
212
+ "cbnz %w[tmp], 0b"
98
- ct->regs = 0;
213
+ : [mem] "+m"(*ptr), [tmp] "=r"(tmp), [l] "=r"(l), [h] "=r"(h));
99
- tcg_regset_set_reg(ct->regs, TCG_REG_R2);
214
+
100
- break;
215
+ return int128_make128(l, h);
101
- case 'b': /* force R3 for division */
216
+}
102
- ct->regs = 0;
217
+
103
- tcg_regset_set_reg(ct->regs, TCG_REG_R3);
218
+static inline void atomic16_set(Int128 *ptr, Int128 val)
104
- break;
219
+{
105
- case 'A':
220
+ uint64_t l = int128_getlo(val), h = int128_gethi(val);
106
- ct->ct |= TCG_CT_CONST_S33;
221
+ uint64_t t1, t2;
107
- break;
222
+
108
- case 'I':
223
+ /* Load into temporaries to acquire the exclusive access lock. */
109
- ct->ct |= TCG_CT_CONST_S16;
224
+ asm("0: ldxp %[t1], %[t2], %[mem]\n\t"
110
- break;
225
+ "stxp %w[t1], %[l], %[h], %[mem]\n\t"
111
- case 'J':
226
+ "cbnz %w[t1], 0b"
112
- ct->ct |= TCG_CT_CONST_S32;
227
+ : [mem] "+m"(*ptr), [t1] "=&r"(t1), [t2] "=&r"(t2)
113
- break;
228
+ : [l] "r"(l), [h] "r"(h));
114
- case 'Z':
229
+}
115
- ct->ct |= TCG_CT_CONST_ZERO;
230
+
116
- break;
231
+# define HAVE_ATOMIC128 1
117
- default:
232
+#elif !defined(CONFIG_USER_ONLY) && HAVE_CMPXCHG128
118
- return NULL;
233
+static inline Int128 atomic16_read(Int128 *ptr)
119
- }
234
+{
120
- return ct_str;
235
+ /* Maybe replace 0 with 0, returning the old value. */
121
-}
236
+ return atomic16_cmpxchg(ptr, 0, 0);
237
+}
238
+
239
+static inline void atomic16_set(Int128 *ptr, Int128 val)
240
+{
241
+ Int128 old = *ptr, cmp;
242
+ do {
243
+ cmp = old;
244
+ old = atomic16_cmpxchg(ptr, cmp, val);
245
+ } while (old != cmp);
246
+}
247
+
248
+# define HAVE_ATOMIC128 1
249
+#else
250
+/* Fallback definitions that must be optimized away, or error. */
251
+Int128 __attribute__((error("unsupported atomic")))
252
+ atomic16_read(Int128 *ptr);
253
+void __attribute__((error("unsupported atomic")))
254
+ atomic16_set(Int128 *ptr, Int128 val);
255
+# define HAVE_ATOMIC128 0
256
+#endif /* Some definition for HAVE_ATOMIC128 */
257
+
258
+#endif /* QEMU_ATOMIC128_H */
259
diff --git a/tcg/tcg.h b/tcg/tcg.h
260
index XXXXXXX..XXXXXXX 100644
261
--- a/tcg/tcg.h
262
+++ b/tcg/tcg.h
263
@@ -XXX,XX +XXX,XX @@
264
#include "qemu/queue.h"
265
#include "tcg-mo.h"
266
#include "tcg-target.h"
267
+#include "qemu/int128.h"
268
269
/* XXX: make safe guess about sizes */
270
#define MAX_OP_PER_INSTR 266
271
@@ -XXX,XX +XXX,XX @@ GEN_ATOMIC_HELPER_ALL(xchg)
272
#undef GEN_ATOMIC_HELPER
273
#endif /* CONFIG_SOFTMMU */
274
275
-#ifdef CONFIG_ATOMIC128
276
-#include "qemu/int128.h"
277
-
122
-
278
-/* These aren't really a "proper" helpers because TCG cannot manage Int128.
123
/* Test if a constant matches the constraint. */
279
- However, use the same format as the others, for use by the backends. */
124
static int tcg_target_const_match(tcg_target_long val, TCGType type,
280
+/*
125
const TCGArgConstraint *arg_ct)
281
+ * These aren't really a "proper" helpers because TCG cannot manage Int128.
282
+ * However, use the same format as the others, for use by the backends.
283
+ *
284
+ * The cmpxchg functions are only defined if HAVE_CMPXCHG128;
285
+ * the ld/st functions are only defined if HAVE_ATOMIC128,
286
+ * as defined by <qemu/atomic128.h>.
287
+ */
288
Int128 helper_atomic_cmpxchgo_le_mmu(CPUArchState *env, target_ulong addr,
289
Int128 cmpv, Int128 newv,
290
TCGMemOpIdx oi, uintptr_t retaddr);
291
@@ -XXX,XX +XXX,XX @@ void helper_atomic_sto_le_mmu(CPUArchState *env, target_ulong addr, Int128 val,
292
void helper_atomic_sto_be_mmu(CPUArchState *env, target_ulong addr, Int128 val,
293
TCGMemOpIdx oi, uintptr_t retaddr);
294
295
-#endif /* CONFIG_ATOMIC128 */
296
-
297
#endif /* TCG_H */
298
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
299
index XXXXXXX..XXXXXXX 100644
300
--- a/accel/tcg/cputlb.c
301
+++ b/accel/tcg/cputlb.c
302
@@ -XXX,XX +XXX,XX @@
303
#include "exec/log.h"
304
#include "exec/helper-proto.h"
305
#include "qemu/atomic.h"
306
+#include "qemu/atomic128.h"
307
308
/* DEBUG defines, enable DEBUG_TLB_LOG to log to the CPU_LOG_MMU target */
309
/* #define DEBUG_TLB */
310
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
311
#include "atomic_template.h"
312
#endif
313
314
-#ifdef CONFIG_ATOMIC128
315
+#if HAVE_CMPXCHG128 || HAVE_ATOMIC128
316
#define DATA_SIZE 16
317
#include "atomic_template.h"
318
#endif
319
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
320
index XXXXXXX..XXXXXXX 100644
321
--- a/accel/tcg/user-exec.c
322
+++ b/accel/tcg/user-exec.c
323
@@ -XXX,XX +XXX,XX @@
324
#include "exec/cpu_ldst.h"
325
#include "translate-all.h"
326
#include "exec/helper-proto.h"
327
+#include "qemu/atomic128.h"
328
329
#undef EAX
330
#undef ECX
331
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
332
/* The following is only callable from other helpers, and matches up
333
with the softmmu version. */
334
335
-#ifdef CONFIG_ATOMIC128
336
+#if HAVE_ATOMIC128 || HAVE_CMPXCHG128
337
338
#undef EXTRA_ARGS
339
#undef ATOMIC_NAME
340
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
341
342
#define DATA_SIZE 16
343
#include "atomic_template.h"
344
-#endif /* CONFIG_ATOMIC128 */
345
+#endif
346
diff --git a/configure b/configure
347
index XXXXXXX..XXXXXXX 100755
348
--- a/configure
349
+++ b/configure
350
@@ -XXX,XX +XXX,XX @@ EOF
351
fi
352
fi
353
354
+cmpxchg128=no
355
+if test "$int128" = yes -a "$atomic128" = no; then
356
+ cat > $TMPC << EOF
357
+int main(void)
358
+{
359
+ unsigned __int128 x = 0, y = 0;
360
+ __sync_val_compare_and_swap_16(&x, y, x);
361
+ return 0;
362
+}
363
+EOF
364
+ if compile_prog "" "" ; then
365
+ cmpxchg128=yes
366
+ fi
367
+fi
368
+
369
#########################################
370
# See if 64-bit atomic operations are supported.
371
# Note that without __atomic builtins, we can only
372
@@ -XXX,XX +XXX,XX @@ if test "$atomic128" = "yes" ; then
373
echo "CONFIG_ATOMIC128=y" >> $config_host_mak
374
fi
375
376
+if test "$cmpxchg128" = "yes" ; then
377
+ echo "CONFIG_CMPXCHG128=y" >> $config_host_mak
378
+fi
379
+
380
if test "$atomic64" = "yes" ; then
381
echo "CONFIG_ATOMIC64=y" >> $config_host_mak
382
fi
383
--
126
--
384
2.17.2
127
2.25.1
385
128
386
129
diff view generated by jsdifflib
1
From: "Emilio G. Cota" <cota@braap.org>
1
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
This plugs two 4-byte holes in 64-bit.
4
5
Signed-off-by: Emilio G. Cota <cota@braap.org>
6
Message-Id: <20181010144853.13005-4-cota@braap.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
4
---
9
tcg/tcg.h | 2 +-
5
tcg/sparc/tcg-target-con-str.h | 23 ++++++++++
10
1 file changed, 1 insertion(+), 1 deletion(-)
6
tcg/sparc/tcg-target.h | 5 +--
7
tcg/sparc/tcg-target.c.inc | 81 +++++++++++++---------------------
8
3 files changed, 55 insertions(+), 54 deletions(-)
9
create mode 100644 tcg/sparc/tcg-target-con-str.h
11
10
12
diff --git a/tcg/tcg.h b/tcg/tcg.h
11
diff --git a/tcg/sparc/tcg-target-con-str.h b/tcg/sparc/tcg-target-con-str.h
12
new file mode 100644
13
index XXXXXXX..XXXXXXX
14
--- /dev/null
15
+++ b/tcg/sparc/tcg-target-con-str.h
16
@@ -XXX,XX +XXX,XX @@
17
+/* SPDX-License-Identifier: MIT */
18
+/*
19
+ * Define Sparc target-specific operand constraints.
20
+ * Copyright (c) 2021 Linaro
21
+ */
22
+
23
+/*
24
+ * Define constraint letters for register sets:
25
+ * REGS(letter, register_mask)
26
+ */
27
+REGS('r', ALL_GENERAL_REGS)
28
+REGS('R', ALL_GENERAL_REGS64)
29
+REGS('s', ALL_QLDST_REGS)
30
+REGS('S', ALL_QLDST_REGS64)
31
+REGS('A', TARGET_LONG_BITS == 64 ? ALL_QLDST_REGS64 : ALL_QLDST_REGS)
32
+
33
+/*
34
+ * Define constraint letters for constants:
35
+ * CONST(letter, TCG_CT_CONST_* bit set)
36
+ */
37
+CONST('I', TCG_CT_CONST_S11)
38
+CONST('J', TCG_CT_CONST_S13)
39
+CONST('Z', TCG_CT_CONST_ZERO)
40
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
13
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
14
--- a/tcg/tcg.h
42
--- a/tcg/sparc/tcg-target.h
15
+++ b/tcg/tcg.h
43
+++ b/tcg/sparc/tcg-target.h
16
@@ -XXX,XX +XXX,XX @@ typedef struct TCGProfile {
44
@@ -XXX,XX +XXX,XX @@ typedef enum {
17
int64_t tb_count;
45
TCG_REG_I7,
18
int64_t op_count; /* total insn count */
46
} TCGReg;
19
int op_count_max; /* max insn per TB */
47
20
- int64_t temp_count;
48
-#define TCG_CT_CONST_S11 0x100
21
int temp_count_max;
49
-#define TCG_CT_CONST_S13 0x200
22
+ int64_t temp_count;
50
-#define TCG_CT_CONST_ZERO 0x400
23
int64_t del_op_count;
51
-
24
int64_t code_in_len;
52
/* used for function call generation */
25
int64_t code_out_len;
53
#define TCG_REG_CALL_STACK TCG_REG_O6
54
55
@@ -XXX,XX +XXX,XX @@ extern bool use_vis3_instructions;
56
void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
57
58
#define TCG_TARGET_NEED_POOL_LABELS
59
+#define TCG_TARGET_CON_STR_H
60
61
#endif
62
diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc/tcg-target.c.inc
63
index XXXXXXX..XXXXXXX 100644
64
--- a/tcg/sparc/tcg-target.c.inc
65
+++ b/tcg/sparc/tcg-target.c.inc
66
@@ -XXX,XX +XXX,XX @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
67
# define SPARC64 0
68
#endif
69
70
-/* Note that sparcv8plus can only hold 64 bit quantities in %g and %o
71
- registers. These are saved manually by the kernel in full 64-bit
72
- slots. The %i and %l registers are saved by the register window
73
- mechanism, which only allocates space for 32 bits. Given that this
74
- window spill/fill can happen on any signal, we must consider the
75
- high bits of the %i and %l registers garbage at all times. */
76
-#if SPARC64
77
-# define ALL_64 0xffffffffu
78
+#define TCG_CT_CONST_S11 0x100
79
+#define TCG_CT_CONST_S13 0x200
80
+#define TCG_CT_CONST_ZERO 0x400
81
+
82
+/*
83
+ * For softmmu, we need to avoid conflicts with the first 3
84
+ * argument registers to perform the tlb lookup, and to call
85
+ * the helper function.
86
+ */
87
+#ifdef CONFIG_SOFTMMU
88
+#define SOFTMMU_RESERVE_REGS MAKE_64BIT_MASK(TCG_REG_O0, 3)
89
#else
90
-# define ALL_64 0xffffu
91
+#define SOFTMMU_RESERVE_REGS 0
92
#endif
93
94
+/*
95
+ * Note that sparcv8plus can only hold 64 bit quantities in %g and %o
96
+ * registers. These are saved manually by the kernel in full 64-bit
97
+ * slots. The %i and %l registers are saved by the register window
98
+ * mechanism, which only allocates space for 32 bits. Given that this
99
+ * window spill/fill can happen on any signal, we must consider the
100
+ * high bits of the %i and %l registers garbage at all times.
101
+ */
102
+#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32)
103
+#if SPARC64
104
+# define ALL_GENERAL_REGS64 ALL_GENERAL_REGS
105
+#else
106
+# define ALL_GENERAL_REGS64 MAKE_64BIT_MASK(0, 16)
107
+#endif
108
+#define ALL_QLDST_REGS (ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS)
109
+#define ALL_QLDST_REGS64 (ALL_GENERAL_REGS64 & ~SOFTMMU_RESERVE_REGS)
110
+
111
/* Define some temporary registers. T2 is used for constant generation. */
112
#define TCG_REG_T1 TCG_REG_G1
113
#define TCG_REG_T2 TCG_REG_O7
114
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *src_rw, int type,
115
return true;
116
}
117
118
-/* parse target specific constraints */
119
-static const char *target_parse_constraint(TCGArgConstraint *ct,
120
- const char *ct_str, TCGType type)
121
-{
122
- switch (*ct_str++) {
123
- case 'r':
124
- ct->regs = 0xffffffff;
125
- break;
126
- case 'R':
127
- ct->regs = ALL_64;
128
- break;
129
- case 'A': /* qemu_ld/st address constraint */
130
- ct->regs = TARGET_LONG_BITS == 64 ? ALL_64 : 0xffffffff;
131
- reserve_helpers:
132
- tcg_regset_reset_reg(ct->regs, TCG_REG_O0);
133
- tcg_regset_reset_reg(ct->regs, TCG_REG_O1);
134
- tcg_regset_reset_reg(ct->regs, TCG_REG_O2);
135
- break;
136
- case 's': /* qemu_st data 32-bit constraint */
137
- ct->regs = 0xffffffff;
138
- goto reserve_helpers;
139
- case 'S': /* qemu_st data 64-bit constraint */
140
- ct->regs = ALL_64;
141
- goto reserve_helpers;
142
- case 'I':
143
- ct->ct |= TCG_CT_CONST_S11;
144
- break;
145
- case 'J':
146
- ct->ct |= TCG_CT_CONST_S13;
147
- break;
148
- case 'Z':
149
- ct->ct |= TCG_CT_CONST_ZERO;
150
- break;
151
- default:
152
- return NULL;
153
- }
154
- return ct_str;
155
-}
156
-
157
/* test if a constant matches the constraint */
158
static inline int tcg_target_const_match(tcg_target_long val, TCGType type,
159
const TCGArgConstraint *arg_ct)
160
@@ -XXX,XX +XXX,XX @@ static void tcg_target_init(TCGContext *s)
161
}
162
#endif
163
164
- tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffff;
165
- tcg_target_available_regs[TCG_TYPE_I64] = ALL_64;
166
+ tcg_target_available_regs[TCG_TYPE_I32] = ALL_GENERAL_REGS;
167
+ tcg_target_available_regs[TCG_TYPE_I64] = ALL_GENERAL_REGS64;
168
169
tcg_target_call_clobber_regs = 0;
170
tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G1);
26
--
171
--
27
2.17.2
172
2.25.1
28
173
29
174
diff view generated by jsdifflib
1
From: "Emilio G. Cota" <cota@braap.org>
1
All backends have now been converted to tcg-target-con-str.h,
2
so we can remove the fallback code.
2
3
3
We forgot to initialize n in commit 15fa08f845 ("tcg: Dynamically
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
allocate TCGOps", 2017-12-29).
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Signed-off-by: Emilio G. Cota <cota@braap.org>
8
Message-Id: <20181010144853.13005-3-cota@braap.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
7
---
11
tcg/tcg.c | 2 +-
8
tcg/aarch64/tcg-target.h | 1 -
12
1 file changed, 1 insertion(+), 1 deletion(-)
9
tcg/arm/tcg-target.h | 1 -
10
tcg/i386/tcg-target.h | 1 -
11
tcg/mips/tcg-target.h | 1 -
12
tcg/ppc/tcg-target.h | 1 -
13
tcg/riscv/tcg-target.h | 1 -
14
tcg/s390/tcg-target.h | 1 -
15
tcg/sparc/tcg-target.h | 1 -
16
tcg/tci/tcg-target.h | 2 --
17
tcg/tcg.c | 16 ----------------
18
10 files changed, 26 deletions(-)
13
19
20
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/tcg/aarch64/tcg-target.h
23
+++ b/tcg/aarch64/tcg-target.h
24
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
25
#define TCG_TARGET_NEED_LDST_LABELS
26
#endif
27
#define TCG_TARGET_NEED_POOL_LABELS
28
-#define TCG_TARGET_CON_STR_H
29
30
#endif /* AARCH64_TCG_TARGET_H */
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 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
36
#define TCG_TARGET_NEED_LDST_LABELS
37
#endif
38
#define TCG_TARGET_NEED_POOL_LABELS
39
-#define TCG_TARGET_CON_STR_H
40
41
#endif
42
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/tcg/i386/tcg-target.h
45
+++ b/tcg/i386/tcg-target.h
46
@@ -XXX,XX +XXX,XX @@ static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
47
#define TCG_TARGET_NEED_LDST_LABELS
48
#endif
49
#define TCG_TARGET_NEED_POOL_LABELS
50
-#define TCG_TARGET_CON_STR_H
51
52
#endif
53
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
54
index XXXXXXX..XXXXXXX 100644
55
--- a/tcg/mips/tcg-target.h
56
+++ b/tcg/mips/tcg-target.h
57
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
58
#ifdef CONFIG_SOFTMMU
59
#define TCG_TARGET_NEED_LDST_LABELS
60
#endif
61
-#define TCG_TARGET_CON_STR_H
62
63
#endif
64
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
65
index XXXXXXX..XXXXXXX 100644
66
--- a/tcg/ppc/tcg-target.h
67
+++ b/tcg/ppc/tcg-target.h
68
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
69
#define TCG_TARGET_NEED_LDST_LABELS
70
#endif
71
#define TCG_TARGET_NEED_POOL_LABELS
72
-#define TCG_TARGET_CON_STR_H
73
74
#endif
75
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
76
index XXXXXXX..XXXXXXX 100644
77
--- a/tcg/riscv/tcg-target.h
78
+++ b/tcg/riscv/tcg-target.h
79
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
80
#define TCG_TARGET_NEED_POOL_LABELS
81
82
#define TCG_TARGET_HAS_MEMORY_BSWAP 0
83
-#define TCG_TARGET_CON_STR_H
84
85
#endif
86
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
87
index XXXXXXX..XXXXXXX 100644
88
--- a/tcg/s390/tcg-target.h
89
+++ b/tcg/s390/tcg-target.h
90
@@ -XXX,XX +XXX,XX @@ static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
91
#define TCG_TARGET_NEED_LDST_LABELS
92
#endif
93
#define TCG_TARGET_NEED_POOL_LABELS
94
-#define TCG_TARGET_CON_STR_H
95
96
#endif
97
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
98
index XXXXXXX..XXXXXXX 100644
99
--- a/tcg/sparc/tcg-target.h
100
+++ b/tcg/sparc/tcg-target.h
101
@@ -XXX,XX +XXX,XX @@ extern bool use_vis3_instructions;
102
void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
103
104
#define TCG_TARGET_NEED_POOL_LABELS
105
-#define TCG_TARGET_CON_STR_H
106
107
#endif
108
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
109
index XXXXXXX..XXXXXXX 100644
110
--- a/tcg/tci/tcg-target.h
111
+++ b/tcg/tci/tcg-target.h
112
@@ -XXX,XX +XXX,XX @@ static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
113
/* no need to flush icache explicitly */
114
}
115
116
-#define TCG_TARGET_CON_STR_H
117
-
118
#endif /* TCG_TARGET_H */
14
diff --git a/tcg/tcg.c b/tcg/tcg.c
119
diff --git a/tcg/tcg.c b/tcg/tcg.c
15
index XXXXXXX..XXXXXXX 100644
120
index XXXXXXX..XXXXXXX 100644
16
--- a/tcg/tcg.c
121
--- a/tcg/tcg.c
17
+++ b/tcg/tcg.c
122
+++ b/tcg/tcg.c
18
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
123
@@ -XXX,XX +XXX,XX @@ static void tcg_register_jit_int(const void *buf, size_t size,
19
124
__attribute__((unused));
20
#ifdef CONFIG_PROFILER
125
21
{
126
/* Forward declarations for functions declared and used in tcg-target.c.inc. */
22
- int n;
127
-#ifndef TCG_TARGET_CON_STR_H
23
+ int n = 0;
128
-static const char *target_parse_constraint(TCGArgConstraint *ct,
24
129
- const char *ct_str, TCGType type);
25
QTAILQ_FOREACH(op, &s->ops, link) {
130
-#endif
26
n++;
131
static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
132
intptr_t arg2);
133
static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
134
@@ -XXX,XX +XXX,XX @@ static void process_op_defs(TCGContext *s)
135
ct_str++;
136
break;
137
138
-#ifdef TCG_TARGET_CON_STR_H
139
/* Include all of the target-specific constraints. */
140
141
#undef CONST
142
@@ -XXX,XX +XXX,XX @@ static void process_op_defs(TCGContext *s)
143
default:
144
/* Typo in TCGTargetOpDef constraint. */
145
g_assert_not_reached();
146
-#else
147
- default:
148
- {
149
- TCGType type = (def->flags & TCG_OPF_64BIT
150
- ? TCG_TYPE_I64 : TCG_TYPE_I32);
151
- ct_str = target_parse_constraint(&def->args_ct[i],
152
- ct_str, type);
153
- /* Typo in TCGTargetOpDef constraint. */
154
- tcg_debug_assert(ct_str != NULL);
155
- }
156
-#endif
157
}
158
}
159
}
27
--
160
--
28
2.17.2
161
2.25.1
29
162
30
163
diff view generated by jsdifflib
1
From: "Emilio G. Cota" <cota@braap.org>
1
This exports the constraint sets from tcg_target_op_def to
2
a place we will be able to manipulate more in future.
2
3
3
When we implemented per-vCPU TCG contexts, we forgot to also
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
distribute the tcg_time counter, which has remained as a global
5
accessed without any serialization, leading to potentially missed
6
counts.
7
8
Fix it by distributing the field over the TCG contexts, embedding
9
it into TCGProfile with a field called "cpu_exec_time", which is more
10
descriptive than "tcg_time". Add a function to query this value
11
directly, and for completeness, fill in the field in
12
tcg_profile_snapshot, even though its callers do not use it.
13
14
Signed-off-by: Emilio G. Cota <cota@braap.org>
15
Message-Id: <20181010144853.13005-5-cota@braap.org>
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
---
6
---
18
include/qemu/timer.h | 1 -
7
tcg/i386/tcg-target-con-set.h | 55 ++++++++++
19
tcg/tcg.h | 2 ++
8
tcg/i386/tcg-target.h | 1 +
20
cpus.c | 3 ++-
9
tcg/tcg.c | 119 +++++++++++++++++++++
21
monitor.c | 13 ++++++++++---
10
tcg/i386/tcg-target.c.inc | 194 ++++++++++++----------------------
22
tcg/tcg.c | 23 +++++++++++++++++++++++
11
4 files changed, 242 insertions(+), 127 deletions(-)
23
5 files changed, 37 insertions(+), 5 deletions(-)
12
create mode 100644 tcg/i386/tcg-target-con-set.h
24
13
25
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
14
diff --git a/tcg/i386/tcg-target-con-set.h b/tcg/i386/tcg-target-con-set.h
15
new file mode 100644
16
index XXXXXXX..XXXXXXX
17
--- /dev/null
18
+++ b/tcg/i386/tcg-target-con-set.h
19
@@ -XXX,XX +XXX,XX @@
20
+/* SPDX-License-Identifier: MIT */
21
+/*
22
+ * Define i386 target-specific constraint sets.
23
+ * Copyright (c) 2021 Linaro
24
+ */
25
+
26
+/*
27
+ * C_On_Im(...) defines a constraint set with <n> outputs and <m> inputs.
28
+ * Each operand should be a sequence of constraint letters as defined by
29
+ * tcg-target-con-str.h; the constraint combination is inclusive or.
30
+ *
31
+ * C_N1_Im(...) defines a constraint set with 1 output and <m> inputs,
32
+ * except that the output must use a new register.
33
+ */
34
+C_O0_I1(r)
35
+C_O0_I2(L, L)
36
+C_O0_I2(qi, r)
37
+C_O0_I2(re, r)
38
+C_O0_I2(ri, r)
39
+C_O0_I2(r, re)
40
+C_O0_I2(s, L)
41
+C_O0_I2(x, r)
42
+C_O0_I3(L, L, L)
43
+C_O0_I3(s, L, L)
44
+C_O0_I4(L, L, L, L)
45
+C_O0_I4(r, r, ri, ri)
46
+C_O1_I1(r, 0)
47
+C_O1_I1(r, L)
48
+C_O1_I1(r, q)
49
+C_O1_I1(r, r)
50
+C_O1_I1(x, r)
51
+C_O1_I1(x, x)
52
+C_O1_I2(Q, 0, Q)
53
+C_O1_I2(q, r, re)
54
+C_O1_I2(r, 0, ci)
55
+C_O1_I2(r, 0, r)
56
+C_O1_I2(r, 0, re)
57
+C_O1_I2(r, 0, reZ)
58
+C_O1_I2(r, 0, ri)
59
+C_O1_I2(r, 0, rI)
60
+C_O1_I2(r, L, L)
61
+C_O1_I2(r, r, re)
62
+C_O1_I2(r, r, ri)
63
+C_O1_I2(r, r, rI)
64
+C_O1_I2(x, x, x)
65
+C_N1_I2(r, r, r)
66
+C_N1_I2(r, r, rW)
67
+C_O1_I3(x, x, x, x)
68
+C_O1_I4(r, r, re, r, 0)
69
+C_O1_I4(r, r, r, ri, ri)
70
+C_O2_I1(r, r, L)
71
+C_O2_I2(a, d, a, r)
72
+C_O2_I2(r, r, L, L)
73
+C_O2_I3(a, d, 0, 1, r)
74
+C_O2_I4(r, r, 0, 1, re, re)
75
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
26
index XXXXXXX..XXXXXXX 100644
76
index XXXXXXX..XXXXXXX 100644
27
--- a/include/qemu/timer.h
77
--- a/tcg/i386/tcg-target.h
28
+++ b/include/qemu/timer.h
78
+++ b/tcg/i386/tcg-target.h
29
@@ -XXX,XX +XXX,XX @@ static inline int64_t profile_getclock(void)
79
@@ -XXX,XX +XXX,XX @@ static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
30
return get_clock();
80
#define TCG_TARGET_NEED_LDST_LABELS
31
}
32
33
-extern int64_t tcg_time;
34
extern int64_t dev_time;
35
#endif
81
#endif
36
82
#define TCG_TARGET_NEED_POOL_LABELS
37
diff --git a/tcg/tcg.h b/tcg/tcg.h
83
+#define TCG_TARGET_CON_SET_H
38
index XXXXXXX..XXXXXXX 100644
84
39
--- a/tcg/tcg.h
40
+++ b/tcg/tcg.h
41
@@ -XXX,XX +XXX,XX @@ typedef struct TCGOp {
42
QEMU_BUILD_BUG_ON(NB_OPS > (1 << 8));
43
44
typedef struct TCGProfile {
45
+ int64_t cpu_exec_time;
46
int64_t tb_count1;
47
int64_t tb_count;
48
int64_t op_count; /* total insn count */
49
@@ -XXX,XX +XXX,XX @@ int tcg_check_temp_count(void);
50
#define tcg_check_temp_count() 0
51
#endif
85
#endif
52
53
+int64_t tcg_cpu_exec_time(void);
54
void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf);
55
void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf);
56
57
diff --git a/cpus.c b/cpus.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/cpus.c
60
+++ b/cpus.c
61
@@ -XXX,XX +XXX,XX @@ static int tcg_cpu_exec(CPUState *cpu)
62
ret = cpu_exec(cpu);
63
cpu_exec_end(cpu);
64
#ifdef CONFIG_PROFILER
65
- tcg_time += profile_getclock() - ti;
66
+ atomic_set(&tcg_ctx->prof.cpu_exec_time,
67
+ tcg_ctx->prof.cpu_exec_time + profile_getclock() - ti);
68
#endif
69
return ret;
70
}
71
diff --git a/monitor.c b/monitor.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/monitor.c
74
+++ b/monitor.c
75
@@ -XXX,XX +XXX,XX @@
76
#include "sysemu/cpus.h"
77
#include "sysemu/iothread.h"
78
#include "qemu/cutils.h"
79
+#include "tcg/tcg.h"
80
81
#if defined(TARGET_S390X)
82
#include "hw/s390x/storage-keys.h"
83
@@ -XXX,XX +XXX,XX @@ static void hmp_info_numa(Monitor *mon, const QDict *qdict)
84
85
#ifdef CONFIG_PROFILER
86
87
-int64_t tcg_time;
88
int64_t dev_time;
89
90
static void hmp_info_profile(Monitor *mon, const QDict *qdict)
91
{
92
+ static int64_t last_cpu_exec_time;
93
+ int64_t cpu_exec_time;
94
+ int64_t delta;
95
+
96
+ cpu_exec_time = tcg_cpu_exec_time();
97
+ delta = cpu_exec_time - last_cpu_exec_time;
98
+
99
monitor_printf(mon, "async time %" PRId64 " (%0.3f)\n",
100
dev_time, dev_time / (double)NANOSECONDS_PER_SECOND);
101
monitor_printf(mon, "qemu time %" PRId64 " (%0.3f)\n",
102
- tcg_time, tcg_time / (double)NANOSECONDS_PER_SECOND);
103
- tcg_time = 0;
104
+ delta, delta / (double)NANOSECONDS_PER_SECOND);
105
+ last_cpu_exec_time = cpu_exec_time;
106
dev_time = 0;
107
}
108
#else
109
diff --git a/tcg/tcg.c b/tcg/tcg.c
86
diff --git a/tcg/tcg.c b/tcg/tcg.c
110
index XXXXXXX..XXXXXXX 100644
87
index XXXXXXX..XXXXXXX 100644
111
--- a/tcg/tcg.c
88
--- a/tcg/tcg.c
112
+++ b/tcg/tcg.c
89
+++ b/tcg/tcg.c
113
@@ -XXX,XX +XXX,XX @@
90
@@ -XXX,XX +XXX,XX @@
114
/* Define to jump the ELF file used to communicate with GDB. */
91
/* Forward declarations for functions declared in tcg-target.c.inc and
115
#undef DEBUG_JIT
92
used here. */
116
93
static void tcg_target_init(TCGContext *s);
117
+#include "qemu/error-report.h"
94
+#ifndef TCG_TARGET_CON_SET_H
118
#include "qemu/cutils.h"
95
static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode);
119
#include "qemu/host-utils.h"
96
+#endif
120
#include "qemu/timer.h"
97
static void tcg_target_qemu_prologue(TCGContext *s);
121
@@ -XXX,XX +XXX,XX @@ void tcg_profile_snapshot(TCGProfile *prof, bool counters, bool table)
98
static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
122
const TCGProfile *orig = &s->prof;
99
intptr_t value, intptr_t addend);
123
100
@@ -XXX,XX +XXX,XX @@ static void set_jmp_reset_offset(TCGContext *s, int which)
124
if (counters) {
101
s->tb_jmp_reset_offset[which] = tcg_current_code_size(s);
125
+ PROF_ADD(prof, orig, cpu_exec_time);
102
}
126
PROF_ADD(prof, orig, tb_count1);
103
127
PROF_ADD(prof, orig, tb_count);
104
+#ifdef TCG_TARGET_CON_SET_H
128
PROF_ADD(prof, orig, op_count);
105
+#define C_PFX1(P, A) P##A
129
@@ -XXX,XX +XXX,XX @@ void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf)
106
+#define C_PFX2(P, A, B) P##A##_##B
130
prof.table_op_count[i]);
107
+#define C_PFX3(P, A, B, C) P##A##_##B##_##C
108
+#define C_PFX4(P, A, B, C, D) P##A##_##B##_##C##_##D
109
+#define C_PFX5(P, A, B, C, D, E) P##A##_##B##_##C##_##D##_##E
110
+#define C_PFX6(P, A, B, C, D, E, F) P##A##_##B##_##C##_##D##_##E##_##F
111
+
112
+/* Define an enumeration for the various combinations. */
113
+
114
+#define C_O0_I1(I1) C_PFX1(c_o0_i1_, I1),
115
+#define C_O0_I2(I1, I2) C_PFX2(c_o0_i2_, I1, I2),
116
+#define C_O0_I3(I1, I2, I3) C_PFX3(c_o0_i3_, I1, I2, I3),
117
+#define C_O0_I4(I1, I2, I3, I4) C_PFX4(c_o0_i4_, I1, I2, I3, I4),
118
+
119
+#define C_O1_I1(O1, I1) C_PFX2(c_o1_i1_, O1, I1),
120
+#define C_O1_I2(O1, I1, I2) C_PFX3(c_o1_i2_, O1, I1, I2),
121
+#define C_O1_I3(O1, I1, I2, I3) C_PFX4(c_o1_i3_, O1, I1, I2, I3),
122
+#define C_O1_I4(O1, I1, I2, I3, I4) C_PFX5(c_o1_i4_, O1, I1, I2, I3, I4),
123
+
124
+#define C_N1_I2(O1, I1, I2) C_PFX3(c_n1_i2_, O1, I1, I2),
125
+
126
+#define C_O2_I1(O1, O2, I1) C_PFX3(c_o2_i1_, O1, O2, I1),
127
+#define C_O2_I2(O1, O2, I1, I2) C_PFX4(c_o2_i2_, O1, O2, I1, I2),
128
+#define C_O2_I3(O1, O2, I1, I2, I3) C_PFX5(c_o2_i3_, O1, O2, I1, I2, I3),
129
+#define C_O2_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_o2_i4_, O1, O2, I1, I2, I3, I4),
130
+
131
+typedef enum {
132
+#include "tcg-target-con-set.h"
133
+} TCGConstraintSetIndex;
134
+
135
+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode);
136
+
137
+#undef C_O0_I1
138
+#undef C_O0_I2
139
+#undef C_O0_I3
140
+#undef C_O0_I4
141
+#undef C_O1_I1
142
+#undef C_O1_I2
143
+#undef C_O1_I3
144
+#undef C_O1_I4
145
+#undef C_N1_I2
146
+#undef C_O2_I1
147
+#undef C_O2_I2
148
+#undef C_O2_I3
149
+#undef C_O2_I4
150
+
151
+/* Put all of the constraint sets into an array, indexed by the enum. */
152
+
153
+#define C_O0_I1(I1) { .args_ct_str = { #I1 } },
154
+#define C_O0_I2(I1, I2) { .args_ct_str = { #I1, #I2 } },
155
+#define C_O0_I3(I1, I2, I3) { .args_ct_str = { #I1, #I2, #I3 } },
156
+#define C_O0_I4(I1, I2, I3, I4) { .args_ct_str = { #I1, #I2, #I3, #I4 } },
157
+
158
+#define C_O1_I1(O1, I1) { .args_ct_str = { #O1, #I1 } },
159
+#define C_O1_I2(O1, I1, I2) { .args_ct_str = { #O1, #I1, #I2 } },
160
+#define C_O1_I3(O1, I1, I2, I3) { .args_ct_str = { #O1, #I1, #I2, #I3 } },
161
+#define C_O1_I4(O1, I1, I2, I3, I4) { .args_ct_str = { #O1, #I1, #I2, #I3, #I4 } },
162
+
163
+#define C_N1_I2(O1, I1, I2) { .args_ct_str = { "&" #O1, #I1, #I2 } },
164
+
165
+#define C_O2_I1(O1, O2, I1) { .args_ct_str = { #O1, #O2, #I1 } },
166
+#define C_O2_I2(O1, O2, I1, I2) { .args_ct_str = { #O1, #O2, #I1, #I2 } },
167
+#define C_O2_I3(O1, O2, I1, I2, I3) { .args_ct_str = { #O1, #O2, #I1, #I2, #I3 } },
168
+#define C_O2_I4(O1, O2, I1, I2, I3, I4) { .args_ct_str = { #O1, #O2, #I1, #I2, #I3, #I4 } },
169
+
170
+static const TCGTargetOpDef constraint_sets[] = {
171
+#include "tcg-target-con-set.h"
172
+};
173
+
174
+
175
+#undef C_O0_I1
176
+#undef C_O0_I2
177
+#undef C_O0_I3
178
+#undef C_O0_I4
179
+#undef C_O1_I1
180
+#undef C_O1_I2
181
+#undef C_O1_I3
182
+#undef C_O1_I4
183
+#undef C_N1_I2
184
+#undef C_O2_I1
185
+#undef C_O2_I2
186
+#undef C_O2_I3
187
+#undef C_O2_I4
188
+
189
+/* Expand the enumerator to be returned from tcg_target_op_def(). */
190
+
191
+#define C_O0_I1(I1) C_PFX1(c_o0_i1_, I1)
192
+#define C_O0_I2(I1, I2) C_PFX2(c_o0_i2_, I1, I2)
193
+#define C_O0_I3(I1, I2, I3) C_PFX3(c_o0_i3_, I1, I2, I3)
194
+#define C_O0_I4(I1, I2, I3, I4) C_PFX4(c_o0_i4_, I1, I2, I3, I4)
195
+
196
+#define C_O1_I1(O1, I1) C_PFX2(c_o1_i1_, O1, I1)
197
+#define C_O1_I2(O1, I1, I2) C_PFX3(c_o1_i2_, O1, I1, I2)
198
+#define C_O1_I3(O1, I1, I2, I3) C_PFX4(c_o1_i3_, O1, I1, I2, I3)
199
+#define C_O1_I4(O1, I1, I2, I3, I4) C_PFX5(c_o1_i4_, O1, I1, I2, I3, I4)
200
+
201
+#define C_N1_I2(O1, I1, I2) C_PFX3(c_n1_i2_, O1, I1, I2)
202
+
203
+#define C_O2_I1(O1, O2, I1) C_PFX3(c_o2_i1_, O1, O2, I1)
204
+#define C_O2_I2(O1, O2, I1, I2) C_PFX4(c_o2_i2_, O1, O2, I1, I2)
205
+#define C_O2_I3(O1, O2, I1, I2, I3) C_PFX5(c_o2_i3_, O1, O2, I1, I2, I3)
206
+#define C_O2_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_o2_i4_, O1, O2, I1, I2, I3, I4)
207
+
208
+#endif /* TCG_TARGET_CON_SET_H */
209
+
210
#include "tcg-target.c.inc"
211
212
/* compare a pointer @ptr and a tb_tc @s */
213
@@ -XXX,XX +XXX,XX @@ static void process_op_defs(TCGContext *s)
214
continue;
215
}
216
217
+#ifdef TCG_TARGET_CON_SET_H
218
+ /*
219
+ * Macro magic should make it impossible, but double-check that
220
+ * the array index is in range. Since the signness of an enum
221
+ * is implementation defined, force the result to unsigned.
222
+ */
223
+ unsigned con_set = tcg_target_op_def(op);
224
+ tcg_debug_assert(con_set < ARRAY_SIZE(constraint_sets));
225
+ tdefs = &constraint_sets[con_set];
226
+#else
227
tdefs = tcg_target_op_def(op);
228
/* Missing TCGTargetOpDef entry. */
229
tcg_debug_assert(tdefs != NULL);
230
+#endif
231
232
for (i = 0; i < nb_args; i++) {
233
const char *ct_str = tdefs->args_ct_str[i];
234
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
235
index XXXXXXX..XXXXXXX 100644
236
--- a/tcg/i386/tcg-target.c.inc
237
+++ b/tcg/i386/tcg-target.c.inc
238
@@ -XXX,XX +XXX,XX @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
131
}
239
}
132
}
240
}
133
+
241
134
+int64_t tcg_cpu_exec_time(void)
242
-static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
135
+{
243
+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
136
+ unsigned int n_ctxs = atomic_read(&n_tcg_ctxs);
137
+ unsigned int i;
138
+ int64_t ret = 0;
139
+
140
+ for (i = 0; i < n_ctxs; i++) {
141
+ const TCGContext *s = atomic_read(&tcg_ctxs[i]);
142
+ const TCGProfile *prof = &s->prof;
143
+
144
+ ret += atomic_read(&prof->cpu_exec_time);
145
+ }
146
+ return ret;
147
+}
148
#else
149
void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf)
150
{
244
{
151
cpu_fprintf(f, "[TCG profiler not compiled]\n");
245
- static const TCGTargetOpDef r = { .args_ct_str = { "r" } };
246
- static const TCGTargetOpDef ri_r = { .args_ct_str = { "ri", "r" } };
247
- static const TCGTargetOpDef re_r = { .args_ct_str = { "re", "r" } };
248
- static const TCGTargetOpDef qi_r = { .args_ct_str = { "qi", "r" } };
249
- static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } };
250
- static const TCGTargetOpDef r_q = { .args_ct_str = { "r", "q" } };
251
- static const TCGTargetOpDef r_re = { .args_ct_str = { "r", "re" } };
252
- static const TCGTargetOpDef r_0 = { .args_ct_str = { "r", "0" } };
253
- static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } };
254
- static const TCGTargetOpDef r_r_re = { .args_ct_str = { "r", "r", "re" } };
255
- static const TCGTargetOpDef r_0_r = { .args_ct_str = { "r", "0", "r" } };
256
- static const TCGTargetOpDef r_0_re = { .args_ct_str = { "r", "0", "re" } };
257
- static const TCGTargetOpDef r_0_ci = { .args_ct_str = { "r", "0", "ci" } };
258
- static const TCGTargetOpDef r_L = { .args_ct_str = { "r", "L" } };
259
- static const TCGTargetOpDef L_L = { .args_ct_str = { "L", "L" } };
260
- static const TCGTargetOpDef s_L = { .args_ct_str = { "s", "L" } };
261
- static const TCGTargetOpDef r_L_L = { .args_ct_str = { "r", "L", "L" } };
262
- static const TCGTargetOpDef r_r_L = { .args_ct_str = { "r", "r", "L" } };
263
- static const TCGTargetOpDef L_L_L = { .args_ct_str = { "L", "L", "L" } };
264
- static const TCGTargetOpDef s_L_L = { .args_ct_str = { "s", "L", "L" } };
265
- static const TCGTargetOpDef r_r_L_L
266
- = { .args_ct_str = { "r", "r", "L", "L" } };
267
- static const TCGTargetOpDef L_L_L_L
268
- = { .args_ct_str = { "L", "L", "L", "L" } };
269
- static const TCGTargetOpDef x_x = { .args_ct_str = { "x", "x" } };
270
- static const TCGTargetOpDef x_x_x = { .args_ct_str = { "x", "x", "x" } };
271
- static const TCGTargetOpDef x_x_x_x
272
- = { .args_ct_str = { "x", "x", "x", "x" } };
273
- static const TCGTargetOpDef x_r = { .args_ct_str = { "x", "r" } };
274
-
275
switch (op) {
276
case INDEX_op_goto_ptr:
277
- return &r;
278
+ return C_O0_I1(r);
279
280
case INDEX_op_ld8u_i32:
281
case INDEX_op_ld8u_i64:
282
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
283
case INDEX_op_ld32u_i64:
284
case INDEX_op_ld32s_i64:
285
case INDEX_op_ld_i64:
286
- return &r_r;
287
+ return C_O1_I1(r, r);
288
289
case INDEX_op_st8_i32:
290
case INDEX_op_st8_i64:
291
- return &qi_r;
292
+ return C_O0_I2(qi, r);
293
+
294
case INDEX_op_st16_i32:
295
case INDEX_op_st16_i64:
296
case INDEX_op_st_i32:
297
case INDEX_op_st32_i64:
298
- return &ri_r;
299
+ return C_O0_I2(ri, r);
300
+
301
case INDEX_op_st_i64:
302
- return &re_r;
303
+ return C_O0_I2(re, r);
304
305
case INDEX_op_add_i32:
306
case INDEX_op_add_i64:
307
- return &r_r_re;
308
+ return C_O1_I2(r, r, re);
309
+
310
case INDEX_op_sub_i32:
311
case INDEX_op_sub_i64:
312
case INDEX_op_mul_i32:
313
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
314
case INDEX_op_or_i64:
315
case INDEX_op_xor_i32:
316
case INDEX_op_xor_i64:
317
- return &r_0_re;
318
+ return C_O1_I2(r, 0, re);
319
320
case INDEX_op_and_i32:
321
case INDEX_op_and_i64:
322
- {
323
- static const TCGTargetOpDef and
324
- = { .args_ct_str = { "r", "0", "reZ" } };
325
- return &and;
326
- }
327
- break;
328
+ return C_O1_I2(r, 0, reZ);
329
+
330
case INDEX_op_andc_i32:
331
case INDEX_op_andc_i64:
332
- {
333
- static const TCGTargetOpDef andc
334
- = { .args_ct_str = { "r", "r", "rI" } };
335
- return &andc;
336
- }
337
- break;
338
+ return C_O1_I2(r, r, rI);
339
340
case INDEX_op_shl_i32:
341
case INDEX_op_shl_i64:
342
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
343
case INDEX_op_shr_i64:
344
case INDEX_op_sar_i32:
345
case INDEX_op_sar_i64:
346
- return have_bmi2 ? &r_r_ri : &r_0_ci;
347
+ return have_bmi2 ? C_O1_I2(r, r, ri) : C_O1_I2(r, 0, ci);
348
+
349
case INDEX_op_rotl_i32:
350
case INDEX_op_rotl_i64:
351
case INDEX_op_rotr_i32:
352
case INDEX_op_rotr_i64:
353
- return &r_0_ci;
354
+ return C_O1_I2(r, 0, ci);
355
356
case INDEX_op_brcond_i32:
357
case INDEX_op_brcond_i64:
358
- return &r_re;
359
+ return C_O0_I2(r, re);
360
361
case INDEX_op_bswap16_i32:
362
case INDEX_op_bswap16_i64:
363
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
364
case INDEX_op_not_i32:
365
case INDEX_op_not_i64:
366
case INDEX_op_extrh_i64_i32:
367
- return &r_0;
368
+ return C_O1_I1(r, 0);
369
370
case INDEX_op_ext8s_i32:
371
case INDEX_op_ext8s_i64:
372
case INDEX_op_ext8u_i32:
373
case INDEX_op_ext8u_i64:
374
- return &r_q;
375
+ return C_O1_I1(r, q);
376
+
377
case INDEX_op_ext16s_i32:
378
case INDEX_op_ext16s_i64:
379
case INDEX_op_ext16u_i32:
380
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
381
case INDEX_op_sextract_i32:
382
case INDEX_op_ctpop_i32:
383
case INDEX_op_ctpop_i64:
384
- return &r_r;
385
+ return C_O1_I1(r, r);
386
+
387
case INDEX_op_extract2_i32:
388
case INDEX_op_extract2_i64:
389
- return &r_0_r;
390
+ return C_O1_I2(r, 0, r);
391
392
case INDEX_op_deposit_i32:
393
case INDEX_op_deposit_i64:
394
- {
395
- static const TCGTargetOpDef dep
396
- = { .args_ct_str = { "Q", "0", "Q" } };
397
- return &dep;
398
- }
399
+ return C_O1_I2(Q, 0, Q);
400
+
401
case INDEX_op_setcond_i32:
402
case INDEX_op_setcond_i64:
403
- {
404
- static const TCGTargetOpDef setc
405
- = { .args_ct_str = { "q", "r", "re" } };
406
- return &setc;
407
- }
408
+ return C_O1_I2(q, r, re);
409
+
410
case INDEX_op_movcond_i32:
411
case INDEX_op_movcond_i64:
412
- {
413
- static const TCGTargetOpDef movc
414
- = { .args_ct_str = { "r", "r", "re", "r", "0" } };
415
- return &movc;
416
- }
417
+ return C_O1_I4(r, r, re, r, 0);
418
+
419
case INDEX_op_div2_i32:
420
case INDEX_op_div2_i64:
421
case INDEX_op_divu2_i32:
422
case INDEX_op_divu2_i64:
423
- {
424
- static const TCGTargetOpDef div2
425
- = { .args_ct_str = { "a", "d", "0", "1", "r" } };
426
- return &div2;
427
- }
428
+ return C_O2_I3(a, d, 0, 1, r);
429
+
430
case INDEX_op_mulu2_i32:
431
case INDEX_op_mulu2_i64:
432
case INDEX_op_muls2_i32:
433
case INDEX_op_muls2_i64:
434
- {
435
- static const TCGTargetOpDef mul2
436
- = { .args_ct_str = { "a", "d", "a", "r" } };
437
- return &mul2;
438
- }
439
+ return C_O2_I2(a, d, a, r);
440
+
441
case INDEX_op_add2_i32:
442
case INDEX_op_add2_i64:
443
case INDEX_op_sub2_i32:
444
case INDEX_op_sub2_i64:
445
- {
446
- static const TCGTargetOpDef arith2
447
- = { .args_ct_str = { "r", "r", "0", "1", "re", "re" } };
448
- return &arith2;
449
- }
450
+ return C_O2_I4(r, r, 0, 1, re, re);
451
+
452
case INDEX_op_ctz_i32:
453
case INDEX_op_ctz_i64:
454
- {
455
- static const TCGTargetOpDef ctz[2] = {
456
- { .args_ct_str = { "&r", "r", "r" } },
457
- { .args_ct_str = { "&r", "r", "rW" } },
458
- };
459
- return &ctz[have_bmi1];
460
- }
461
+ return have_bmi1 ? C_N1_I2(r, r, rW) : C_N1_I2(r, r, r);
462
+
463
case INDEX_op_clz_i32:
464
case INDEX_op_clz_i64:
465
- {
466
- static const TCGTargetOpDef clz[2] = {
467
- { .args_ct_str = { "&r", "r", "r" } },
468
- { .args_ct_str = { "&r", "r", "rW" } },
469
- };
470
- return &clz[have_lzcnt];
471
- }
472
+ return have_lzcnt ? C_N1_I2(r, r, rW) : C_N1_I2(r, r, r);
473
474
case INDEX_op_qemu_ld_i32:
475
- return TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &r_L : &r_L_L;
476
+ return (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
477
+ ? C_O1_I1(r, L) : C_O1_I2(r, L, L));
478
+
479
case INDEX_op_qemu_st_i32:
480
- return TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &L_L : &L_L_L;
481
+ return (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
482
+ ? C_O0_I2(L, L) : C_O0_I3(L, L, L));
483
case INDEX_op_qemu_st8_i32:
484
- return TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &s_L : &s_L_L;
485
+ return (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
486
+ ? C_O0_I2(s, L) : C_O0_I3(s, L, L));
487
+
488
case INDEX_op_qemu_ld_i64:
489
- return (TCG_TARGET_REG_BITS == 64 ? &r_L
490
- : TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &r_r_L
491
- : &r_r_L_L);
492
+ return (TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, L)
493
+ : TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? C_O2_I1(r, r, L)
494
+ : C_O2_I2(r, r, L, L));
495
+
496
case INDEX_op_qemu_st_i64:
497
- return (TCG_TARGET_REG_BITS == 64 ? &L_L
498
- : TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &L_L_L
499
- : &L_L_L_L);
500
+ return (TCG_TARGET_REG_BITS == 64 ? C_O0_I2(L, L)
501
+ : TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? C_O0_I3(L, L, L)
502
+ : C_O0_I4(L, L, L, L));
503
504
case INDEX_op_brcond2_i32:
505
- {
506
- static const TCGTargetOpDef b2
507
- = { .args_ct_str = { "r", "r", "ri", "ri" } };
508
- return &b2;
509
- }
510
+ return C_O0_I4(r, r, ri, ri);
511
+
512
case INDEX_op_setcond2_i32:
513
- {
514
- static const TCGTargetOpDef s2
515
- = { .args_ct_str = { "r", "r", "r", "ri", "ri" } };
516
- return &s2;
517
- }
518
+ return C_O1_I4(r, r, r, ri, ri);
519
520
case INDEX_op_ld_vec:
521
- case INDEX_op_st_vec:
522
case INDEX_op_dupm_vec:
523
- return &x_r;
524
+ return C_O1_I1(x, r);
525
+
526
+ case INDEX_op_st_vec:
527
+ return C_O0_I2(x, r);
528
529
case INDEX_op_add_vec:
530
case INDEX_op_sub_vec:
531
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
532
#if TCG_TARGET_REG_BITS == 32
533
case INDEX_op_dup2_vec:
534
#endif
535
- return &x_x_x;
536
+ return C_O1_I2(x, x, x);
537
+
538
case INDEX_op_abs_vec:
539
case INDEX_op_dup_vec:
540
case INDEX_op_shli_vec:
541
case INDEX_op_shri_vec:
542
case INDEX_op_sari_vec:
543
case INDEX_op_x86_psrldq_vec:
544
- return &x_x;
545
+ return C_O1_I1(x, x);
546
+
547
case INDEX_op_x86_vpblendvb_vec:
548
- return &x_x_x_x;
549
+ return C_O1_I3(x, x, x, x);
550
551
default:
552
- break;
553
+ g_assert_not_reached();
554
}
555
- return NULL;
152
}
556
}
153
+
557
154
+int64_t tcg_cpu_exec_time(void)
558
int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece)
155
+{
156
+ error_report("%s: TCG profiler not compiled", __func__);
157
+ exit(EXIT_FAILURE);
158
+}
159
#endif
160
161
162
--
559
--
163
2.17.2
560
2.25.1
164
561
165
562
diff view generated by jsdifflib
1
From: "Emilio G. Cota" <cota@braap.org>
1
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2
3
Consistently access u16.high with atomics to avoid
4
undefined behaviour in MTTCG.
5
6
Note that icount_decr.u16.low is only used in icount mode,
7
so regular accesses to it are OK.
8
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Emilio G. Cota <cota@braap.org>
11
Message-Id: <20181010144853.13005-2-cota@braap.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
---
3
---
14
accel/tcg/tcg-all.c | 2 +-
4
tcg/aarch64/tcg-target-con-set.h | 36 +++++++++++++
15
accel/tcg/translate-all.c | 2 +-
5
tcg/aarch64/tcg-target.h | 1 +
16
qom/cpu.c | 2 +-
6
tcg/aarch64/tcg-target.c.inc | 86 +++++++++++---------------------
17
3 files changed, 3 insertions(+), 3 deletions(-)
7
3 files changed, 65 insertions(+), 58 deletions(-)
8
create mode 100644 tcg/aarch64/tcg-target-con-set.h
18
9
19
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
10
diff --git a/tcg/aarch64/tcg-target-con-set.h b/tcg/aarch64/tcg-target-con-set.h
11
new file mode 100644
12
index XXXXXXX..XXXXXXX
13
--- /dev/null
14
+++ b/tcg/aarch64/tcg-target-con-set.h
15
@@ -XXX,XX +XXX,XX @@
16
+/* SPDX-License-Identifier: GPL-2.0-or-later */
17
+/*
18
+ * Define AArch64 target-specific constraint sets.
19
+ * Copyright (c) 2021 Linaro
20
+ */
21
+
22
+/*
23
+ * C_On_Im(...) defines a constraint set with <n> outputs and <m> inputs.
24
+ * Each operand should be a sequence of constraint letters as defined by
25
+ * tcg-target-con-str.h; the constraint combination is inclusive or.
26
+ */
27
+C_O0_I1(r)
28
+C_O0_I2(lZ, l)
29
+C_O0_I2(r, rA)
30
+C_O0_I2(rZ, r)
31
+C_O0_I2(w, r)
32
+C_O1_I1(r, l)
33
+C_O1_I1(r, r)
34
+C_O1_I1(w, r)
35
+C_O1_I1(w, w)
36
+C_O1_I1(w, wr)
37
+C_O1_I2(r, 0, rZ)
38
+C_O1_I2(r, r, r)
39
+C_O1_I2(r, r, rA)
40
+C_O1_I2(r, r, rAL)
41
+C_O1_I2(r, r, ri)
42
+C_O1_I2(r, r, rL)
43
+C_O1_I2(r, rZ, rZ)
44
+C_O1_I2(w, 0, w)
45
+C_O1_I2(w, w, w)
46
+C_O1_I2(w, w, wN)
47
+C_O1_I2(w, w, wO)
48
+C_O1_I2(w, w, wZ)
49
+C_O1_I3(w, w, w, w)
50
+C_O1_I4(r, r, rA, rZ, rZ)
51
+C_O2_I4(r, r, rZ, rZ, rA, rMZ)
52
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
20
index XXXXXXX..XXXXXXX 100644
53
index XXXXXXX..XXXXXXX 100644
21
--- a/accel/tcg/tcg-all.c
54
--- a/tcg/aarch64/tcg-target.h
22
+++ b/accel/tcg/tcg-all.c
55
+++ b/tcg/aarch64/tcg-target.h
23
@@ -XXX,XX +XXX,XX @@ static void tcg_handle_interrupt(CPUState *cpu, int mask)
56
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
24
if (!qemu_cpu_is_self(cpu)) {
57
#define TCG_TARGET_NEED_LDST_LABELS
25
qemu_cpu_kick(cpu);
58
#endif
26
} else {
59
#define TCG_TARGET_NEED_POOL_LABELS
27
- cpu->icount_decr.u16.high = -1;
60
+#define TCG_TARGET_CON_SET_H
28
+ atomic_set(&cpu->icount_decr.u16.high, -1);
61
29
if (use_icount &&
62
#endif /* AARCH64_TCG_TARGET_H */
30
!cpu->can_do_io
63
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
31
&& (mask & ~old_mask) != 0) {
32
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
33
index XXXXXXX..XXXXXXX 100644
64
index XXXXXXX..XXXXXXX 100644
34
--- a/accel/tcg/translate-all.c
65
--- a/tcg/aarch64/tcg-target.c.inc
35
+++ b/accel/tcg/translate-all.c
66
+++ b/tcg/aarch64/tcg-target.c.inc
36
@@ -XXX,XX +XXX,XX @@ void cpu_interrupt(CPUState *cpu, int mask)
67
@@ -XXX,XX +XXX,XX @@ void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece,
68
va_end(va);
69
}
70
71
-static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
72
+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
37
{
73
{
38
g_assert(qemu_mutex_iothread_locked());
74
- static const TCGTargetOpDef r = { .args_ct_str = { "r" } };
39
cpu->interrupt_request |= mask;
75
- static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } };
40
- cpu->icount_decr.u16.high = -1;
76
- static const TCGTargetOpDef w_w = { .args_ct_str = { "w", "w" } };
41
+ atomic_set(&cpu->icount_decr.u16.high, -1);
77
- static const TCGTargetOpDef w_r = { .args_ct_str = { "w", "r" } };
78
- static const TCGTargetOpDef w_wr = { .args_ct_str = { "w", "wr" } };
79
- static const TCGTargetOpDef r_l = { .args_ct_str = { "r", "l" } };
80
- static const TCGTargetOpDef r_rA = { .args_ct_str = { "r", "rA" } };
81
- static const TCGTargetOpDef rZ_r = { .args_ct_str = { "rZ", "r" } };
82
- static const TCGTargetOpDef lZ_l = { .args_ct_str = { "lZ", "l" } };
83
- static const TCGTargetOpDef r_r_r = { .args_ct_str = { "r", "r", "r" } };
84
- static const TCGTargetOpDef w_w_w = { .args_ct_str = { "w", "w", "w" } };
85
- static const TCGTargetOpDef w_0_w = { .args_ct_str = { "w", "0", "w" } };
86
- static const TCGTargetOpDef w_w_wO = { .args_ct_str = { "w", "w", "wO" } };
87
- static const TCGTargetOpDef w_w_wN = { .args_ct_str = { "w", "w", "wN" } };
88
- static const TCGTargetOpDef w_w_wZ = { .args_ct_str = { "w", "w", "wZ" } };
89
- static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } };
90
- static const TCGTargetOpDef r_r_rA = { .args_ct_str = { "r", "r", "rA" } };
91
- static const TCGTargetOpDef r_r_rL = { .args_ct_str = { "r", "r", "rL" } };
92
- static const TCGTargetOpDef r_r_rAL
93
- = { .args_ct_str = { "r", "r", "rAL" } };
94
- static const TCGTargetOpDef dep
95
- = { .args_ct_str = { "r", "0", "rZ" } };
96
- static const TCGTargetOpDef ext2
97
- = { .args_ct_str = { "r", "rZ", "rZ" } };
98
- static const TCGTargetOpDef movc
99
- = { .args_ct_str = { "r", "r", "rA", "rZ", "rZ" } };
100
- static const TCGTargetOpDef add2
101
- = { .args_ct_str = { "r", "r", "rZ", "rZ", "rA", "rMZ" } };
102
- static const TCGTargetOpDef w_w_w_w
103
- = { .args_ct_str = { "w", "w", "w", "w" } };
104
-
105
switch (op) {
106
case INDEX_op_goto_ptr:
107
- return &r;
108
+ return C_O0_I1(r);
109
110
case INDEX_op_ld8u_i32:
111
case INDEX_op_ld8s_i32:
112
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
113
case INDEX_op_extract_i64:
114
case INDEX_op_sextract_i32:
115
case INDEX_op_sextract_i64:
116
- return &r_r;
117
+ return C_O1_I1(r, r);
118
119
case INDEX_op_st8_i32:
120
case INDEX_op_st16_i32:
121
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
122
case INDEX_op_st16_i64:
123
case INDEX_op_st32_i64:
124
case INDEX_op_st_i64:
125
- return &rZ_r;
126
+ return C_O0_I2(rZ, r);
127
128
case INDEX_op_add_i32:
129
case INDEX_op_add_i64:
130
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
131
case INDEX_op_sub_i64:
132
case INDEX_op_setcond_i32:
133
case INDEX_op_setcond_i64:
134
- return &r_r_rA;
135
+ return C_O1_I2(r, r, rA);
136
137
case INDEX_op_mul_i32:
138
case INDEX_op_mul_i64:
139
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
140
case INDEX_op_remu_i64:
141
case INDEX_op_muluh_i64:
142
case INDEX_op_mulsh_i64:
143
- return &r_r_r;
144
+ return C_O1_I2(r, r, r);
145
146
case INDEX_op_and_i32:
147
case INDEX_op_and_i64:
148
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
149
case INDEX_op_orc_i64:
150
case INDEX_op_eqv_i32:
151
case INDEX_op_eqv_i64:
152
- return &r_r_rL;
153
+ return C_O1_I2(r, r, rL);
154
155
case INDEX_op_shl_i32:
156
case INDEX_op_shr_i32:
157
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
158
case INDEX_op_sar_i64:
159
case INDEX_op_rotl_i64:
160
case INDEX_op_rotr_i64:
161
- return &r_r_ri;
162
+ return C_O1_I2(r, r, ri);
163
164
case INDEX_op_clz_i32:
165
case INDEX_op_ctz_i32:
166
case INDEX_op_clz_i64:
167
case INDEX_op_ctz_i64:
168
- return &r_r_rAL;
169
+ return C_O1_I2(r, r, rAL);
170
171
case INDEX_op_brcond_i32:
172
case INDEX_op_brcond_i64:
173
- return &r_rA;
174
+ return C_O0_I2(r, rA);
175
176
case INDEX_op_movcond_i32:
177
case INDEX_op_movcond_i64:
178
- return &movc;
179
+ return C_O1_I4(r, r, rA, rZ, rZ);
180
181
case INDEX_op_qemu_ld_i32:
182
case INDEX_op_qemu_ld_i64:
183
- return &r_l;
184
+ return C_O1_I1(r, l);
185
case INDEX_op_qemu_st_i32:
186
case INDEX_op_qemu_st_i64:
187
- return &lZ_l;
188
+ return C_O0_I2(lZ, l);
189
190
case INDEX_op_deposit_i32:
191
case INDEX_op_deposit_i64:
192
- return &dep;
193
+ return C_O1_I2(r, 0, rZ);
194
195
case INDEX_op_extract2_i32:
196
case INDEX_op_extract2_i64:
197
- return &ext2;
198
+ return C_O1_I2(r, rZ, rZ);
199
200
case INDEX_op_add2_i32:
201
case INDEX_op_add2_i64:
202
case INDEX_op_sub2_i32:
203
case INDEX_op_sub2_i64:
204
- return &add2;
205
+ return C_O2_I4(r, r, rZ, rZ, rA, rMZ);
206
207
case INDEX_op_add_vec:
208
case INDEX_op_sub_vec:
209
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
210
case INDEX_op_shrv_vec:
211
case INDEX_op_sarv_vec:
212
case INDEX_op_aa64_sshl_vec:
213
- return &w_w_w;
214
+ return C_O1_I2(w, w, w);
215
case INDEX_op_not_vec:
216
case INDEX_op_neg_vec:
217
case INDEX_op_abs_vec:
218
case INDEX_op_shli_vec:
219
case INDEX_op_shri_vec:
220
case INDEX_op_sari_vec:
221
- return &w_w;
222
+ return C_O1_I1(w, w);
223
case INDEX_op_ld_vec:
224
- case INDEX_op_st_vec:
225
case INDEX_op_dupm_vec:
226
- return &w_r;
227
+ return C_O1_I1(w, r);
228
+ case INDEX_op_st_vec:
229
+ return C_O0_I2(w, r);
230
case INDEX_op_dup_vec:
231
- return &w_wr;
232
+ return C_O1_I1(w, wr);
233
case INDEX_op_or_vec:
234
case INDEX_op_andc_vec:
235
- return &w_w_wO;
236
+ return C_O1_I2(w, w, wO);
237
case INDEX_op_and_vec:
238
case INDEX_op_orc_vec:
239
- return &w_w_wN;
240
+ return C_O1_I2(w, w, wN);
241
case INDEX_op_cmp_vec:
242
- return &w_w_wZ;
243
+ return C_O1_I2(w, w, wZ);
244
case INDEX_op_bitsel_vec:
245
- return &w_w_w_w;
246
+ return C_O1_I3(w, w, w, w);
247
case INDEX_op_aa64_sli_vec:
248
- return &w_0_w;
249
+ return C_O1_I2(w, 0, w);
250
251
default:
252
- return NULL;
253
+ g_assert_not_reached();
254
}
42
}
255
}
43
256
44
/*
45
diff --git a/qom/cpu.c b/qom/cpu.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/qom/cpu.c
48
+++ b/qom/cpu.c
49
@@ -XXX,XX +XXX,XX @@ static void cpu_common_reset(CPUState *cpu)
50
cpu->mem_io_pc = 0;
51
cpu->mem_io_vaddr = 0;
52
cpu->icount_extra = 0;
53
- cpu->icount_decr.u32 = 0;
54
+ atomic_set(&cpu->icount_decr.u32, 0);
55
cpu->can_do_io = 1;
56
cpu->exception_index = -1;
57
cpu->crash_occurred = false;
58
--
257
--
59
2.17.2
258
2.25.1
60
259
61
260
diff view generated by jsdifflib
1
Reviewed-by: Emilio G. Cota <cota@braap.org>
1
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
3
---
5
target/i386/mem_helper.c | 9 ++++-----
4
tcg/arm/tcg-target-con-set.h | 35 ++++++++++++++
6
1 file changed, 4 insertions(+), 5 deletions(-)
5
tcg/arm/tcg-target.h | 1 +
6
tcg/arm/tcg-target.c.inc | 94 ++++++++++++------------------------
7
3 files changed, 68 insertions(+), 62 deletions(-)
8
create mode 100644 tcg/arm/tcg-target-con-set.h
7
9
8
diff --git a/target/i386/mem_helper.c b/target/i386/mem_helper.c
10
diff --git a/tcg/arm/tcg-target-con-set.h b/tcg/arm/tcg-target-con-set.h
11
new file mode 100644
12
index XXXXXXX..XXXXXXX
13
--- /dev/null
14
+++ b/tcg/arm/tcg-target-con-set.h
15
@@ -XXX,XX +XXX,XX @@
16
+/* SPDX-License-Identifier: MIT */
17
+/*
18
+ * Define Arm target-specific constraint sets.
19
+ * Copyright (c) 2021 Linaro
20
+ */
21
+
22
+/*
23
+ * C_On_Im(...) defines a constraint set with <n> outputs and <m> inputs.
24
+ * Each operand should be a sequence of constraint letters as defined by
25
+ * tcg-target-con-str.h; the constraint combination is inclusive or.
26
+ */
27
+C_O0_I1(r)
28
+C_O0_I2(r, r)
29
+C_O0_I2(r, rIN)
30
+C_O0_I2(s, s)
31
+C_O0_I3(s, s, s)
32
+C_O0_I4(r, r, rI, rI)
33
+C_O0_I4(s, s, s, s)
34
+C_O1_I1(r, l)
35
+C_O1_I1(r, r)
36
+C_O1_I2(r, 0, rZ)
37
+C_O1_I2(r, l, l)
38
+C_O1_I2(r, r, r)
39
+C_O1_I2(r, r, rI)
40
+C_O1_I2(r, r, rIK)
41
+C_O1_I2(r, r, rIN)
42
+C_O1_I2(r, r, ri)
43
+C_O1_I2(r, rZ, rZ)
44
+C_O1_I4(r, r, r, rI, rI)
45
+C_O1_I4(r, r, rIN, rIK, 0)
46
+C_O2_I1(r, r, l)
47
+C_O2_I2(r, r, l, l)
48
+C_O2_I2(r, r, r, r)
49
+C_O2_I4(r, r, r, r, rIN, rIK)
50
+C_O2_I4(r, r, rI, rI, rIN, rIK)
51
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
9
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
10
--- a/target/i386/mem_helper.c
53
--- a/tcg/arm/tcg-target.h
11
+++ b/target/i386/mem_helper.c
54
+++ b/tcg/arm/tcg-target.h
12
@@ -XXX,XX +XXX,XX @@
55
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
13
#include "exec/exec-all.h"
56
#define TCG_TARGET_NEED_LDST_LABELS
14
#include "exec/cpu_ldst.h"
57
#endif
15
#include "qemu/int128.h"
58
#define TCG_TARGET_NEED_POOL_LABELS
16
+#include "qemu/atomic128.h"
59
+#define TCG_TARGET_CON_SET_H
17
#include "tcg.h"
60
18
61
#endif
19
void helper_cmpxchg8b_unlocked(CPUX86State *env, target_ulong a0)
62
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
20
@@ -XXX,XX +XXX,XX @@ void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
63
index XXXXXXX..XXXXXXX 100644
21
64
--- a/tcg/arm/tcg-target.c.inc
22
if ((a0 & 0xf) != 0) {
65
+++ b/tcg/arm/tcg-target.c.inc
23
raise_exception_ra(env, EXCP0D_GPF, ra);
66
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
24
- } else {
25
-#ifndef CONFIG_ATOMIC128
26
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
27
-#else
28
+ } else if (HAVE_CMPXCHG128) {
29
int eflags = cpu_cc_compute_all(env, CC_OP);
30
31
Int128 cmpv = int128_make128(env->regs[R_EAX], env->regs[R_EDX]);
32
@@ -XXX,XX +XXX,XX @@ void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
33
eflags &= ~CC_Z;
34
}
35
CC_SRC = eflags;
36
-#endif
37
+ } else {
38
+ cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
39
}
67
}
40
}
68
}
41
#endif
69
70
-static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
71
+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
72
{
73
- static const TCGTargetOpDef r = { .args_ct_str = { "r" } };
74
- static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } };
75
- static const TCGTargetOpDef s_s = { .args_ct_str = { "s", "s" } };
76
- static const TCGTargetOpDef r_l = { .args_ct_str = { "r", "l" } };
77
- static const TCGTargetOpDef r_r_r = { .args_ct_str = { "r", "r", "r" } };
78
- static const TCGTargetOpDef r_r_l = { .args_ct_str = { "r", "r", "l" } };
79
- static const TCGTargetOpDef r_l_l = { .args_ct_str = { "r", "l", "l" } };
80
- static const TCGTargetOpDef s_s_s = { .args_ct_str = { "s", "s", "s" } };
81
- static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } };
82
- static const TCGTargetOpDef r_r_rI = { .args_ct_str = { "r", "r", "rI" } };
83
- static const TCGTargetOpDef r_r_rIN
84
- = { .args_ct_str = { "r", "r", "rIN" } };
85
- static const TCGTargetOpDef r_r_rIK
86
- = { .args_ct_str = { "r", "r", "rIK" } };
87
- static const TCGTargetOpDef r_r_r_r
88
- = { .args_ct_str = { "r", "r", "r", "r" } };
89
- static const TCGTargetOpDef r_r_l_l
90
- = { .args_ct_str = { "r", "r", "l", "l" } };
91
- static const TCGTargetOpDef s_s_s_s
92
- = { .args_ct_str = { "s", "s", "s", "s" } };
93
- static const TCGTargetOpDef br
94
- = { .args_ct_str = { "r", "rIN" } };
95
- static const TCGTargetOpDef ext2
96
- = { .args_ct_str = { "r", "rZ", "rZ" } };
97
- static const TCGTargetOpDef dep
98
- = { .args_ct_str = { "r", "0", "rZ" } };
99
- static const TCGTargetOpDef movc
100
- = { .args_ct_str = { "r", "r", "rIN", "rIK", "0" } };
101
- static const TCGTargetOpDef add2
102
- = { .args_ct_str = { "r", "r", "r", "r", "rIN", "rIK" } };
103
- static const TCGTargetOpDef sub2
104
- = { .args_ct_str = { "r", "r", "rI", "rI", "rIN", "rIK" } };
105
- static const TCGTargetOpDef br2
106
- = { .args_ct_str = { "r", "r", "rI", "rI" } };
107
- static const TCGTargetOpDef setc2
108
- = { .args_ct_str = { "r", "r", "r", "rI", "rI" } };
109
-
110
switch (op) {
111
case INDEX_op_goto_ptr:
112
- return &r;
113
+ return C_O0_I1(r);
114
115
case INDEX_op_ld8u_i32:
116
case INDEX_op_ld8s_i32:
117
case INDEX_op_ld16u_i32:
118
case INDEX_op_ld16s_i32:
119
case INDEX_op_ld_i32:
120
- case INDEX_op_st8_i32:
121
- case INDEX_op_st16_i32:
122
- case INDEX_op_st_i32:
123
case INDEX_op_neg_i32:
124
case INDEX_op_not_i32:
125
case INDEX_op_bswap16_i32:
126
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
127
case INDEX_op_ext16u_i32:
128
case INDEX_op_extract_i32:
129
case INDEX_op_sextract_i32:
130
- return &r_r;
131
+ return C_O1_I1(r, r);
132
+
133
+ case INDEX_op_st8_i32:
134
+ case INDEX_op_st16_i32:
135
+ case INDEX_op_st_i32:
136
+ return C_O0_I2(r, r);
137
138
case INDEX_op_add_i32:
139
case INDEX_op_sub_i32:
140
case INDEX_op_setcond_i32:
141
- return &r_r_rIN;
142
+ return C_O1_I2(r, r, rIN);
143
+
144
case INDEX_op_and_i32:
145
case INDEX_op_andc_i32:
146
case INDEX_op_clz_i32:
147
case INDEX_op_ctz_i32:
148
- return &r_r_rIK;
149
+ return C_O1_I2(r, r, rIK);
150
+
151
case INDEX_op_mul_i32:
152
case INDEX_op_div_i32:
153
case INDEX_op_divu_i32:
154
- return &r_r_r;
155
+ return C_O1_I2(r, r, r);
156
+
157
case INDEX_op_mulu2_i32:
158
case INDEX_op_muls2_i32:
159
- return &r_r_r_r;
160
+ return C_O2_I2(r, r, r, r);
161
+
162
case INDEX_op_or_i32:
163
case INDEX_op_xor_i32:
164
- return &r_r_rI;
165
+ return C_O1_I2(r, r, rI);
166
+
167
case INDEX_op_shl_i32:
168
case INDEX_op_shr_i32:
169
case INDEX_op_sar_i32:
170
case INDEX_op_rotl_i32:
171
case INDEX_op_rotr_i32:
172
- return &r_r_ri;
173
+ return C_O1_I2(r, r, ri);
174
175
case INDEX_op_brcond_i32:
176
- return &br;
177
+ return C_O0_I2(r, rIN);
178
case INDEX_op_deposit_i32:
179
- return &dep;
180
+ return C_O1_I2(r, 0, rZ);
181
case INDEX_op_extract2_i32:
182
- return &ext2;
183
+ return C_O1_I2(r, rZ, rZ);
184
case INDEX_op_movcond_i32:
185
- return &movc;
186
+ return C_O1_I4(r, r, rIN, rIK, 0);
187
case INDEX_op_add2_i32:
188
- return &add2;
189
+ return C_O2_I4(r, r, r, r, rIN, rIK);
190
case INDEX_op_sub2_i32:
191
- return &sub2;
192
+ return C_O2_I4(r, r, rI, rI, rIN, rIK);
193
case INDEX_op_brcond2_i32:
194
- return &br2;
195
+ return C_O0_I4(r, r, rI, rI);
196
case INDEX_op_setcond2_i32:
197
- return &setc2;
198
+ return C_O1_I4(r, r, r, rI, rI);
199
200
case INDEX_op_qemu_ld_i32:
201
- return TARGET_LONG_BITS == 32 ? &r_l : &r_l_l;
202
+ return TARGET_LONG_BITS == 32 ? C_O1_I1(r, l) : C_O1_I2(r, l, l);
203
case INDEX_op_qemu_ld_i64:
204
- return TARGET_LONG_BITS == 32 ? &r_r_l : &r_r_l_l;
205
+ return TARGET_LONG_BITS == 32 ? C_O2_I1(r, r, l) : C_O2_I2(r, r, l, l);
206
case INDEX_op_qemu_st_i32:
207
- return TARGET_LONG_BITS == 32 ? &s_s : &s_s_s;
208
+ return TARGET_LONG_BITS == 32 ? C_O0_I2(s, s) : C_O0_I3(s, s, s);
209
case INDEX_op_qemu_st_i64:
210
- return TARGET_LONG_BITS == 32 ? &s_s_s : &s_s_s_s;
211
+ return TARGET_LONG_BITS == 32 ? C_O0_I3(s, s, s) : C_O0_I4(s, s, s, s);
212
213
default:
214
- return NULL;
215
+ g_assert_not_reached();
216
}
217
}
218
42
--
219
--
43
2.17.2
220
2.25.1
44
221
45
222
diff view generated by jsdifflib
1
From: "Emilio G. Cota" <cota@braap.org>
1
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2
3
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Signed-off-by: Emilio G. Cota <cota@braap.org>
6
Message-Id: <20181009174557.16125-5-cota@braap.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
3
---
9
accel/tcg/cputlb.c | 4 ++--
4
tcg/mips/tcg-target-con-set.h | 36 +++++++++++++
10
1 file changed, 2 insertions(+), 2 deletions(-)
5
tcg/mips/tcg-target.h | 1 +
6
tcg/mips/tcg-target.c.inc | 96 +++++++++++------------------------
7
3 files changed, 66 insertions(+), 67 deletions(-)
8
create mode 100644 tcg/mips/tcg-target-con-set.h
11
9
12
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
10
diff --git a/tcg/mips/tcg-target-con-set.h b/tcg/mips/tcg-target-con-set.h
11
new file mode 100644
12
index XXXXXXX..XXXXXXX
13
--- /dev/null
14
+++ b/tcg/mips/tcg-target-con-set.h
15
@@ -XXX,XX +XXX,XX @@
16
+/* SPDX-License-Identifier: MIT */
17
+/*
18
+ * Define MIPS target-specific constraint sets.
19
+ * Copyright (c) 2021 Linaro
20
+ */
21
+
22
+/*
23
+ * C_On_Im(...) defines a constraint set with <n> outputs and <m> inputs.
24
+ * Each operand should be a sequence of constraint letters as defined by
25
+ * tcg-target-con-str.h; the constraint combination is inclusive or.
26
+ */
27
+C_O0_I1(r)
28
+C_O0_I2(rZ, r)
29
+C_O0_I2(rZ, rZ)
30
+C_O0_I2(SZ, S)
31
+C_O0_I3(SZ, S, S)
32
+C_O0_I3(SZ, SZ, S)
33
+C_O0_I4(rZ, rZ, rZ, rZ)
34
+C_O0_I4(SZ, SZ, S, S)
35
+C_O1_I1(r, L)
36
+C_O1_I1(r, r)
37
+C_O1_I2(r, 0, rZ)
38
+C_O1_I2(r, L, L)
39
+C_O1_I2(r, r, ri)
40
+C_O1_I2(r, r, rI)
41
+C_O1_I2(r, r, rIK)
42
+C_O1_I2(r, r, rJ)
43
+C_O1_I2(r, r, rWZ)
44
+C_O1_I2(r, rZ, rN)
45
+C_O1_I2(r, rZ, rZ)
46
+C_O1_I4(r, rZ, rZ, rZ, 0)
47
+C_O1_I4(r, rZ, rZ, rZ, rZ)
48
+C_O2_I1(r, r, L)
49
+C_O2_I2(r, r, L, L)
50
+C_O2_I2(r, r, r, r)
51
+C_O2_I4(r, r, rZ, rZ, rN, rN)
52
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
13
index XXXXXXX..XXXXXXX 100644
53
index XXXXXXX..XXXXXXX 100644
14
--- a/accel/tcg/cputlb.c
54
--- a/tcg/mips/tcg-target.h
15
+++ b/accel/tcg/cputlb.c
55
+++ b/tcg/mips/tcg-target.h
16
@@ -XXX,XX +XXX,XX @@
56
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
17
} \
57
#ifdef CONFIG_SOFTMMU
18
} while (0)
58
#define TCG_TARGET_NEED_LDST_LABELS
19
59
#endif
20
-#define assert_cpu_is_self(this_cpu) do { \
60
+#define TCG_TARGET_CON_SET_H
21
+#define assert_cpu_is_self(cpu) do { \
61
22
if (DEBUG_TLB_GATE) { \
62
#endif
23
- g_assert(!cpu->created || qemu_cpu_is_self(cpu)); \
63
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
24
+ g_assert(!(cpu)->created || qemu_cpu_is_self(cpu)); \
64
index XXXXXXX..XXXXXXX 100644
25
} \
65
--- a/tcg/mips/tcg-target.c.inc
26
} while (0)
66
+++ b/tcg/mips/tcg-target.c.inc
67
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
68
}
69
}
70
71
-static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
72
+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
73
{
74
- static const TCGTargetOpDef r = { .args_ct_str = { "r" } };
75
- static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } };
76
- static const TCGTargetOpDef r_L = { .args_ct_str = { "r", "L" } };
77
- static const TCGTargetOpDef rZ_r = { .args_ct_str = { "rZ", "r" } };
78
- static const TCGTargetOpDef SZ_S = { .args_ct_str = { "SZ", "S" } };
79
- static const TCGTargetOpDef rZ_rZ = { .args_ct_str = { "rZ", "rZ" } };
80
- static const TCGTargetOpDef r_r_L = { .args_ct_str = { "r", "r", "L" } };
81
- static const TCGTargetOpDef r_L_L = { .args_ct_str = { "r", "L", "L" } };
82
- static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } };
83
- static const TCGTargetOpDef r_r_rI = { .args_ct_str = { "r", "r", "rI" } };
84
- static const TCGTargetOpDef r_r_rJ = { .args_ct_str = { "r", "r", "rJ" } };
85
- static const TCGTargetOpDef SZ_S_S = { .args_ct_str = { "SZ", "S", "S" } };
86
- static const TCGTargetOpDef SZ_SZ_S
87
- = { .args_ct_str = { "SZ", "SZ", "S" } };
88
- static const TCGTargetOpDef SZ_SZ_S_S
89
- = { .args_ct_str = { "SZ", "SZ", "S", "S" } };
90
- static const TCGTargetOpDef r_rZ_rN
91
- = { .args_ct_str = { "r", "rZ", "rN" } };
92
- static const TCGTargetOpDef r_rZ_rZ
93
- = { .args_ct_str = { "r", "rZ", "rZ" } };
94
- static const TCGTargetOpDef r_r_rIK
95
- = { .args_ct_str = { "r", "r", "rIK" } };
96
- static const TCGTargetOpDef r_r_rWZ
97
- = { .args_ct_str = { "r", "r", "rWZ" } };
98
- static const TCGTargetOpDef r_r_r_r
99
- = { .args_ct_str = { "r", "r", "r", "r" } };
100
- static const TCGTargetOpDef r_r_L_L
101
- = { .args_ct_str = { "r", "r", "L", "L" } };
102
- static const TCGTargetOpDef dep
103
- = { .args_ct_str = { "r", "0", "rZ" } };
104
- static const TCGTargetOpDef movc
105
- = { .args_ct_str = { "r", "rZ", "rZ", "rZ", "0" } };
106
- static const TCGTargetOpDef movc_r6
107
- = { .args_ct_str = { "r", "rZ", "rZ", "rZ", "rZ" } };
108
- static const TCGTargetOpDef add2
109
- = { .args_ct_str = { "r", "r", "rZ", "rZ", "rN", "rN" } };
110
- static const TCGTargetOpDef br2
111
- = { .args_ct_str = { "rZ", "rZ", "rZ", "rZ" } };
112
- static const TCGTargetOpDef setc2
113
- = { .args_ct_str = { "r", "rZ", "rZ", "rZ", "rZ" } };
114
-
115
switch (op) {
116
case INDEX_op_goto_ptr:
117
- return &r;
118
+ return C_O0_I1(r);
119
120
case INDEX_op_ld8u_i32:
121
case INDEX_op_ld8s_i32:
122
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
123
case INDEX_op_extrl_i64_i32:
124
case INDEX_op_extrh_i64_i32:
125
case INDEX_op_extract_i64:
126
- return &r_r;
127
+ return C_O1_I1(r, r);
128
129
case INDEX_op_st8_i32:
130
case INDEX_op_st16_i32:
131
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
132
case INDEX_op_st16_i64:
133
case INDEX_op_st32_i64:
134
case INDEX_op_st_i64:
135
- return &rZ_r;
136
+ return C_O0_I2(rZ, r);
137
138
case INDEX_op_add_i32:
139
case INDEX_op_add_i64:
140
- return &r_r_rJ;
141
+ return C_O1_I2(r, r, rJ);
142
case INDEX_op_sub_i32:
143
case INDEX_op_sub_i64:
144
- return &r_rZ_rN;
145
+ return C_O1_I2(r, rZ, rN);
146
case INDEX_op_mul_i32:
147
case INDEX_op_mulsh_i32:
148
case INDEX_op_muluh_i32:
149
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
150
case INDEX_op_remu_i64:
151
case INDEX_op_nor_i64:
152
case INDEX_op_setcond_i64:
153
- return &r_rZ_rZ;
154
+ return C_O1_I2(r, rZ, rZ);
155
case INDEX_op_muls2_i32:
156
case INDEX_op_mulu2_i32:
157
case INDEX_op_muls2_i64:
158
case INDEX_op_mulu2_i64:
159
- return &r_r_r_r;
160
+ return C_O2_I2(r, r, r, r);
161
case INDEX_op_and_i32:
162
case INDEX_op_and_i64:
163
- return &r_r_rIK;
164
+ return C_O1_I2(r, r, rIK);
165
case INDEX_op_or_i32:
166
case INDEX_op_xor_i32:
167
case INDEX_op_or_i64:
168
case INDEX_op_xor_i64:
169
- return &r_r_rI;
170
+ return C_O1_I2(r, r, rI);
171
case INDEX_op_shl_i32:
172
case INDEX_op_shr_i32:
173
case INDEX_op_sar_i32:
174
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
175
case INDEX_op_sar_i64:
176
case INDEX_op_rotr_i64:
177
case INDEX_op_rotl_i64:
178
- return &r_r_ri;
179
+ return C_O1_I2(r, r, ri);
180
case INDEX_op_clz_i32:
181
case INDEX_op_clz_i64:
182
- return &r_r_rWZ;
183
+ return C_O1_I2(r, r, rWZ);
184
185
case INDEX_op_deposit_i32:
186
case INDEX_op_deposit_i64:
187
- return &dep;
188
+ return C_O1_I2(r, 0, rZ);
189
case INDEX_op_brcond_i32:
190
case INDEX_op_brcond_i64:
191
- return &rZ_rZ;
192
+ return C_O0_I2(rZ, rZ);
193
case INDEX_op_movcond_i32:
194
case INDEX_op_movcond_i64:
195
- return use_mips32r6_instructions ? &movc_r6 : &movc;
196
-
197
+ return (use_mips32r6_instructions
198
+ ? C_O1_I4(r, rZ, rZ, rZ, rZ)
199
+ : C_O1_I4(r, rZ, rZ, rZ, 0));
200
case INDEX_op_add2_i32:
201
case INDEX_op_sub2_i32:
202
- return &add2;
203
+ return C_O2_I4(r, r, rZ, rZ, rN, rN);
204
case INDEX_op_setcond2_i32:
205
- return &setc2;
206
+ return C_O1_I4(r, rZ, rZ, rZ, rZ);
207
case INDEX_op_brcond2_i32:
208
- return &br2;
209
+ return C_O0_I4(rZ, rZ, rZ, rZ);
210
211
case INDEX_op_qemu_ld_i32:
212
return (TCG_TARGET_REG_BITS == 64 || TARGET_LONG_BITS == 32
213
- ? &r_L : &r_L_L);
214
+ ? C_O1_I1(r, L) : C_O1_I2(r, L, L));
215
case INDEX_op_qemu_st_i32:
216
return (TCG_TARGET_REG_BITS == 64 || TARGET_LONG_BITS == 32
217
- ? &SZ_S : &SZ_S_S);
218
+ ? C_O0_I2(SZ, S) : C_O0_I3(SZ, S, S));
219
case INDEX_op_qemu_ld_i64:
220
- return (TCG_TARGET_REG_BITS == 64 ? &r_L
221
- : TARGET_LONG_BITS == 32 ? &r_r_L : &r_r_L_L);
222
+ return (TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, L)
223
+ : TARGET_LONG_BITS == 32 ? C_O2_I1(r, r, L)
224
+ : C_O2_I2(r, r, L, L));
225
case INDEX_op_qemu_st_i64:
226
- return (TCG_TARGET_REG_BITS == 64 ? &SZ_S
227
- : TARGET_LONG_BITS == 32 ? &SZ_SZ_S : &SZ_SZ_S_S);
228
+ return (TCG_TARGET_REG_BITS == 64 ? C_O0_I2(SZ, S)
229
+ : TARGET_LONG_BITS == 32 ? C_O0_I3(SZ, SZ, S)
230
+ : C_O0_I4(SZ, SZ, S, S));
231
232
default:
233
- return NULL;
234
+ g_assert_not_reached();
235
}
236
}
27
237
28
--
238
--
29
2.17.2
239
2.25.1
30
240
31
241
diff view generated by jsdifflib
1
Reviewed-by: David Hildenbrand <david@redhat.com>
1
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
3
---
4
target/s390x/mem_helper.c | 92 +++++++++++++++++----------------------
4
tcg/ppc/tcg-target-con-set.h | 42 +++++++++++
5
1 file changed, 41 insertions(+), 51 deletions(-)
5
tcg/ppc/tcg-target.h | 1 +
6
tcg/ppc/tcg-target.c.inc | 136 +++++++++++++++--------------------
7
3 files changed, 99 insertions(+), 80 deletions(-)
8
create mode 100644 tcg/ppc/tcg-target-con-set.h
6
9
7
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
10
diff --git a/tcg/ppc/tcg-target-con-set.h b/tcg/ppc/tcg-target-con-set.h
11
new file mode 100644
12
index XXXXXXX..XXXXXXX
13
--- /dev/null
14
+++ b/tcg/ppc/tcg-target-con-set.h
15
@@ -XXX,XX +XXX,XX @@
16
+/* SPDX-License-Identifier: MIT */
17
+/*
18
+ * Define PowerPC target-specific constraint sets.
19
+ * Copyright (c) 2021 Linaro
20
+ */
21
+
22
+/*
23
+ * C_On_Im(...) defines a constraint set with <n> outputs and <m> inputs.
24
+ * Each operand should be a sequence of constraint letters as defined by
25
+ * tcg-target-con-str.h; the constraint combination is inclusive or.
26
+ */
27
+C_O0_I1(r)
28
+C_O0_I2(r, r)
29
+C_O0_I2(r, ri)
30
+C_O0_I2(S, S)
31
+C_O0_I2(v, r)
32
+C_O0_I3(S, S, S)
33
+C_O0_I4(r, r, ri, ri)
34
+C_O0_I4(S, S, S, S)
35
+C_O1_I1(r, L)
36
+C_O1_I1(r, r)
37
+C_O1_I1(v, r)
38
+C_O1_I1(v, v)
39
+C_O1_I1(v, vr)
40
+C_O1_I2(r, 0, rZ)
41
+C_O1_I2(r, L, L)
42
+C_O1_I2(r, rI, ri)
43
+C_O1_I2(r, rI, rT)
44
+C_O1_I2(r, r, r)
45
+C_O1_I2(r, r, ri)
46
+C_O1_I2(r, r, rI)
47
+C_O1_I2(r, r, rT)
48
+C_O1_I2(r, r, rU)
49
+C_O1_I2(r, r, rZW)
50
+C_O1_I2(v, v, v)
51
+C_O1_I3(v, v, v, v)
52
+C_O1_I4(r, r, ri, rZ, rZ)
53
+C_O1_I4(r, r, r, ri, ri)
54
+C_O2_I1(L, L, L)
55
+C_O2_I2(L, L, L, L)
56
+C_O2_I4(r, r, rI, rZM, r, r)
57
+C_O2_I4(r, r, r, r, rI, rZM)
58
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
8
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
9
--- a/target/s390x/mem_helper.c
60
--- a/tcg/ppc/tcg-target.h
10
+++ b/target/s390x/mem_helper.c
61
+++ b/tcg/ppc/tcg-target.h
11
@@ -XXX,XX +XXX,XX @@
62
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
12
#include "exec/exec-all.h"
63
#define TCG_TARGET_NEED_LDST_LABELS
13
#include "exec/cpu_ldst.h"
64
#endif
14
#include "qemu/int128.h"
65
#define TCG_TARGET_NEED_POOL_LABELS
15
+#include "qemu/atomic128.h"
66
+#define TCG_TARGET_CON_SET_H
16
67
17
#if !defined(CONFIG_USER_ONLY)
68
#endif
18
#include "hw/s390x/storage-keys.h"
69
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
19
@@ -XXX,XX +XXX,XX @@ static void do_cdsg(CPUS390XState *env, uint64_t addr,
70
index XXXXXXX..XXXXXXX 100644
20
bool fail;
71
--- a/tcg/ppc/tcg-target.c.inc
21
72
+++ b/tcg/ppc/tcg-target.c.inc
22
if (parallel) {
73
@@ -XXX,XX +XXX,XX @@ void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece,
23
-#ifndef CONFIG_ATOMIC128
74
va_end(va);
24
+#if !HAVE_CMPXCHG128
75
}
25
cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
76
26
#else
77
-static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
27
int mem_idx = cpu_mmu_index(env, false);
78
+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
28
@@ -XXX,XX +XXX,XX @@ void HELPER(cdsg_parallel)(CPUS390XState *env, uint64_t addr,
29
static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
30
uint64_t a2, bool parallel)
31
{
79
{
32
-#if !defined(CONFIG_USER_ONLY) || defined(CONFIG_ATOMIC128)
80
- static const TCGTargetOpDef r = { .args_ct_str = { "r" } };
33
uint32_t mem_idx = cpu_mmu_index(env, false);
81
- static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } };
34
-#endif
82
- static const TCGTargetOpDef r_L = { .args_ct_str = { "r", "L" } };
35
uintptr_t ra = GETPC();
83
- static const TCGTargetOpDef S_S = { .args_ct_str = { "S", "S" } };
36
uint32_t fc = extract32(env->regs[0], 0, 8);
84
- static const TCGTargetOpDef r_ri = { .args_ct_str = { "r", "ri" } };
37
uint32_t sc = extract32(env->regs[0], 8, 8);
85
- static const TCGTargetOpDef r_r_r = { .args_ct_str = { "r", "r", "r" } };
38
@@ -XXX,XX +XXX,XX @@ static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
86
- static const TCGTargetOpDef r_L_L = { .args_ct_str = { "r", "L", "L" } };
39
probe_write(env, a2, 0, mem_idx, ra);
87
- static const TCGTargetOpDef L_L_L = { .args_ct_str = { "L", "L", "L" } };
40
#endif
88
- static const TCGTargetOpDef S_S_S = { .args_ct_str = { "S", "S", "S" } };
41
89
- static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } };
42
- /* Note that the compare-and-swap is atomic, and the store is atomic, but
90
- static const TCGTargetOpDef r_r_rI = { .args_ct_str = { "r", "r", "rI" } };
43
- the complete operation is not. Therefore we do not need to assert serial
91
- static const TCGTargetOpDef r_r_rT = { .args_ct_str = { "r", "r", "rT" } };
44
- context in order to implement this. That said, restart early if we can't
92
- static const TCGTargetOpDef r_r_rU = { .args_ct_str = { "r", "r", "rU" } };
45
- support either operation that is supposed to be atomic. */
93
- static const TCGTargetOpDef r_rI_ri
46
+ /*
94
- = { .args_ct_str = { "r", "rI", "ri" } };
47
+ * Note that the compare-and-swap is atomic, and the store is atomic,
95
- static const TCGTargetOpDef r_rI_rT
48
+ * but the complete operation is not. Therefore we do not need to
96
- = { .args_ct_str = { "r", "rI", "rT" } };
49
+ * assert serial context in order to implement this. That said,
97
- static const TCGTargetOpDef r_r_rZW
50
+ * restart early if we can't support either operation that is supposed
98
- = { .args_ct_str = { "r", "r", "rZW" } };
51
+ * to be atomic.
99
- static const TCGTargetOpDef L_L_L_L
52
+ */
100
- = { .args_ct_str = { "L", "L", "L", "L" } };
53
if (parallel) {
101
- static const TCGTargetOpDef S_S_S_S
54
- int mask = 0;
102
- = { .args_ct_str = { "S", "S", "S", "S" } };
55
-#if !defined(CONFIG_ATOMIC64)
103
- static const TCGTargetOpDef movc
56
- mask = -8;
104
- = { .args_ct_str = { "r", "r", "ri", "rZ", "rZ" } };
57
-#elif !defined(CONFIG_ATOMIC128)
105
- static const TCGTargetOpDef dep
58
- mask = -16;
106
- = { .args_ct_str = { "r", "0", "rZ" } };
59
+ uint32_t max = 2;
107
- static const TCGTargetOpDef br2
60
+#ifdef CONFIG_ATOMIC64
108
- = { .args_ct_str = { "r", "r", "ri", "ri" } };
61
+ max = 3;
109
- static const TCGTargetOpDef setc2
62
#endif
110
- = { .args_ct_str = { "r", "r", "r", "ri", "ri" } };
63
- if (((4 << fc) | (1 << sc)) & mask) {
111
- static const TCGTargetOpDef add2
64
+ if ((HAVE_CMPXCHG128 ? 0 : fc + 2 > max) ||
112
- = { .args_ct_str = { "r", "r", "r", "r", "rI", "rZM" } };
65
+ (HAVE_ATOMIC128 ? 0 : sc > max)) {
113
- static const TCGTargetOpDef sub2
66
cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
114
- = { .args_ct_str = { "r", "r", "rI", "rZM", "r", "r" } };
67
}
115
- static const TCGTargetOpDef v_r = { .args_ct_str = { "v", "r" } };
68
}
116
- static const TCGTargetOpDef v_vr = { .args_ct_str = { "v", "vr" } };
69
@@ -XXX,XX +XXX,XX @@ static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
117
- static const TCGTargetOpDef v_v = { .args_ct_str = { "v", "v" } };
70
Int128 cv = int128_make128(env->regs[r3 + 1], env->regs[r3]);
118
- static const TCGTargetOpDef v_v_v = { .args_ct_str = { "v", "v", "v" } };
71
Int128 ov;
119
- static const TCGTargetOpDef v_v_v_v
72
120
- = { .args_ct_str = { "v", "v", "v", "v" } };
73
- if (parallel) {
74
-#ifdef CONFIG_ATOMIC128
75
- TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
76
- ov = helper_atomic_cmpxchgo_be_mmu(env, a1, cv, nv, oi, ra);
77
- cc = !int128_eq(ov, cv);
78
-#else
79
- /* Note that we asserted !parallel above. */
80
- g_assert_not_reached();
81
-#endif
82
- } else {
83
+ if (!parallel) {
84
uint64_t oh = cpu_ldq_data_ra(env, a1 + 0, ra);
85
uint64_t ol = cpu_ldq_data_ra(env, a1 + 8, ra);
86
87
@@ -XXX,XX +XXX,XX @@ static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
88
89
cpu_stq_data_ra(env, a1 + 0, int128_gethi(nv), ra);
90
cpu_stq_data_ra(env, a1 + 8, int128_getlo(nv), ra);
91
+ } else if (HAVE_CMPXCHG128) {
92
+ TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
93
+ ov = helper_atomic_cmpxchgo_be_mmu(env, a1, cv, nv, oi, ra);
94
+ cc = !int128_eq(ov, cv);
95
+ } else {
96
+ /* Note that we asserted !parallel above. */
97
+ g_assert_not_reached();
98
}
99
100
env->regs[r3 + 0] = int128_gethi(ov);
101
@@ -XXX,XX +XXX,XX @@ static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
102
cpu_stq_data_ra(env, a2, svh, ra);
103
break;
104
case 4:
105
- if (parallel) {
106
-#ifdef CONFIG_ATOMIC128
107
+ if (!parallel) {
108
+ cpu_stq_data_ra(env, a2 + 0, svh, ra);
109
+ cpu_stq_data_ra(env, a2 + 8, svl, ra);
110
+ } else if (HAVE_ATOMIC128) {
111
TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
112
Int128 sv = int128_make128(svl, svh);
113
helper_atomic_sto_be_mmu(env, a2, sv, oi, ra);
114
-#else
115
+ } else {
116
/* Note that we asserted !parallel above. */
117
g_assert_not_reached();
118
-#endif
119
- } else {
120
- cpu_stq_data_ra(env, a2 + 0, svh, ra);
121
- cpu_stq_data_ra(env, a2 + 8, svl, ra);
122
}
123
break;
124
default:
125
@@ -XXX,XX +XXX,XX @@ static uint64_t do_lpq(CPUS390XState *env, uint64_t addr, bool parallel)
126
uintptr_t ra = GETPC();
127
uint64_t hi, lo;
128
129
- if (parallel) {
130
-#ifndef CONFIG_ATOMIC128
131
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
132
-#else
133
+ if (!parallel) {
134
+ check_alignment(env, addr, 16, ra);
135
+ hi = cpu_ldq_data_ra(env, addr + 0, ra);
136
+ lo = cpu_ldq_data_ra(env, addr + 8, ra);
137
+ } else if (HAVE_ATOMIC128) {
138
int mem_idx = cpu_mmu_index(env, false);
139
TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
140
Int128 v = helper_atomic_ldo_be_mmu(env, addr, oi, ra);
141
hi = int128_gethi(v);
142
lo = int128_getlo(v);
143
-#endif
144
} else {
145
- check_alignment(env, addr, 16, ra);
146
-
121
-
147
- hi = cpu_ldq_data_ra(env, addr + 0, ra);
122
switch (op) {
148
- lo = cpu_ldq_data_ra(env, addr + 8, ra);
123
case INDEX_op_goto_ptr:
149
+ cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
124
- return &r;
150
}
125
+ return C_O0_I1(r);
151
126
152
env->retxl = lo;
127
case INDEX_op_ld8u_i32:
153
@@ -XXX,XX +XXX,XX @@ static void do_stpq(CPUS390XState *env, uint64_t addr,
128
case INDEX_op_ld8s_i32:
154
{
129
case INDEX_op_ld16u_i32:
155
uintptr_t ra = GETPC();
130
case INDEX_op_ld16s_i32:
156
131
case INDEX_op_ld_i32:
157
- if (parallel) {
132
- case INDEX_op_st8_i32:
158
-#ifndef CONFIG_ATOMIC128
133
- case INDEX_op_st16_i32:
159
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
134
- case INDEX_op_st_i32:
160
-#else
135
case INDEX_op_ctpop_i32:
161
- int mem_idx = cpu_mmu_index(env, false);
136
case INDEX_op_neg_i32:
162
- TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
137
case INDEX_op_not_i32:
163
-
138
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
164
- Int128 v = int128_make128(low, high);
139
case INDEX_op_ld32u_i64:
165
- helper_atomic_sto_be_mmu(env, addr, v, oi, ra);
140
case INDEX_op_ld32s_i64:
166
-#endif
141
case INDEX_op_ld_i64:
167
- } else {
142
- case INDEX_op_st8_i64:
168
+ if (!parallel) {
143
- case INDEX_op_st16_i64:
169
check_alignment(env, addr, 16, ra);
144
- case INDEX_op_st32_i64:
170
-
145
- case INDEX_op_st_i64:
171
cpu_stq_data_ra(env, addr + 0, high, ra);
146
case INDEX_op_ctpop_i64:
172
cpu_stq_data_ra(env, addr + 8, low, ra);
147
case INDEX_op_neg_i64:
173
+ } else if (HAVE_ATOMIC128) {
148
case INDEX_op_not_i64:
174
+ int mem_idx = cpu_mmu_index(env, false);
149
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
175
+ TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
150
case INDEX_op_bswap32_i64:
176
+ Int128 v = int128_make128(low, high);
151
case INDEX_op_bswap64_i64:
177
+ helper_atomic_sto_be_mmu(env, addr, v, oi, ra);
152
case INDEX_op_extract_i64:
178
+ } else {
153
- return &r_r;
179
+ cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
154
+ return C_O1_I1(r, r);
155
+
156
+ case INDEX_op_st8_i32:
157
+ case INDEX_op_st16_i32:
158
+ case INDEX_op_st_i32:
159
+ case INDEX_op_st8_i64:
160
+ case INDEX_op_st16_i64:
161
+ case INDEX_op_st32_i64:
162
+ case INDEX_op_st_i64:
163
+ return C_O0_I2(r, r);
164
165
case INDEX_op_add_i32:
166
case INDEX_op_and_i32:
167
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
168
case INDEX_op_rotl_i64:
169
case INDEX_op_rotr_i64:
170
case INDEX_op_setcond_i64:
171
- return &r_r_ri;
172
+ return C_O1_I2(r, r, ri);
173
+
174
case INDEX_op_mul_i32:
175
case INDEX_op_mul_i64:
176
- return &r_r_rI;
177
+ return C_O1_I2(r, r, rI);
178
+
179
case INDEX_op_div_i32:
180
case INDEX_op_divu_i32:
181
case INDEX_op_nand_i32:
182
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
183
case INDEX_op_divu_i64:
184
case INDEX_op_mulsh_i64:
185
case INDEX_op_muluh_i64:
186
- return &r_r_r;
187
+ return C_O1_I2(r, r, r);
188
+
189
case INDEX_op_sub_i32:
190
- return &r_rI_ri;
191
+ return C_O1_I2(r, rI, ri);
192
case INDEX_op_add_i64:
193
- return &r_r_rT;
194
+ return C_O1_I2(r, r, rT);
195
case INDEX_op_or_i64:
196
case INDEX_op_xor_i64:
197
- return &r_r_rU;
198
+ return C_O1_I2(r, r, rU);
199
case INDEX_op_sub_i64:
200
- return &r_rI_rT;
201
+ return C_O1_I2(r, rI, rT);
202
case INDEX_op_clz_i32:
203
case INDEX_op_ctz_i32:
204
case INDEX_op_clz_i64:
205
case INDEX_op_ctz_i64:
206
- return &r_r_rZW;
207
+ return C_O1_I2(r, r, rZW);
208
209
case INDEX_op_brcond_i32:
210
case INDEX_op_brcond_i64:
211
- return &r_ri;
212
+ return C_O0_I2(r, ri);
213
214
case INDEX_op_movcond_i32:
215
case INDEX_op_movcond_i64:
216
- return &movc;
217
+ return C_O1_I4(r, r, ri, rZ, rZ);
218
case INDEX_op_deposit_i32:
219
case INDEX_op_deposit_i64:
220
- return &dep;
221
+ return C_O1_I2(r, 0, rZ);
222
case INDEX_op_brcond2_i32:
223
- return &br2;
224
+ return C_O0_I4(r, r, ri, ri);
225
case INDEX_op_setcond2_i32:
226
- return &setc2;
227
+ return C_O1_I4(r, r, r, ri, ri);
228
case INDEX_op_add2_i64:
229
case INDEX_op_add2_i32:
230
- return &add2;
231
+ return C_O2_I4(r, r, r, r, rI, rZM);
232
case INDEX_op_sub2_i64:
233
case INDEX_op_sub2_i32:
234
- return &sub2;
235
+ return C_O2_I4(r, r, rI, rZM, r, r);
236
237
case INDEX_op_qemu_ld_i32:
238
return (TCG_TARGET_REG_BITS == 64 || TARGET_LONG_BITS == 32
239
- ? &r_L : &r_L_L);
240
+ ? C_O1_I1(r, L)
241
+ : C_O1_I2(r, L, L));
242
+
243
case INDEX_op_qemu_st_i32:
244
return (TCG_TARGET_REG_BITS == 64 || TARGET_LONG_BITS == 32
245
- ? &S_S : &S_S_S);
246
+ ? C_O0_I2(S, S)
247
+ : C_O0_I3(S, S, S));
248
+
249
case INDEX_op_qemu_ld_i64:
250
- return (TCG_TARGET_REG_BITS == 64 ? &r_L
251
- : TARGET_LONG_BITS == 32 ? &L_L_L : &L_L_L_L);
252
+ return (TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, L)
253
+ : TARGET_LONG_BITS == 32 ? C_O2_I1(L, L, L)
254
+ : C_O2_I2(L, L, L, L));
255
+
256
case INDEX_op_qemu_st_i64:
257
- return (TCG_TARGET_REG_BITS == 64 ? &S_S
258
- : TARGET_LONG_BITS == 32 ? &S_S_S : &S_S_S_S);
259
+ return (TCG_TARGET_REG_BITS == 64 ? C_O0_I2(S, S)
260
+ : TARGET_LONG_BITS == 32 ? C_O0_I3(S, S, S)
261
+ : C_O0_I4(S, S, S, S));
262
263
case INDEX_op_add_vec:
264
case INDEX_op_sub_vec:
265
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
266
case INDEX_op_ppc_mulou_vec:
267
case INDEX_op_ppc_pkum_vec:
268
case INDEX_op_dup2_vec:
269
- return &v_v_v;
270
+ return C_O1_I2(v, v, v);
271
+
272
case INDEX_op_not_vec:
273
case INDEX_op_neg_vec:
274
- return &v_v;
275
+ return C_O1_I1(v, v);
276
+
277
case INDEX_op_dup_vec:
278
- return have_isa_3_00 ? &v_vr : &v_v;
279
+ return have_isa_3_00 ? C_O1_I1(v, vr) : C_O1_I1(v, v);
280
+
281
case INDEX_op_ld_vec:
282
- case INDEX_op_st_vec:
283
case INDEX_op_dupm_vec:
284
- return &v_r;
285
+ return C_O1_I1(v, r);
286
+
287
+ case INDEX_op_st_vec:
288
+ return C_O0_I2(v, r);
289
+
290
case INDEX_op_bitsel_vec:
291
case INDEX_op_ppc_msum_vec:
292
- return &v_v_v_v;
293
+ return C_O1_I3(v, v, v, v);
294
295
default:
296
- return NULL;
297
+ g_assert_not_reached();
180
}
298
}
181
}
299
}
182
300
183
--
301
--
184
2.17.2
302
2.25.1
185
303
186
304
diff view generated by jsdifflib
1
Isolate the computation of an index from an address into a
1
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2
helper before we change that function.
2
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
5
tcg/riscv/tcg-target-con-set.h | 30 ++++++++++++
6
tcg/riscv/tcg-target.h | 1 +
7
tcg/riscv/tcg-target.c.inc | 83 ++++++++++------------------------
8
3 files changed, 54 insertions(+), 60 deletions(-)
9
create mode 100644 tcg/riscv/tcg-target-con-set.h
3
10
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
diff --git a/tcg/riscv/tcg-target-con-set.h b/tcg/riscv/tcg-target-con-set.h
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
new file mode 100644
6
[ cota: convert tlb_vaddr_to_host; use atomic_read on addr_write ]
13
index XXXXXXX..XXXXXXX
7
Signed-off-by: Emilio G. Cota <cota@braap.org>
14
--- /dev/null
8
Message-Id: <20181009175129.17888-2-cota@braap.org>
15
+++ b/tcg/riscv/tcg-target-con-set.h
9
---
16
@@ -XXX,XX +XXX,XX @@
10
accel/tcg/softmmu_template.h | 64 +++++++++++++++++---------------
17
+/* SPDX-License-Identifier: MIT */
11
include/exec/cpu_ldst.h | 19 ++++++++--
18
+/*
12
include/exec/cpu_ldst_template.h | 25 +++++++------
19
+ * Define RISC-V target-specific constraint sets.
13
accel/tcg/cputlb.c | 60 ++++++++++++++----------------
20
+ * Copyright (c) 2021 Linaro
14
4 files changed, 90 insertions(+), 78 deletions(-)
21
+ */
15
22
+
16
diff --git a/accel/tcg/softmmu_template.h b/accel/tcg/softmmu_template.h
23
+/*
24
+ * C_On_Im(...) defines a constraint set with <n> outputs and <m> inputs.
25
+ * Each operand should be a sequence of constraint letters as defined by
26
+ * tcg-target-con-str.h; the constraint combination is inclusive or.
27
+ */
28
+C_O0_I1(r)
29
+C_O0_I2(LZ, L)
30
+C_O0_I2(rZ, r)
31
+C_O0_I2(rZ, rZ)
32
+C_O0_I3(LZ, L, L)
33
+C_O0_I3(LZ, LZ, L)
34
+C_O0_I4(LZ, LZ, L, L)
35
+C_O0_I4(rZ, rZ, rZ, rZ)
36
+C_O1_I1(r, L)
37
+C_O1_I1(r, r)
38
+C_O1_I2(r, L, L)
39
+C_O1_I2(r, r, ri)
40
+C_O1_I2(r, r, rI)
41
+C_O1_I2(r, rZ, rN)
42
+C_O1_I2(r, rZ, rZ)
43
+C_O1_I4(r, rZ, rZ, rZ, rZ)
44
+C_O2_I1(r, r, L)
45
+C_O2_I2(r, r, L, L)
46
+C_O2_I4(r, r, rZ, rZ, rM, rM)
47
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
17
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
18
--- a/accel/tcg/softmmu_template.h
49
--- a/tcg/riscv/tcg-target.h
19
+++ b/accel/tcg/softmmu_template.h
50
+++ b/tcg/riscv/tcg-target.h
20
@@ -XXX,XX +XXX,XX @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
51
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
21
WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
52
#define TCG_TARGET_NEED_POOL_LABELS
22
TCGMemOpIdx oi, uintptr_t retaddr)
53
23
{
54
#define TCG_TARGET_HAS_MEMORY_BSWAP 0
24
- unsigned mmu_idx = get_mmuidx(oi);
55
+#define TCG_TARGET_CON_SET_H
25
- int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
56
26
- target_ulong tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
57
#endif
27
+ uintptr_t mmu_idx = get_mmuidx(oi);
58
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
28
+ uintptr_t index = tlb_index(env, mmu_idx, addr);
29
+ CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
30
+ target_ulong tlb_addr = entry->ADDR_READ;
31
unsigned a_bits = get_alignment_bits(get_memop(oi));
32
uintptr_t haddr;
33
DATA_TYPE res;
34
@@ -XXX,XX +XXX,XX @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
35
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, READ_ACCESS_TYPE,
36
mmu_idx, retaddr);
37
}
38
- tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
39
+ tlb_addr = entry->ADDR_READ;
40
}
41
42
/* Handle an IO access. */
43
@@ -XXX,XX +XXX,XX @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
44
return res;
45
}
46
47
- haddr = addr + env->tlb_table[mmu_idx][index].addend;
48
+ haddr = addr + entry->addend;
49
#if DATA_SIZE == 1
50
res = glue(glue(ld, LSUFFIX), _p)((uint8_t *)haddr);
51
#else
52
@@ -XXX,XX +XXX,XX @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
53
WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
54
TCGMemOpIdx oi, uintptr_t retaddr)
55
{
56
- unsigned mmu_idx = get_mmuidx(oi);
57
- int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
58
- target_ulong tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
59
+ uintptr_t mmu_idx = get_mmuidx(oi);
60
+ uintptr_t index = tlb_index(env, mmu_idx, addr);
61
+ CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
62
+ target_ulong tlb_addr = entry->ADDR_READ;
63
unsigned a_bits = get_alignment_bits(get_memop(oi));
64
uintptr_t haddr;
65
DATA_TYPE res;
66
@@ -XXX,XX +XXX,XX @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
67
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, READ_ACCESS_TYPE,
68
mmu_idx, retaddr);
69
}
70
- tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
71
+ tlb_addr = entry->ADDR_READ;
72
}
73
74
/* Handle an IO access. */
75
@@ -XXX,XX +XXX,XX @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
76
return res;
77
}
78
79
- haddr = addr + env->tlb_table[mmu_idx][index].addend;
80
+ haddr = addr + entry->addend;
81
res = glue(glue(ld, LSUFFIX), _be_p)((uint8_t *)haddr);
82
return res;
83
}
84
@@ -XXX,XX +XXX,XX @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
85
void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
86
TCGMemOpIdx oi, uintptr_t retaddr)
87
{
88
- unsigned mmu_idx = get_mmuidx(oi);
89
- int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
90
- target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
91
+ uintptr_t mmu_idx = get_mmuidx(oi);
92
+ uintptr_t index = tlb_index(env, mmu_idx, addr);
93
+ CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
94
+ target_ulong tlb_addr = entry->addr_write;
95
unsigned a_bits = get_alignment_bits(get_memop(oi));
96
uintptr_t haddr;
97
98
@@ -XXX,XX +XXX,XX @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
99
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, MMU_DATA_STORE,
100
mmu_idx, retaddr);
101
}
102
- tlb_addr = env->tlb_table[mmu_idx][index].addr_write & ~TLB_INVALID_MASK;
103
+ tlb_addr = entry->addr_write & ~TLB_INVALID_MASK;
104
}
105
106
/* Handle an IO access. */
107
@@ -XXX,XX +XXX,XX @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
108
if (DATA_SIZE > 1
109
&& unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1
110
>= TARGET_PAGE_SIZE)) {
111
- int i, index2;
112
- target_ulong page2, tlb_addr2;
113
+ int i;
114
+ target_ulong page2;
115
+ CPUTLBEntry *entry2;
116
do_unaligned_access:
117
/* Ensure the second page is in the TLB. Note that the first page
118
is already guaranteed to be filled, and that the second page
119
cannot evict the first. */
120
page2 = (addr + DATA_SIZE) & TARGET_PAGE_MASK;
121
- index2 = (page2 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
122
- tlb_addr2 = env->tlb_table[mmu_idx][index2].addr_write;
123
- if (!tlb_hit_page(tlb_addr2, page2)
124
+ entry2 = tlb_entry(env, mmu_idx, page2);
125
+ if (!tlb_hit_page(entry2->addr_write, page2)
126
&& !VICTIM_TLB_HIT(addr_write, page2)) {
127
tlb_fill(ENV_GET_CPU(env), page2, DATA_SIZE, MMU_DATA_STORE,
128
mmu_idx, retaddr);
129
@@ -XXX,XX +XXX,XX @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
130
return;
131
}
132
133
- haddr = addr + env->tlb_table[mmu_idx][index].addend;
134
+ haddr = addr + entry->addend;
135
#if DATA_SIZE == 1
136
glue(glue(st, SUFFIX), _p)((uint8_t *)haddr, val);
137
#else
138
@@ -XXX,XX +XXX,XX @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
139
void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
140
TCGMemOpIdx oi, uintptr_t retaddr)
141
{
142
- unsigned mmu_idx = get_mmuidx(oi);
143
- int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
144
- target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
145
+ uintptr_t mmu_idx = get_mmuidx(oi);
146
+ uintptr_t index = tlb_index(env, mmu_idx, addr);
147
+ CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
148
+ target_ulong tlb_addr = entry->addr_write;
149
unsigned a_bits = get_alignment_bits(get_memop(oi));
150
uintptr_t haddr;
151
152
@@ -XXX,XX +XXX,XX @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
153
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, MMU_DATA_STORE,
154
mmu_idx, retaddr);
155
}
156
- tlb_addr = env->tlb_table[mmu_idx][index].addr_write & ~TLB_INVALID_MASK;
157
+ tlb_addr = entry->addr_write & ~TLB_INVALID_MASK;
158
}
159
160
/* Handle an IO access. */
161
@@ -XXX,XX +XXX,XX @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
162
if (DATA_SIZE > 1
163
&& unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1
164
>= TARGET_PAGE_SIZE)) {
165
- int i, index2;
166
- target_ulong page2, tlb_addr2;
167
+ int i;
168
+ target_ulong page2;
169
+ CPUTLBEntry *entry2;
170
do_unaligned_access:
171
/* Ensure the second page is in the TLB. Note that the first page
172
is already guaranteed to be filled, and that the second page
173
cannot evict the first. */
174
page2 = (addr + DATA_SIZE) & TARGET_PAGE_MASK;
175
- index2 = (page2 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
176
- tlb_addr2 = env->tlb_table[mmu_idx][index2].addr_write;
177
- if (!tlb_hit_page(tlb_addr2, page2)
178
+ entry2 = tlb_entry(env, mmu_idx, page2);
179
+ if (!tlb_hit_page(entry2->addr_write, page2)
180
&& !VICTIM_TLB_HIT(addr_write, page2)) {
181
tlb_fill(ENV_GET_CPU(env), page2, DATA_SIZE, MMU_DATA_STORE,
182
mmu_idx, retaddr);
183
@@ -XXX,XX +XXX,XX @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
184
return;
185
}
186
187
- haddr = addr + env->tlb_table[mmu_idx][index].addend;
188
+ haddr = addr + entry->addend;
189
glue(glue(st, SUFFIX), _be_p)((uint8_t *)haddr, val);
190
}
191
#endif /* DATA_SIZE > 1 */
192
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
193
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
194
--- a/include/exec/cpu_ldst.h
60
--- a/tcg/riscv/tcg-target.c.inc
195
+++ b/include/exec/cpu_ldst.h
61
+++ b/tcg/riscv/tcg-target.c.inc
196
@@ -XXX,XX +XXX,XX @@ extern __thread uintptr_t helper_retaddr;
62
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
197
/* The memory helpers for tcg-generated code need tcg_target_long etc. */
198
#include "tcg.h"
199
200
+/* Find the TLB index corresponding to the mmu_idx + address pair. */
201
+static inline uintptr_t tlb_index(CPUArchState *env, uintptr_t mmu_idx,
202
+ target_ulong addr)
203
+{
204
+ return (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
205
+}
206
+
207
+/* Find the TLB entry corresponding to the mmu_idx + address pair. */
208
+static inline CPUTLBEntry *tlb_entry(CPUArchState *env, uintptr_t mmu_idx,
209
+ target_ulong addr)
210
+{
211
+ return &env->tlb_table[mmu_idx][tlb_index(env, mmu_idx, addr)];
212
+}
213
+
214
#ifdef MMU_MODE0_SUFFIX
215
#define CPU_MMU_INDEX 0
216
#define MEMSUFFIX MMU_MODE0_SUFFIX
217
@@ -XXX,XX +XXX,XX @@ static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
218
#if defined(CONFIG_USER_ONLY)
219
return g2h(addr);
220
#else
221
- int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
222
- CPUTLBEntry *tlbentry = &env->tlb_table[mmu_idx][index];
223
+ CPUTLBEntry *tlbentry = tlb_entry(env, mmu_idx, addr);
224
abi_ptr tlb_addr;
225
uintptr_t haddr;
226
227
@@ -XXX,XX +XXX,XX @@ static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
228
return NULL;
229
}
230
231
- haddr = addr + env->tlb_table[mmu_idx][index].addend;
232
+ haddr = addr + tlbentry->addend;
233
return (void *)haddr;
234
#endif /* defined(CONFIG_USER_ONLY) */
235
}
236
diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_template.h
237
index XXXXXXX..XXXXXXX 100644
238
--- a/include/exec/cpu_ldst_template.h
239
+++ b/include/exec/cpu_ldst_template.h
240
@@ -XXX,XX +XXX,XX @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
241
target_ulong ptr,
242
uintptr_t retaddr)
243
{
244
- int page_index;
245
+ CPUTLBEntry *entry;
246
RES_TYPE res;
247
target_ulong addr;
248
int mmu_idx;
249
@@ -XXX,XX +XXX,XX @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
250
#endif
251
252
addr = ptr;
253
- page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
254
mmu_idx = CPU_MMU_INDEX;
255
- if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
256
+ entry = tlb_entry(env, mmu_idx, addr);
257
+ if (unlikely(entry->ADDR_READ !=
258
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
259
oi = make_memop_idx(SHIFT, mmu_idx);
260
res = glue(glue(helper_ret_ld, URETSUFFIX), MMUSUFFIX)(env, addr,
261
oi, retaddr);
262
} else {
263
- uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
264
+ uintptr_t hostaddr = addr + entry->addend;
265
res = glue(glue(ld, USUFFIX), _p)((uint8_t *)hostaddr);
266
}
267
return res;
268
@@ -XXX,XX +XXX,XX @@ glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
269
target_ulong ptr,
270
uintptr_t retaddr)
271
{
272
- int res, page_index;
273
+ CPUTLBEntry *entry;
274
+ int res;
275
target_ulong addr;
276
int mmu_idx;
277
TCGMemOpIdx oi;
278
@@ -XXX,XX +XXX,XX @@ glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
279
#endif
280
281
addr = ptr;
282
- page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
283
mmu_idx = CPU_MMU_INDEX;
284
- if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
285
+ entry = tlb_entry(env, mmu_idx, addr);
286
+ if (unlikely(entry->ADDR_READ !=
287
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
288
oi = make_memop_idx(SHIFT, mmu_idx);
289
res = (DATA_STYPE)glue(glue(helper_ret_ld, SRETSUFFIX),
290
MMUSUFFIX)(env, addr, oi, retaddr);
291
} else {
292
- uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
293
+ uintptr_t hostaddr = addr + entry->addend;
294
res = glue(glue(lds, SUFFIX), _p)((uint8_t *)hostaddr);
295
}
296
return res;
297
@@ -XXX,XX +XXX,XX @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
298
target_ulong ptr,
299
RES_TYPE v, uintptr_t retaddr)
300
{
301
- int page_index;
302
+ CPUTLBEntry *entry;
303
target_ulong addr;
304
int mmu_idx;
305
TCGMemOpIdx oi;
306
@@ -XXX,XX +XXX,XX @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
307
#endif
308
309
addr = ptr;
310
- page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
311
mmu_idx = CPU_MMU_INDEX;
312
- if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
313
+ entry = tlb_entry(env, mmu_idx, addr);
314
+ if (unlikely(entry->addr_write !=
315
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
316
oi = make_memop_idx(SHIFT, mmu_idx);
317
glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, v, oi,
318
retaddr);
319
} else {
320
- uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
321
+ uintptr_t hostaddr = addr + entry->addend;
322
glue(glue(st, SUFFIX), _p)((uint8_t *)hostaddr, v);
323
}
63
}
324
}
64
}
325
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
65
326
index XXXXXXX..XXXXXXX 100644
66
-static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
327
--- a/accel/tcg/cputlb.c
67
+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
328
+++ b/accel/tcg/cputlb.c
329
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_page_async_work(CPUState *cpu, run_on_cpu_data data)
330
{
68
{
331
CPUArchState *env = cpu->env_ptr;
69
- static const TCGTargetOpDef r
332
target_ulong addr = (target_ulong) data.target_ptr;
70
- = { .args_ct_str = { "r" } };
333
- int i;
71
- static const TCGTargetOpDef r_r
334
int mmu_idx;
72
- = { .args_ct_str = { "r", "r" } };
335
73
- static const TCGTargetOpDef rZ_r
336
assert_cpu_is_self(cpu);
74
- = { .args_ct_str = { "rZ", "r" } };
337
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_page_async_work(CPUState *cpu, run_on_cpu_data data)
75
- static const TCGTargetOpDef rZ_rZ
76
- = { .args_ct_str = { "rZ", "rZ" } };
77
- static const TCGTargetOpDef rZ_rZ_rZ_rZ
78
- = { .args_ct_str = { "rZ", "rZ", "rZ", "rZ" } };
79
- static const TCGTargetOpDef r_r_ri
80
- = { .args_ct_str = { "r", "r", "ri" } };
81
- static const TCGTargetOpDef r_r_rI
82
- = { .args_ct_str = { "r", "r", "rI" } };
83
- static const TCGTargetOpDef r_rZ_rN
84
- = { .args_ct_str = { "r", "rZ", "rN" } };
85
- static const TCGTargetOpDef r_rZ_rZ
86
- = { .args_ct_str = { "r", "rZ", "rZ" } };
87
- static const TCGTargetOpDef r_rZ_rZ_rZ_rZ
88
- = { .args_ct_str = { "r", "rZ", "rZ", "rZ", "rZ" } };
89
- static const TCGTargetOpDef r_L
90
- = { .args_ct_str = { "r", "L" } };
91
- static const TCGTargetOpDef r_r_L
92
- = { .args_ct_str = { "r", "r", "L" } };
93
- static const TCGTargetOpDef r_L_L
94
- = { .args_ct_str = { "r", "L", "L" } };
95
- static const TCGTargetOpDef r_r_L_L
96
- = { .args_ct_str = { "r", "r", "L", "L" } };
97
- static const TCGTargetOpDef LZ_L
98
- = { .args_ct_str = { "LZ", "L" } };
99
- static const TCGTargetOpDef LZ_L_L
100
- = { .args_ct_str = { "LZ", "L", "L" } };
101
- static const TCGTargetOpDef LZ_LZ_L
102
- = { .args_ct_str = { "LZ", "LZ", "L" } };
103
- static const TCGTargetOpDef LZ_LZ_L_L
104
- = { .args_ct_str = { "LZ", "LZ", "L", "L" } };
105
- static const TCGTargetOpDef r_r_rZ_rZ_rM_rM
106
- = { .args_ct_str = { "r", "r", "rZ", "rZ", "rM", "rM" } };
107
-
108
switch (op) {
109
case INDEX_op_goto_ptr:
110
- return &r;
111
+ return C_O0_I1(r);
112
113
case INDEX_op_ld8u_i32:
114
case INDEX_op_ld8s_i32:
115
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
116
case INDEX_op_extrl_i64_i32:
117
case INDEX_op_extrh_i64_i32:
118
case INDEX_op_ext_i32_i64:
119
- return &r_r;
120
+ return C_O1_I1(r, r);
121
122
case INDEX_op_st8_i32:
123
case INDEX_op_st16_i32:
124
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
125
case INDEX_op_st16_i64:
126
case INDEX_op_st32_i64:
127
case INDEX_op_st_i64:
128
- return &rZ_r;
129
+ return C_O0_I2(rZ, r);
130
131
case INDEX_op_add_i32:
132
case INDEX_op_and_i32:
133
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
134
case INDEX_op_and_i64:
135
case INDEX_op_or_i64:
136
case INDEX_op_xor_i64:
137
- return &r_r_rI;
138
+ return C_O1_I2(r, r, rI);
139
140
case INDEX_op_sub_i32:
141
case INDEX_op_sub_i64:
142
- return &r_rZ_rN;
143
+ return C_O1_I2(r, rZ, rN);
144
145
case INDEX_op_mul_i32:
146
case INDEX_op_mulsh_i32:
147
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
148
case INDEX_op_rem_i64:
149
case INDEX_op_remu_i64:
150
case INDEX_op_setcond_i64:
151
- return &r_rZ_rZ;
152
+ return C_O1_I2(r, rZ, rZ);
153
154
case INDEX_op_shl_i32:
155
case INDEX_op_shr_i32:
156
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
157
case INDEX_op_shl_i64:
158
case INDEX_op_shr_i64:
159
case INDEX_op_sar_i64:
160
- return &r_r_ri;
161
+ return C_O1_I2(r, r, ri);
162
163
case INDEX_op_brcond_i32:
164
case INDEX_op_brcond_i64:
165
- return &rZ_rZ;
166
+ return C_O0_I2(rZ, rZ);
167
168
case INDEX_op_add2_i32:
169
case INDEX_op_add2_i64:
170
case INDEX_op_sub2_i32:
171
case INDEX_op_sub2_i64:
172
- return &r_r_rZ_rZ_rM_rM;
173
+ return C_O2_I4(r, r, rZ, rZ, rM, rM);
174
175
case INDEX_op_brcond2_i32:
176
- return &rZ_rZ_rZ_rZ;
177
+ return C_O0_I4(rZ, rZ, rZ, rZ);
178
179
case INDEX_op_setcond2_i32:
180
- return &r_rZ_rZ_rZ_rZ;
181
+ return C_O1_I4(r, rZ, rZ, rZ, rZ);
182
183
case INDEX_op_qemu_ld_i32:
184
- return TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &r_L : &r_L_L;
185
+ return (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
186
+ ? C_O1_I1(r, L) : C_O1_I2(r, L, L));
187
case INDEX_op_qemu_st_i32:
188
- return TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &LZ_L : &LZ_L_L;
189
+ return (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
190
+ ? C_O0_I2(LZ, L) : C_O0_I3(LZ, L, L));
191
case INDEX_op_qemu_ld_i64:
192
- return TCG_TARGET_REG_BITS == 64 ? &r_L
193
- : TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &r_r_L
194
- : &r_r_L_L;
195
+ return (TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, L)
196
+ : TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? C_O2_I1(r, r, L)
197
+ : C_O2_I2(r, r, L, L));
198
case INDEX_op_qemu_st_i64:
199
- return TCG_TARGET_REG_BITS == 64 ? &LZ_L
200
- : TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &LZ_LZ_L
201
- : &LZ_LZ_L_L;
202
+ return (TCG_TARGET_REG_BITS == 64 ? C_O0_I2(LZ, L)
203
+ : TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? C_O0_I3(LZ, LZ, L)
204
+ : C_O0_I4(LZ, LZ, L, L));
205
206
default:
207
- return NULL;
208
+ g_assert_not_reached();
338
}
209
}
339
340
addr &= TARGET_PAGE_MASK;
341
- i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
342
qemu_spin_lock(&env->tlb_lock);
343
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
344
- tlb_flush_entry_locked(&env->tlb_table[mmu_idx][i], addr);
345
+ tlb_flush_entry_locked(tlb_entry(env, mmu_idx, addr), addr);
346
tlb_flush_vtlb_page_locked(env, mmu_idx, addr);
347
}
348
qemu_spin_unlock(&env->tlb_lock);
349
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_page_by_mmuidx_async_work(CPUState *cpu,
350
target_ulong addr_and_mmuidx = (target_ulong) data.target_ptr;
351
target_ulong addr = addr_and_mmuidx & TARGET_PAGE_MASK;
352
unsigned long mmu_idx_bitmap = addr_and_mmuidx & ALL_MMUIDX_BITS;
353
- int page = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
354
int mmu_idx;
355
356
assert_cpu_is_self(cpu);
357
358
- tlb_debug("page:%d addr:"TARGET_FMT_lx" mmu_idx:0x%lx\n",
359
- page, addr, mmu_idx_bitmap);
360
+ tlb_debug("flush page addr:"TARGET_FMT_lx" mmu_idx:0x%lx\n",
361
+ addr, mmu_idx_bitmap);
362
363
qemu_spin_lock(&env->tlb_lock);
364
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
365
if (test_bit(mmu_idx, &mmu_idx_bitmap)) {
366
- tlb_flush_entry_locked(&env->tlb_table[mmu_idx][page], addr);
367
+ tlb_flush_entry_locked(tlb_entry(env, mmu_idx, addr), addr);
368
tlb_flush_vtlb_page_locked(env, mmu_idx, addr);
369
}
370
}
371
@@ -XXX,XX +XXX,XX @@ static inline void tlb_set_dirty1_locked(CPUTLBEntry *tlb_entry,
372
void tlb_set_dirty(CPUState *cpu, target_ulong vaddr)
373
{
374
CPUArchState *env = cpu->env_ptr;
375
- int i;
376
int mmu_idx;
377
378
assert_cpu_is_self(cpu);
379
380
vaddr &= TARGET_PAGE_MASK;
381
- i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
382
qemu_spin_lock(&env->tlb_lock);
383
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
384
- tlb_set_dirty1_locked(&env->tlb_table[mmu_idx][i], vaddr);
385
+ tlb_set_dirty1_locked(tlb_entry(env, mmu_idx, vaddr), vaddr);
386
}
387
388
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
389
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
390
iotlb = memory_region_section_get_iotlb(cpu, section, vaddr_page,
391
paddr_page, xlat, prot, &address);
392
393
- index = (vaddr_page >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
394
- te = &env->tlb_table[mmu_idx][index];
395
+ index = tlb_index(env, mmu_idx, vaddr_page);
396
+ te = tlb_entry(env, mmu_idx, vaddr_page);
397
398
/*
399
* Hold the TLB lock for the rest of the function. We could acquire/release
400
@@ -XXX,XX +XXX,XX @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
401
* repeat the MMU check here. This tlb_fill() call might
402
* longjump out if this access should cause a guest exception.
403
*/
404
- int index;
405
+ CPUTLBEntry *entry;
406
target_ulong tlb_addr;
407
408
tlb_fill(cpu, addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);
409
410
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
411
- tlb_addr = env->tlb_table[mmu_idx][index].addr_read;
412
+ entry = tlb_entry(env, mmu_idx, addr);
413
+ tlb_addr = entry->addr_read;
414
if (!(tlb_addr & ~(TARGET_PAGE_MASK | TLB_RECHECK))) {
415
/* RAM access */
416
- uintptr_t haddr = addr + env->tlb_table[mmu_idx][index].addend;
417
+ uintptr_t haddr = addr + entry->addend;
418
419
return ldn_p((void *)haddr, size);
420
}
421
@@ -XXX,XX +XXX,XX @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
422
* repeat the MMU check here. This tlb_fill() call might
423
* longjump out if this access should cause a guest exception.
424
*/
425
- int index;
426
+ CPUTLBEntry *entry;
427
target_ulong tlb_addr;
428
429
tlb_fill(cpu, addr, size, MMU_DATA_STORE, mmu_idx, retaddr);
430
431
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
432
- tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
433
+ entry = tlb_entry(env, mmu_idx, addr);
434
+ tlb_addr = entry->addr_write;
435
if (!(tlb_addr & ~(TARGET_PAGE_MASK | TLB_RECHECK))) {
436
/* RAM access */
437
- uintptr_t haddr = addr + env->tlb_table[mmu_idx][index].addend;
438
+ uintptr_t haddr = addr + entry->addend;
439
440
stn_p((void *)haddr, size, val);
441
return;
442
@@ -XXX,XX +XXX,XX @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
443
*/
444
tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
445
{
446
- int mmu_idx, index;
447
+ uintptr_t mmu_idx = cpu_mmu_index(env, true);
448
+ uintptr_t index = tlb_index(env, mmu_idx, addr);
449
+ CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
450
void *p;
451
452
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
453
- mmu_idx = cpu_mmu_index(env, true);
454
- if (unlikely(!tlb_hit(env->tlb_table[mmu_idx][index].addr_code, addr))) {
455
+ if (unlikely(!tlb_hit(entry->addr_code, addr))) {
456
if (!VICTIM_TLB_HIT(addr_code, addr)) {
457
tlb_fill(ENV_GET_CPU(env), addr, 0, MMU_INST_FETCH, mmu_idx, 0);
458
}
459
- assert(tlb_hit(env->tlb_table[mmu_idx][index].addr_code, addr));
460
+ assert(tlb_hit(entry->addr_code, addr));
461
}
462
463
- if (unlikely(env->tlb_table[mmu_idx][index].addr_code &
464
- (TLB_RECHECK | TLB_MMIO))) {
465
+ if (unlikely(entry->addr_code & (TLB_RECHECK | TLB_MMIO))) {
466
/*
467
* Return -1 if we can't translate and execute from an entire
468
* page of RAM here, which will cause us to execute by loading
469
@@ -XXX,XX +XXX,XX @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
470
return -1;
471
}
472
473
- p = (void *)((uintptr_t)addr + env->tlb_table[mmu_idx][index].addend);
474
+ p = (void *)((uintptr_t)addr + entry->addend);
475
return qemu_ram_addr_from_host_nofail(p);
476
}
210
}
477
211
478
@@ -XXX,XX +XXX,XX @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
479
void probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx,
480
uintptr_t retaddr)
481
{
482
- int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
483
- target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
484
+ uintptr_t index = tlb_index(env, mmu_idx, addr);
485
+ CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
486
487
- if (!tlb_hit(tlb_addr, addr)) {
488
+ if (!tlb_hit(entry->addr_write, addr)) {
489
/* TLB entry is for a different page */
490
if (!VICTIM_TLB_HIT(addr_write, addr)) {
491
tlb_fill(ENV_GET_CPU(env), addr, size, MMU_DATA_STORE,
492
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
493
NotDirtyInfo *ndi)
494
{
495
size_t mmu_idx = get_mmuidx(oi);
496
- size_t index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
497
- CPUTLBEntry *tlbe = &env->tlb_table[mmu_idx][index];
498
+ uintptr_t index = tlb_index(env, mmu_idx, addr);
499
+ CPUTLBEntry *tlbe = tlb_entry(env, mmu_idx, addr);
500
target_ulong tlb_addr = tlbe->addr_write;
501
TCGMemOp mop = get_memop(oi);
502
int a_bits = get_alignment_bits(mop);
503
--
212
--
504
2.17.2
213
2.25.1
505
214
506
215
diff view generated by jsdifflib
1
From: "Emilio G. Cota" <cota@braap.org>
1
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2
3
As far as I can tell tlb_flush does not need to be called
4
this early. tlb_flush is eventually called after the CPU
5
has been realized.
6
7
This change paves the way to the introduction of tlb_init,
8
which will be called from cpu_exec_realizefn.
9
10
Cc: Guan Xuetao <gxt@mprc.pku.edu.cn>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Emilio G. Cota <cota@braap.org>
14
Message-Id: <20181009174557.16125-3-cota@braap.org>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
---
3
---
17
target/unicore32/cpu.c | 2 --
4
tcg/s390/tcg-target-con-set.h | 29 ++++++++
18
1 file changed, 2 deletions(-)
5
tcg/s390/tcg-target.h | 1 +
6
tcg/s390/tcg-target.c.inc | 121 ++++++++++++++--------------------
7
3 files changed, 81 insertions(+), 70 deletions(-)
8
create mode 100644 tcg/s390/tcg-target-con-set.h
19
9
20
diff --git a/target/unicore32/cpu.c b/target/unicore32/cpu.c
10
diff --git a/tcg/s390/tcg-target-con-set.h b/tcg/s390/tcg-target-con-set.h
11
new file mode 100644
12
index XXXXXXX..XXXXXXX
13
--- /dev/null
14
+++ b/tcg/s390/tcg-target-con-set.h
15
@@ -XXX,XX +XXX,XX @@
16
+/* SPDX-License-Identifier: MIT */
17
+/*
18
+ * Define S390 target-specific constraint sets.
19
+ * Copyright (c) 2021 Linaro
20
+ */
21
+
22
+/*
23
+ * C_On_Im(...) defines a constraint set with <n> outputs and <m> inputs.
24
+ * Each operand should be a sequence of constraint letters as defined by
25
+ * tcg-target-con-str.h; the constraint combination is inclusive or.
26
+ */
27
+C_O0_I1(r)
28
+C_O0_I2(L, L)
29
+C_O0_I2(r, r)
30
+C_O0_I2(r, ri)
31
+C_O1_I1(r, L)
32
+C_O1_I1(r, r)
33
+C_O1_I2(r, 0, ri)
34
+C_O1_I2(r, 0, rI)
35
+C_O1_I2(r, 0, rJ)
36
+C_O1_I2(r, r, ri)
37
+C_O1_I2(r, rZ, r)
38
+C_O1_I4(r, r, ri, r, 0)
39
+C_O1_I4(r, r, ri, rI, 0)
40
+C_O2_I2(b, a, 0, r)
41
+C_O2_I3(b, a, 0, 1, r)
42
+C_O2_I4(r, r, 0, 1, rA, r)
43
+C_O2_I4(r, r, 0, 1, ri, r)
44
+C_O2_I4(r, r, 0, 1, r, r)
45
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
21
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
22
--- a/target/unicore32/cpu.c
47
--- a/tcg/s390/tcg-target.h
23
+++ b/target/unicore32/cpu.c
48
+++ b/tcg/s390/tcg-target.h
24
@@ -XXX,XX +XXX,XX @@ static void uc32_cpu_initfn(Object *obj)
49
@@ -XXX,XX +XXX,XX @@ static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
25
env->uncached_asr = ASR_MODE_PRIV;
50
#define TCG_TARGET_NEED_LDST_LABELS
26
env->regs[31] = 0x03000000;
27
#endif
51
#endif
28
-
52
#define TCG_TARGET_NEED_POOL_LABELS
29
- tlb_flush(cs);
53
+#define TCG_TARGET_CON_SET_H
54
55
#endif
56
diff --git a/tcg/s390/tcg-target.c.inc b/tcg/s390/tcg-target.c.inc
57
index XXXXXXX..XXXXXXX 100644
58
--- a/tcg/s390/tcg-target.c.inc
59
+++ b/tcg/s390/tcg-target.c.inc
60
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
61
}
30
}
62
}
31
63
32
static const VMStateDescription vmstate_uc32_cpu = {
64
-static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
65
+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
66
{
67
- static const TCGTargetOpDef r = { .args_ct_str = { "r" } };
68
- static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } };
69
- static const TCGTargetOpDef r_L = { .args_ct_str = { "r", "L" } };
70
- static const TCGTargetOpDef L_L = { .args_ct_str = { "L", "L" } };
71
- static const TCGTargetOpDef r_ri = { .args_ct_str = { "r", "ri" } };
72
- static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } };
73
- static const TCGTargetOpDef r_0_ri = { .args_ct_str = { "r", "0", "ri" } };
74
- static const TCGTargetOpDef r_0_rI = { .args_ct_str = { "r", "0", "rI" } };
75
- static const TCGTargetOpDef r_0_rJ = { .args_ct_str = { "r", "0", "rJ" } };
76
- static const TCGTargetOpDef a2_r
77
- = { .args_ct_str = { "r", "r", "0", "1", "r", "r" } };
78
- static const TCGTargetOpDef a2_ri
79
- = { .args_ct_str = { "r", "r", "0", "1", "ri", "r" } };
80
- static const TCGTargetOpDef a2_rA
81
- = { .args_ct_str = { "r", "r", "0", "1", "rA", "r" } };
82
-
83
switch (op) {
84
case INDEX_op_goto_ptr:
85
- return &r;
86
+ return C_O0_I1(r);
87
88
case INDEX_op_ld8u_i32:
89
case INDEX_op_ld8u_i64:
90
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
91
case INDEX_op_ld32u_i64:
92
case INDEX_op_ld32s_i64:
93
case INDEX_op_ld_i64:
94
+ return C_O1_I1(r, r);
95
+
96
case INDEX_op_st8_i32:
97
case INDEX_op_st8_i64:
98
case INDEX_op_st16_i32:
99
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
100
case INDEX_op_st_i32:
101
case INDEX_op_st32_i64:
102
case INDEX_op_st_i64:
103
- return &r_r;
104
+ return C_O0_I2(r, r);
105
106
case INDEX_op_add_i32:
107
case INDEX_op_add_i64:
108
- return &r_r_ri;
109
+ case INDEX_op_shl_i64:
110
+ case INDEX_op_shr_i64:
111
+ case INDEX_op_sar_i64:
112
+ case INDEX_op_rotl_i32:
113
+ case INDEX_op_rotl_i64:
114
+ case INDEX_op_rotr_i32:
115
+ case INDEX_op_rotr_i64:
116
+ case INDEX_op_clz_i64:
117
+ case INDEX_op_setcond_i32:
118
+ case INDEX_op_setcond_i64:
119
+ return C_O1_I2(r, r, ri);
120
+
121
case INDEX_op_sub_i32:
122
case INDEX_op_sub_i64:
123
case INDEX_op_and_i32:
124
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
125
case INDEX_op_or_i64:
126
case INDEX_op_xor_i32:
127
case INDEX_op_xor_i64:
128
- return (s390_facilities & FACILITY_DISTINCT_OPS ? &r_r_ri : &r_0_ri);
129
+ return (s390_facilities & FACILITY_DISTINCT_OPS
130
+ ? C_O1_I2(r, r, ri)
131
+ : C_O1_I2(r, 0, ri));
132
133
case INDEX_op_mul_i32:
134
/* If we have the general-instruction-extensions, then we have
135
MULTIPLY SINGLE IMMEDIATE with a signed 32-bit, otherwise we
136
have only MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit. */
137
- return (s390_facilities & FACILITY_GEN_INST_EXT ? &r_0_ri : &r_0_rI);
138
+ return (s390_facilities & FACILITY_GEN_INST_EXT
139
+ ? C_O1_I2(r, 0, ri)
140
+ : C_O1_I2(r, 0, rI));
141
+
142
case INDEX_op_mul_i64:
143
- return (s390_facilities & FACILITY_GEN_INST_EXT ? &r_0_rJ : &r_0_rI);
144
+ return (s390_facilities & FACILITY_GEN_INST_EXT
145
+ ? C_O1_I2(r, 0, rJ)
146
+ : C_O1_I2(r, 0, rI));
147
148
case INDEX_op_shl_i32:
149
case INDEX_op_shr_i32:
150
case INDEX_op_sar_i32:
151
- return (s390_facilities & FACILITY_DISTINCT_OPS ? &r_r_ri : &r_0_ri);
152
-
153
- case INDEX_op_shl_i64:
154
- case INDEX_op_shr_i64:
155
- case INDEX_op_sar_i64:
156
- return &r_r_ri;
157
-
158
- case INDEX_op_rotl_i32:
159
- case INDEX_op_rotl_i64:
160
- case INDEX_op_rotr_i32:
161
- case INDEX_op_rotr_i64:
162
- return &r_r_ri;
163
+ return (s390_facilities & FACILITY_DISTINCT_OPS
164
+ ? C_O1_I2(r, r, ri)
165
+ : C_O1_I2(r, 0, ri));
166
167
case INDEX_op_brcond_i32:
168
case INDEX_op_brcond_i64:
169
- return &r_ri;
170
+ return C_O0_I2(r, ri);
171
172
case INDEX_op_bswap16_i32:
173
case INDEX_op_bswap16_i64:
174
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
175
case INDEX_op_extu_i32_i64:
176
case INDEX_op_extract_i32:
177
case INDEX_op_extract_i64:
178
- return &r_r;
179
-
180
- case INDEX_op_clz_i64:
181
- case INDEX_op_setcond_i32:
182
- case INDEX_op_setcond_i64:
183
- return &r_r_ri;
184
+ return C_O1_I1(r, r);
185
186
case INDEX_op_qemu_ld_i32:
187
case INDEX_op_qemu_ld_i64:
188
- return &r_L;
189
+ return C_O1_I1(r, L);
190
case INDEX_op_qemu_st_i64:
191
case INDEX_op_qemu_st_i32:
192
- return &L_L;
193
+ return C_O0_I2(L, L);
194
195
case INDEX_op_deposit_i32:
196
case INDEX_op_deposit_i64:
197
- {
198
- static const TCGTargetOpDef dep
199
- = { .args_ct_str = { "r", "rZ", "r" } };
200
- return &dep;
201
- }
202
+ return C_O1_I2(r, rZ, r);
203
+
204
case INDEX_op_movcond_i32:
205
case INDEX_op_movcond_i64:
206
- {
207
- static const TCGTargetOpDef movc
208
- = { .args_ct_str = { "r", "r", "ri", "r", "0" } };
209
- static const TCGTargetOpDef movc_l
210
- = { .args_ct_str = { "r", "r", "ri", "rI", "0" } };
211
- return (s390_facilities & FACILITY_LOAD_ON_COND2 ? &movc_l : &movc);
212
- }
213
+ return (s390_facilities & FACILITY_LOAD_ON_COND2
214
+ ? C_O1_I4(r, r, ri, rI, 0)
215
+ : C_O1_I4(r, r, ri, r, 0));
216
+
217
case INDEX_op_div2_i32:
218
case INDEX_op_div2_i64:
219
case INDEX_op_divu2_i32:
220
case INDEX_op_divu2_i64:
221
- {
222
- static const TCGTargetOpDef div2
223
- = { .args_ct_str = { "b", "a", "0", "1", "r" } };
224
- return &div2;
225
- }
226
+ return C_O2_I3(b, a, 0, 1, r);
227
+
228
case INDEX_op_mulu2_i64:
229
- {
230
- static const TCGTargetOpDef mul2
231
- = { .args_ct_str = { "b", "a", "0", "r" } };
232
- return &mul2;
233
- }
234
+ return C_O2_I2(b, a, 0, r);
235
236
case INDEX_op_add2_i32:
237
case INDEX_op_sub2_i32:
238
- return (s390_facilities & FACILITY_EXT_IMM ? &a2_ri : &a2_r);
239
+ return (s390_facilities & FACILITY_EXT_IMM
240
+ ? C_O2_I4(r, r, 0, 1, ri, r)
241
+ : C_O2_I4(r, r, 0, 1, r, r));
242
+
243
case INDEX_op_add2_i64:
244
case INDEX_op_sub2_i64:
245
- return (s390_facilities & FACILITY_EXT_IMM ? &a2_rA : &a2_r);
246
+ return (s390_facilities & FACILITY_EXT_IMM
247
+ ? C_O2_I4(r, r, 0, 1, rA, r)
248
+ : C_O2_I4(r, r, 0, 1, r, r));
249
250
default:
251
- break;
252
+ g_assert_not_reached();
253
}
254
- return NULL;
255
}
256
257
static void query_s390_facilities(void)
33
--
258
--
34
2.17.2
259
2.25.1
35
260
36
261
diff view generated by jsdifflib
1
From: "Emilio G. Cota" <cota@braap.org>
1
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2
3
Currently we rely on atomic operations for cross-CPU invalidations.
4
There are two cases that these atomics miss: cross-CPU invalidations
5
can race with either (1) vCPU threads flushing their TLB, which
6
happens via memset, or (2) vCPUs calling tlb_reset_dirty on their TLB,
7
which updates .addr_write with a regular store. This results in
8
undefined behaviour, since we're mixing regular and atomic ops
9
on concurrent accesses.
10
11
Fix it by using tlb_lock, a per-vCPU lock. All updaters of tlb_table
12
and the corresponding victim cache now hold the lock.
13
The readers that do not hold tlb_lock must use atomic reads when
14
reading .addr_write, since this field can be updated by other threads;
15
the conversion to atomic reads is done in the next patch.
16
17
Note that an alternative fix would be to expand the use of atomic ops.
18
However, in the case of TLB flushes this would have a huge performance
19
impact, since (1) TLB flushes can happen very frequently and (2) we
20
currently use a full memory barrier to flush each TLB entry, and a TLB
21
has many entries. Instead, acquiring the lock is barely slower than a
22
full memory barrier since it is uncontended, and with a single lock
23
acquisition we can flush the entire TLB.
24
25
Tested-by: Alex Bennée <alex.bennee@linaro.org>
26
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
27
Signed-off-by: Emilio G. Cota <cota@braap.org>
28
Message-Id: <20181009174557.16125-6-cota@braap.org>
29
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
30
---
3
---
31
include/exec/cpu-defs.h | 3 +
4
tcg/sparc/tcg-target-con-set.h | 32 +++++++++++++++
32
accel/tcg/cputlb.c | 155 ++++++++++++++++++++++------------------
5
tcg/sparc/tcg-target.h | 1 +
33
2 files changed, 87 insertions(+), 71 deletions(-)
6
tcg/sparc/tcg-target.c.inc | 75 +++++++++++-----------------------
7
3 files changed, 56 insertions(+), 52 deletions(-)
8
create mode 100644 tcg/sparc/tcg-target-con-set.h
34
9
35
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
10
diff --git a/tcg/sparc/tcg-target-con-set.h b/tcg/sparc/tcg-target-con-set.h
11
new file mode 100644
12
index XXXXXXX..XXXXXXX
13
--- /dev/null
14
+++ b/tcg/sparc/tcg-target-con-set.h
15
@@ -XXX,XX +XXX,XX @@
16
+/* SPDX-License-Identifier: MIT */
17
+/*
18
+ * Define Sparc target-specific constraint sets.
19
+ * Copyright (c) 2021 Linaro
20
+ */
21
+
22
+/*
23
+ * C_On_Im(...) defines a constraint set with <n> outputs and <m> inputs.
24
+ * Each operand should be a sequence of constraint letters as defined by
25
+ * tcg-target-con-str.h; the constraint combination is inclusive or.
26
+ */
27
+C_O0_I1(r)
28
+C_O0_I2(rZ, r)
29
+C_O0_I2(RZ, r)
30
+C_O0_I2(rZ, rJ)
31
+C_O0_I2(RZ, RJ)
32
+C_O0_I2(sZ, A)
33
+C_O0_I2(SZ, A)
34
+C_O1_I1(r, A)
35
+C_O1_I1(R, A)
36
+C_O1_I1(r, r)
37
+C_O1_I1(r, R)
38
+C_O1_I1(R, r)
39
+C_O1_I1(R, R)
40
+C_O1_I2(R, R, R)
41
+C_O1_I2(r, rZ, rJ)
42
+C_O1_I2(R, RZ, RJ)
43
+C_O1_I4(r, rZ, rJ, rI, 0)
44
+C_O1_I4(R, RZ, RJ, RI, 0)
45
+C_O2_I2(r, r, rZ, rJ)
46
+C_O2_I4(R, R, RZ, RZ, RJ, RI)
47
+C_O2_I4(r, r, rZ, rZ, rJ, rJ)
48
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
36
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
37
--- a/include/exec/cpu-defs.h
50
--- a/tcg/sparc/tcg-target.h
38
+++ b/include/exec/cpu-defs.h
51
+++ b/tcg/sparc/tcg-target.h
39
@@ -XXX,XX +XXX,XX @@
52
@@ -XXX,XX +XXX,XX @@ extern bool use_vis3_instructions;
53
void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
54
55
#define TCG_TARGET_NEED_POOL_LABELS
56
+#define TCG_TARGET_CON_SET_H
57
40
#endif
58
#endif
41
59
diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc/tcg-target.c.inc
42
#include "qemu/host-utils.h"
43
+#include "qemu/thread.h"
44
#include "qemu/queue.h"
45
#ifdef CONFIG_TCG
46
#include "tcg-target.h"
47
@@ -XXX,XX +XXX,XX @@ typedef struct CPUIOTLBEntry {
48
49
#define CPU_COMMON_TLB \
50
/* The meaning of the MMU modes is defined in the target code. */ \
51
+ /* tlb_lock serializes updates to tlb_table and tlb_v_table */ \
52
+ QemuSpin tlb_lock; \
53
CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE]; \
54
CPUTLBEntry tlb_v_table[NB_MMU_MODES][CPU_VTLB_SIZE]; \
55
CPUIOTLBEntry iotlb[NB_MMU_MODES][CPU_TLB_SIZE]; \
56
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
57
index XXXXXXX..XXXXXXX 100644
60
index XXXXXXX..XXXXXXX 100644
58
--- a/accel/tcg/cputlb.c
61
--- a/tcg/sparc/tcg-target.c.inc
59
+++ b/accel/tcg/cputlb.c
62
+++ b/tcg/sparc/tcg-target.c.inc
60
@@ -XXX,XX +XXX,XX @@ QEMU_BUILD_BUG_ON(NB_MMU_MODES > 16);
63
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
61
62
void tlb_init(CPUState *cpu)
63
{
64
+ CPUArchState *env = cpu->env_ptr;
65
+
66
+ qemu_spin_init(&env->tlb_lock);
67
}
68
69
/* flush_all_helper: run fn across all cpus
70
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_nocheck(CPUState *cpu)
71
atomic_set(&env->tlb_flush_count, env->tlb_flush_count + 1);
72
tlb_debug("(count: %zu)\n", tlb_flush_count());
73
74
+ /*
75
+ * tlb_table/tlb_v_table updates from any thread must hold tlb_lock.
76
+ * However, updates from the owner thread (as is the case here; see the
77
+ * above assert_cpu_is_self) do not need atomic_set because all reads
78
+ * that do not hold the lock are performed by the same owner thread.
79
+ */
80
+ qemu_spin_lock(&env->tlb_lock);
81
memset(env->tlb_table, -1, sizeof(env->tlb_table));
82
memset(env->tlb_v_table, -1, sizeof(env->tlb_v_table));
83
+ qemu_spin_unlock(&env->tlb_lock);
84
+
85
cpu_tb_jmp_cache_clear(cpu);
86
87
env->vtlb_index = 0;
88
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_by_mmuidx_async_work(CPUState *cpu, run_on_cpu_data data)
89
90
tlb_debug("start: mmu_idx:0x%04lx\n", mmu_idx_bitmask);
91
92
+ qemu_spin_lock(&env->tlb_lock);
93
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
94
95
if (test_bit(mmu_idx, &mmu_idx_bitmask)) {
96
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_by_mmuidx_async_work(CPUState *cpu, run_on_cpu_data data)
97
memset(env->tlb_v_table[mmu_idx], -1, sizeof(env->tlb_v_table[0]));
98
}
99
}
100
+ qemu_spin_unlock(&env->tlb_lock);
101
102
cpu_tb_jmp_cache_clear(cpu);
103
104
@@ -XXX,XX +XXX,XX @@ static inline bool tlb_hit_page_anyprot(CPUTLBEntry *tlb_entry,
105
tlb_hit_page(tlb_entry->addr_code, page);
106
}
107
108
-static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong page)
109
+/* Called with tlb_lock held */
110
+static inline void tlb_flush_entry_locked(CPUTLBEntry *tlb_entry,
111
+ target_ulong page)
112
{
113
if (tlb_hit_page_anyprot(tlb_entry, page)) {
114
memset(tlb_entry, -1, sizeof(*tlb_entry));
115
}
64
}
116
}
65
}
117
66
118
-static inline void tlb_flush_vtlb_page(CPUArchState *env, int mmu_idx,
67
-static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
119
- target_ulong page)
68
+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
120
+/* Called with tlb_lock held */
121
+static inline void tlb_flush_vtlb_page_locked(CPUArchState *env, int mmu_idx,
122
+ target_ulong page)
123
{
69
{
124
int k;
70
- static const TCGTargetOpDef r = { .args_ct_str = { "r" } };
125
+
71
- static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } };
126
+ assert_cpu_is_self(ENV_GET_CPU(env));
72
- static const TCGTargetOpDef R_r = { .args_ct_str = { "R", "r" } };
127
for (k = 0; k < CPU_VTLB_SIZE; k++) {
73
- static const TCGTargetOpDef r_R = { .args_ct_str = { "r", "R" } };
128
- tlb_flush_entry(&env->tlb_v_table[mmu_idx][k], page);
74
- static const TCGTargetOpDef R_R = { .args_ct_str = { "R", "R" } };
129
+ tlb_flush_entry_locked(&env->tlb_v_table[mmu_idx][k], page);
75
- static const TCGTargetOpDef r_A = { .args_ct_str = { "r", "A" } };
76
- static const TCGTargetOpDef R_A = { .args_ct_str = { "R", "A" } };
77
- static const TCGTargetOpDef rZ_r = { .args_ct_str = { "rZ", "r" } };
78
- static const TCGTargetOpDef RZ_r = { .args_ct_str = { "RZ", "r" } };
79
- static const TCGTargetOpDef sZ_A = { .args_ct_str = { "sZ", "A" } };
80
- static const TCGTargetOpDef SZ_A = { .args_ct_str = { "SZ", "A" } };
81
- static const TCGTargetOpDef rZ_rJ = { .args_ct_str = { "rZ", "rJ" } };
82
- static const TCGTargetOpDef RZ_RJ = { .args_ct_str = { "RZ", "RJ" } };
83
- static const TCGTargetOpDef R_R_R = { .args_ct_str = { "R", "R", "R" } };
84
- static const TCGTargetOpDef r_rZ_rJ
85
- = { .args_ct_str = { "r", "rZ", "rJ" } };
86
- static const TCGTargetOpDef R_RZ_RJ
87
- = { .args_ct_str = { "R", "RZ", "RJ" } };
88
- static const TCGTargetOpDef r_r_rZ_rJ
89
- = { .args_ct_str = { "r", "r", "rZ", "rJ" } };
90
- static const TCGTargetOpDef movc_32
91
- = { .args_ct_str = { "r", "rZ", "rJ", "rI", "0" } };
92
- static const TCGTargetOpDef movc_64
93
- = { .args_ct_str = { "R", "RZ", "RJ", "RI", "0" } };
94
- static const TCGTargetOpDef add2_32
95
- = { .args_ct_str = { "r", "r", "rZ", "rZ", "rJ", "rJ" } };
96
- static const TCGTargetOpDef add2_64
97
- = { .args_ct_str = { "R", "R", "RZ", "RZ", "RJ", "RI" } };
98
-
99
switch (op) {
100
case INDEX_op_goto_ptr:
101
- return &r;
102
+ return C_O0_I1(r);
103
104
case INDEX_op_ld8u_i32:
105
case INDEX_op_ld8s_i32:
106
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
107
case INDEX_op_ld_i32:
108
case INDEX_op_neg_i32:
109
case INDEX_op_not_i32:
110
- return &r_r;
111
+ return C_O1_I1(r, r);
112
113
case INDEX_op_st8_i32:
114
case INDEX_op_st16_i32:
115
case INDEX_op_st_i32:
116
- return &rZ_r;
117
+ return C_O0_I2(rZ, r);
118
119
case INDEX_op_add_i32:
120
case INDEX_op_mul_i32:
121
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
122
case INDEX_op_shr_i32:
123
case INDEX_op_sar_i32:
124
case INDEX_op_setcond_i32:
125
- return &r_rZ_rJ;
126
+ return C_O1_I2(r, rZ, rJ);
127
128
case INDEX_op_brcond_i32:
129
- return &rZ_rJ;
130
+ return C_O0_I2(rZ, rJ);
131
case INDEX_op_movcond_i32:
132
- return &movc_32;
133
+ return C_O1_I4(r, rZ, rJ, rI, 0);
134
case INDEX_op_add2_i32:
135
case INDEX_op_sub2_i32:
136
- return &add2_32;
137
+ return C_O2_I4(r, r, rZ, rZ, rJ, rJ);
138
case INDEX_op_mulu2_i32:
139
case INDEX_op_muls2_i32:
140
- return &r_r_rZ_rJ;
141
+ return C_O2_I2(r, r, rZ, rJ);
142
143
case INDEX_op_ld8u_i64:
144
case INDEX_op_ld8s_i64:
145
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
146
case INDEX_op_ld_i64:
147
case INDEX_op_ext_i32_i64:
148
case INDEX_op_extu_i32_i64:
149
- return &R_r;
150
+ return C_O1_I1(R, r);
151
152
case INDEX_op_st8_i64:
153
case INDEX_op_st16_i64:
154
case INDEX_op_st32_i64:
155
case INDEX_op_st_i64:
156
- return &RZ_r;
157
+ return C_O0_I2(RZ, r);
158
159
case INDEX_op_add_i64:
160
case INDEX_op_mul_i64:
161
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
162
case INDEX_op_shr_i64:
163
case INDEX_op_sar_i64:
164
case INDEX_op_setcond_i64:
165
- return &R_RZ_RJ;
166
+ return C_O1_I2(R, RZ, RJ);
167
168
case INDEX_op_neg_i64:
169
case INDEX_op_not_i64:
170
case INDEX_op_ext32s_i64:
171
case INDEX_op_ext32u_i64:
172
- return &R_R;
173
+ return C_O1_I1(R, R);
174
175
case INDEX_op_extrl_i64_i32:
176
case INDEX_op_extrh_i64_i32:
177
- return &r_R;
178
+ return C_O1_I1(r, R);
179
180
case INDEX_op_brcond_i64:
181
- return &RZ_RJ;
182
+ return C_O0_I2(RZ, RJ);
183
case INDEX_op_movcond_i64:
184
- return &movc_64;
185
+ return C_O1_I4(R, RZ, RJ, RI, 0);
186
case INDEX_op_add2_i64:
187
case INDEX_op_sub2_i64:
188
- return &add2_64;
189
+ return C_O2_I4(R, R, RZ, RZ, RJ, RI);
190
case INDEX_op_muluh_i64:
191
- return &R_R_R;
192
+ return C_O1_I2(R, R, R);
193
194
case INDEX_op_qemu_ld_i32:
195
- return &r_A;
196
+ return C_O1_I1(r, A);
197
case INDEX_op_qemu_ld_i64:
198
- return &R_A;
199
+ return C_O1_I1(R, A);
200
case INDEX_op_qemu_st_i32:
201
- return &sZ_A;
202
+ return C_O0_I2(sZ, A);
203
case INDEX_op_qemu_st_i64:
204
- return &SZ_A;
205
+ return C_O0_I2(SZ, A);
206
207
default:
208
- return NULL;
209
+ g_assert_not_reached();
130
}
210
}
131
}
211
}
132
212
133
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_page_async_work(CPUState *cpu, run_on_cpu_data data)
134
135
addr &= TARGET_PAGE_MASK;
136
i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
137
+ qemu_spin_lock(&env->tlb_lock);
138
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
139
- tlb_flush_entry(&env->tlb_table[mmu_idx][i], addr);
140
- tlb_flush_vtlb_page(env, mmu_idx, addr);
141
+ tlb_flush_entry_locked(&env->tlb_table[mmu_idx][i], addr);
142
+ tlb_flush_vtlb_page_locked(env, mmu_idx, addr);
143
}
144
+ qemu_spin_unlock(&env->tlb_lock);
145
146
tb_flush_jmp_cache(cpu, addr);
147
}
148
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_page_by_mmuidx_async_work(CPUState *cpu,
149
tlb_debug("page:%d addr:"TARGET_FMT_lx" mmu_idx:0x%lx\n",
150
page, addr, mmu_idx_bitmap);
151
152
+ qemu_spin_lock(&env->tlb_lock);
153
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
154
if (test_bit(mmu_idx, &mmu_idx_bitmap)) {
155
- tlb_flush_entry(&env->tlb_table[mmu_idx][page], addr);
156
- tlb_flush_vtlb_page(env, mmu_idx, addr);
157
+ tlb_flush_entry_locked(&env->tlb_table[mmu_idx][page], addr);
158
+ tlb_flush_vtlb_page_locked(env, mmu_idx, addr);
159
}
160
}
161
+ qemu_spin_unlock(&env->tlb_lock);
162
163
tb_flush_jmp_cache(cpu, addr);
164
}
165
@@ -XXX,XX +XXX,XX @@ void tlb_unprotect_code(ram_addr_t ram_addr)
166
* most usual is detecting writes to code regions which may invalidate
167
* generated code.
168
*
169
- * Because we want other vCPUs to respond to changes straight away we
170
- * update the te->addr_write field atomically. If the TLB entry has
171
- * been changed by the vCPU in the mean time we skip the update.
172
+ * Other vCPUs might be reading their TLBs during guest execution, so we update
173
+ * te->addr_write with atomic_set. We don't need to worry about this for
174
+ * oversized guests as MTTCG is disabled for them.
175
*
176
- * As this function uses atomic accesses we also need to ensure
177
- * updates to tlb_entries follow the same access rules. We don't need
178
- * to worry about this for oversized guests as MTTCG is disabled for
179
- * them.
180
+ * Called with tlb_lock held.
181
*/
182
-
183
-static void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, uintptr_t start,
184
- uintptr_t length)
185
+static void tlb_reset_dirty_range_locked(CPUTLBEntry *tlb_entry,
186
+ uintptr_t start, uintptr_t length)
187
{
188
-#if TCG_OVERSIZED_GUEST
189
uintptr_t addr = tlb_entry->addr_write;
190
191
if ((addr & (TLB_INVALID_MASK | TLB_MMIO | TLB_NOTDIRTY)) == 0) {
192
addr &= TARGET_PAGE_MASK;
193
addr += tlb_entry->addend;
194
if ((addr - start) < length) {
195
+#if TCG_OVERSIZED_GUEST
196
tlb_entry->addr_write |= TLB_NOTDIRTY;
197
- }
198
- }
199
#else
200
- /* paired with atomic_mb_set in tlb_set_page_with_attrs */
201
- uintptr_t orig_addr = atomic_mb_read(&tlb_entry->addr_write);
202
- uintptr_t addr = orig_addr;
203
-
204
- if ((addr & (TLB_INVALID_MASK | TLB_MMIO | TLB_NOTDIRTY)) == 0) {
205
- addr &= TARGET_PAGE_MASK;
206
- addr += atomic_read(&tlb_entry->addend);
207
- if ((addr - start) < length) {
208
- uintptr_t notdirty_addr = orig_addr | TLB_NOTDIRTY;
209
- atomic_cmpxchg(&tlb_entry->addr_write, orig_addr, notdirty_addr);
210
+ atomic_set(&tlb_entry->addr_write,
211
+ tlb_entry->addr_write | TLB_NOTDIRTY);
212
+#endif
213
}
214
}
215
-#endif
216
}
217
218
-/* For atomic correctness when running MTTCG we need to use the right
219
- * primitives when copying entries */
220
-static inline void copy_tlb_helper(CPUTLBEntry *d, CPUTLBEntry *s,
221
- bool atomic_set)
222
+/*
223
+ * Called with tlb_lock held.
224
+ * Called only from the vCPU context, i.e. the TLB's owner thread.
225
+ */
226
+static inline void copy_tlb_helper_locked(CPUTLBEntry *d, const CPUTLBEntry *s)
227
{
228
-#if TCG_OVERSIZED_GUEST
229
*d = *s;
230
-#else
231
- if (atomic_set) {
232
- d->addr_read = s->addr_read;
233
- d->addr_code = s->addr_code;
234
- atomic_set(&d->addend, atomic_read(&s->addend));
235
- /* Pairs with flag setting in tlb_reset_dirty_range */
236
- atomic_mb_set(&d->addr_write, atomic_read(&s->addr_write));
237
- } else {
238
- d->addr_read = s->addr_read;
239
- d->addr_write = atomic_read(&s->addr_write);
240
- d->addr_code = s->addr_code;
241
- d->addend = atomic_read(&s->addend);
242
- }
243
-#endif
244
}
245
246
/* This is a cross vCPU call (i.e. another vCPU resetting the flags of
247
- * the target vCPU). As such care needs to be taken that we don't
248
- * dangerously race with another vCPU update. The only thing actually
249
- * updated is the target TLB entry ->addr_write flags.
250
+ * the target vCPU).
251
+ * We must take tlb_lock to avoid racing with another vCPU update. The only
252
+ * thing actually updated is the target TLB entry ->addr_write flags.
253
*/
254
void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length)
255
{
256
@@ -XXX,XX +XXX,XX @@ void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length)
257
int mmu_idx;
258
259
env = cpu->env_ptr;
260
+ qemu_spin_lock(&env->tlb_lock);
261
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
262
unsigned int i;
263
264
for (i = 0; i < CPU_TLB_SIZE; i++) {
265
- tlb_reset_dirty_range(&env->tlb_table[mmu_idx][i],
266
- start1, length);
267
+ tlb_reset_dirty_range_locked(&env->tlb_table[mmu_idx][i], start1,
268
+ length);
269
}
270
271
for (i = 0; i < CPU_VTLB_SIZE; i++) {
272
- tlb_reset_dirty_range(&env->tlb_v_table[mmu_idx][i],
273
- start1, length);
274
+ tlb_reset_dirty_range_locked(&env->tlb_v_table[mmu_idx][i], start1,
275
+ length);
276
}
277
}
278
+ qemu_spin_unlock(&env->tlb_lock);
279
}
280
281
-static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry, target_ulong vaddr)
282
+/* Called with tlb_lock held */
283
+static inline void tlb_set_dirty1_locked(CPUTLBEntry *tlb_entry,
284
+ target_ulong vaddr)
285
{
286
if (tlb_entry->addr_write == (vaddr | TLB_NOTDIRTY)) {
287
tlb_entry->addr_write = vaddr;
288
@@ -XXX,XX +XXX,XX @@ void tlb_set_dirty(CPUState *cpu, target_ulong vaddr)
289
290
vaddr &= TARGET_PAGE_MASK;
291
i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
292
+ qemu_spin_lock(&env->tlb_lock);
293
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
294
- tlb_set_dirty1(&env->tlb_table[mmu_idx][i], vaddr);
295
+ tlb_set_dirty1_locked(&env->tlb_table[mmu_idx][i], vaddr);
296
}
297
298
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
299
int k;
300
for (k = 0; k < CPU_VTLB_SIZE; k++) {
301
- tlb_set_dirty1(&env->tlb_v_table[mmu_idx][k], vaddr);
302
+ tlb_set_dirty1_locked(&env->tlb_v_table[mmu_idx][k], vaddr);
303
}
304
}
305
+ qemu_spin_unlock(&env->tlb_lock);
306
}
307
308
/* Our TLB does not support large pages, so remember the area covered by
309
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
310
addend = (uintptr_t)memory_region_get_ram_ptr(section->mr) + xlat;
311
}
312
313
- /* Make sure there's no cached translation for the new page. */
314
- tlb_flush_vtlb_page(env, mmu_idx, vaddr_page);
315
-
316
code_address = address;
317
iotlb = memory_region_section_get_iotlb(cpu, section, vaddr_page,
318
paddr_page, xlat, prot, &address);
319
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
320
index = (vaddr_page >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
321
te = &env->tlb_table[mmu_idx][index];
322
323
+ /*
324
+ * Hold the TLB lock for the rest of the function. We could acquire/release
325
+ * the lock several times in the function, but it is faster to amortize the
326
+ * acquisition cost by acquiring it just once. Note that this leads to
327
+ * a longer critical section, but this is not a concern since the TLB lock
328
+ * is unlikely to be contended.
329
+ */
330
+ qemu_spin_lock(&env->tlb_lock);
331
+
332
+ /* Make sure there's no cached translation for the new page. */
333
+ tlb_flush_vtlb_page_locked(env, mmu_idx, vaddr_page);
334
+
335
/*
336
* Only evict the old entry to the victim tlb if it's for a
337
* different page; otherwise just overwrite the stale data.
338
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
339
CPUTLBEntry *tv = &env->tlb_v_table[mmu_idx][vidx];
340
341
/* Evict the old entry into the victim tlb. */
342
- copy_tlb_helper(tv, te, true);
343
+ copy_tlb_helper_locked(tv, te);
344
env->iotlb_v[mmu_idx][vidx] = env->iotlb[mmu_idx][index];
345
}
346
347
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
348
}
349
}
350
351
- /* Pairs with flag setting in tlb_reset_dirty_range */
352
- copy_tlb_helper(te, &tn, true);
353
- /* atomic_mb_set(&te->addr_write, write_address); */
354
+ copy_tlb_helper_locked(te, &tn);
355
+ qemu_spin_unlock(&env->tlb_lock);
356
}
357
358
/* Add a new TLB entry, but without specifying the memory
359
@@ -XXX,XX +XXX,XX @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
360
size_t elt_ofs, target_ulong page)
361
{
362
size_t vidx;
363
+
364
+ assert_cpu_is_self(ENV_GET_CPU(env));
365
for (vidx = 0; vidx < CPU_VTLB_SIZE; ++vidx) {
366
CPUTLBEntry *vtlb = &env->tlb_v_table[mmu_idx][vidx];
367
target_ulong cmp = *(target_ulong *)((uintptr_t)vtlb + elt_ofs);
368
@@ -XXX,XX +XXX,XX @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
369
/* Found entry in victim tlb, swap tlb and iotlb. */
370
CPUTLBEntry tmptlb, *tlb = &env->tlb_table[mmu_idx][index];
371
372
- copy_tlb_helper(&tmptlb, tlb, false);
373
- copy_tlb_helper(tlb, vtlb, true);
374
- copy_tlb_helper(vtlb, &tmptlb, true);
375
+ qemu_spin_lock(&env->tlb_lock);
376
+ copy_tlb_helper_locked(&tmptlb, tlb);
377
+ copy_tlb_helper_locked(tlb, vtlb);
378
+ copy_tlb_helper_locked(vtlb, &tmptlb);
379
+ qemu_spin_unlock(&env->tlb_lock);
380
381
CPUIOTLBEntry tmpio, *io = &env->iotlb[mmu_idx][index];
382
CPUIOTLBEntry *vio = &env->iotlb_v[mmu_idx][vidx];
383
--
213
--
384
2.17.2
214
2.25.1
385
215
386
216
diff view generated by jsdifflib
1
Rather than test NOCHAIN before linking, do not emit the
1
This requires finishing the conversion to tcg_target_op_def.
2
goto_tb opcode at all. We already do this for goto_ptr.
3
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
5
---
6
accel/tcg/cpu-exec.c | 2 +-
6
tcg/tci/tcg-target-con-set.h | 25 ++++
7
tcg/tcg-op.c | 9 ++++++++-
7
tcg/tci/tcg-target.h | 2 +
8
2 files changed, 9 insertions(+), 2 deletions(-)
8
tcg/tci/tcg-target.c.inc | 279 +++++++++++++++++------------------
9
3 files changed, 161 insertions(+), 145 deletions(-)
10
create mode 100644 tcg/tci/tcg-target-con-set.h
9
11
10
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
12
diff --git a/tcg/tci/tcg-target-con-set.h b/tcg/tci/tcg-target-con-set.h
13
new file mode 100644
14
index XXXXXXX..XXXXXXX
15
--- /dev/null
16
+++ b/tcg/tci/tcg-target-con-set.h
17
@@ -XXX,XX +XXX,XX @@
18
+/* SPDX-License-Identifier: MIT */
19
+/*
20
+ * TCI target-specific constraint sets.
21
+ * Copyright (c) 2021 Linaro
22
+ */
23
+
24
+/*
25
+ * C_On_Im(...) defines a constraint set with <n> outputs and <m> inputs.
26
+ * Each operand should be a sequence of constraint letters as defined by
27
+ * tcg-target-con-str.h; the constraint combination is inclusive or.
28
+ */
29
+C_O0_I2(r, r)
30
+C_O0_I2(r, ri)
31
+C_O0_I3(r, r, r)
32
+C_O0_I4(r, r, ri, ri)
33
+C_O0_I4(r, r, r, r)
34
+C_O1_I1(r, r)
35
+C_O1_I2(r, 0, r)
36
+C_O1_I2(r, ri, ri)
37
+C_O1_I2(r, r, r)
38
+C_O1_I2(r, r, ri)
39
+C_O1_I4(r, r, r, ri, ri)
40
+C_O2_I1(r, r, r)
41
+C_O2_I2(r, r, r, r)
42
+C_O2_I4(r, r, r, r, r, r)
43
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
11
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
12
--- a/accel/tcg/cpu-exec.c
45
--- a/tcg/tci/tcg-target.h
13
+++ b/accel/tcg/cpu-exec.c
46
+++ b/tcg/tci/tcg-target.h
14
@@ -XXX,XX +XXX,XX @@ static inline TranslationBlock *tb_find(CPUState *cpu,
47
@@ -XXX,XX +XXX,XX @@ static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
48
/* no need to flush icache explicitly */
49
}
50
51
+#define TCG_TARGET_CON_SET_H
52
+
53
#endif /* TCG_TARGET_H */
54
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
55
index XXXXXXX..XXXXXXX 100644
56
--- a/tcg/tci/tcg-target.c.inc
57
+++ b/tcg/tci/tcg-target.c.inc
58
@@ -XXX,XX +XXX,XX @@
59
/* Bitfield n...m (in 32 bit value). */
60
#define BITS(n, m) (((0xffffffffU << (31 - n)) >> (31 - n + m)) << m)
61
62
-/* Macros used in tcg_target_op_defs. */
63
-#define R "r"
64
-#define RI "ri"
65
-#if TCG_TARGET_REG_BITS == 32
66
-# define R64 "r", "r"
67
-#else
68
-# define R64 "r"
69
-#endif
70
-#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
71
-# define L "r", "r"
72
-# define S "r", "r"
73
-#else
74
-# define L "r"
75
-# define S "r"
76
-#endif
77
-
78
-/* TODO: documentation. */
79
-static const TCGTargetOpDef tcg_target_op_defs[] = {
80
- { INDEX_op_exit_tb, { NULL } },
81
- { INDEX_op_goto_tb, { NULL } },
82
- { INDEX_op_br, { NULL } },
83
-
84
- { INDEX_op_ld8u_i32, { R, R } },
85
- { INDEX_op_ld8s_i32, { R, R } },
86
- { INDEX_op_ld16u_i32, { R, R } },
87
- { INDEX_op_ld16s_i32, { R, R } },
88
- { INDEX_op_ld_i32, { R, R } },
89
- { INDEX_op_st8_i32, { R, R } },
90
- { INDEX_op_st16_i32, { R, R } },
91
- { INDEX_op_st_i32, { R, R } },
92
-
93
- { INDEX_op_add_i32, { R, RI, RI } },
94
- { INDEX_op_sub_i32, { R, RI, RI } },
95
- { INDEX_op_mul_i32, { R, RI, RI } },
96
- { INDEX_op_div_i32, { R, R, R } },
97
- { INDEX_op_divu_i32, { R, R, R } },
98
- { INDEX_op_rem_i32, { R, R, R } },
99
- { INDEX_op_remu_i32, { R, R, R } },
100
- /* TODO: Does R, RI, RI result in faster code than R, R, RI?
101
- If both operands are constants, we can optimize. */
102
- { INDEX_op_and_i32, { R, RI, RI } },
103
- { INDEX_op_andc_i32, { R, RI, RI } },
104
- { INDEX_op_eqv_i32, { R, RI, RI } },
105
- { INDEX_op_nand_i32, { R, RI, RI } },
106
- { INDEX_op_nor_i32, { R, RI, RI } },
107
- { INDEX_op_or_i32, { R, RI, RI } },
108
- { INDEX_op_orc_i32, { R, RI, RI } },
109
- { INDEX_op_xor_i32, { R, RI, RI } },
110
- { INDEX_op_shl_i32, { R, RI, RI } },
111
- { INDEX_op_shr_i32, { R, RI, RI } },
112
- { INDEX_op_sar_i32, { R, RI, RI } },
113
- { INDEX_op_rotl_i32, { R, RI, RI } },
114
- { INDEX_op_rotr_i32, { R, RI, RI } },
115
- { INDEX_op_deposit_i32, { R, "0", R } },
116
-
117
- { INDEX_op_brcond_i32, { R, RI } },
118
-
119
- { INDEX_op_setcond_i32, { R, R, RI } },
120
- { INDEX_op_setcond_i64, { R, R, RI } },
121
-
122
- /* TODO: Support R, R, R, R, RI, RI? Will it be faster? */
123
- { INDEX_op_add2_i32, { R, R, R, R, R, R } },
124
- { INDEX_op_sub2_i32, { R, R, R, R, R, R } },
125
- { INDEX_op_brcond2_i32, { R, R, RI, RI } },
126
- { INDEX_op_mulu2_i32, { R, R, R, R } },
127
- { INDEX_op_setcond2_i32, { R, R, R, RI, RI } },
128
-
129
- { INDEX_op_not_i32, { R, R } },
130
- { INDEX_op_neg_i32, { R, R } },
131
-
132
- { INDEX_op_ld8u_i64, { R, R } },
133
- { INDEX_op_ld8s_i64, { R, R } },
134
- { INDEX_op_ld16u_i64, { R, R } },
135
- { INDEX_op_ld16s_i64, { R, R } },
136
- { INDEX_op_ld32u_i64, { R, R } },
137
- { INDEX_op_ld32s_i64, { R, R } },
138
- { INDEX_op_ld_i64, { R, R } },
139
-
140
- { INDEX_op_st8_i64, { R, R } },
141
- { INDEX_op_st16_i64, { R, R } },
142
- { INDEX_op_st32_i64, { R, R } },
143
- { INDEX_op_st_i64, { R, R } },
144
-
145
- { INDEX_op_add_i64, { R, RI, RI } },
146
- { INDEX_op_sub_i64, { R, RI, RI } },
147
- { INDEX_op_mul_i64, { R, RI, RI } },
148
- { INDEX_op_div_i64, { R, R, R } },
149
- { INDEX_op_divu_i64, { R, R, R } },
150
- { INDEX_op_rem_i64, { R, R, R } },
151
- { INDEX_op_remu_i64, { R, R, R } },
152
- { INDEX_op_and_i64, { R, RI, RI } },
153
- { INDEX_op_andc_i64, { R, RI, RI } },
154
- { INDEX_op_eqv_i64, { R, RI, RI } },
155
- { INDEX_op_nand_i64, { R, RI, RI } },
156
- { INDEX_op_nor_i64, { R, RI, RI } },
157
- { INDEX_op_or_i64, { R, RI, RI } },
158
- { INDEX_op_orc_i64, { R, RI, RI } },
159
- { INDEX_op_xor_i64, { R, RI, RI } },
160
- { INDEX_op_shl_i64, { R, RI, RI } },
161
- { INDEX_op_shr_i64, { R, RI, RI } },
162
- { INDEX_op_sar_i64, { R, RI, RI } },
163
- { INDEX_op_rotl_i64, { R, RI, RI } },
164
- { INDEX_op_rotr_i64, { R, RI, RI } },
165
- { INDEX_op_deposit_i64, { R, "0", R } },
166
- { INDEX_op_brcond_i64, { R, RI } },
167
-
168
- { INDEX_op_ext8s_i64, { R, R } },
169
- { INDEX_op_ext16s_i64, { R, R } },
170
- { INDEX_op_ext32s_i64, { R, R } },
171
- { INDEX_op_ext8u_i64, { R, R } },
172
- { INDEX_op_ext16u_i64, { R, R } },
173
- { INDEX_op_ext32u_i64, { R, R } },
174
- { INDEX_op_ext_i32_i64, { R, R } },
175
- { INDEX_op_extu_i32_i64, { R, R } },
176
- { INDEX_op_bswap16_i64, { R, R } },
177
- { INDEX_op_bswap32_i64, { R, R } },
178
- { INDEX_op_bswap64_i64, { R, R } },
179
- { INDEX_op_not_i64, { R, R } },
180
- { INDEX_op_neg_i64, { R, R } },
181
-
182
- { INDEX_op_qemu_ld_i32, { R, L } },
183
- { INDEX_op_qemu_ld_i64, { R64, L } },
184
-
185
- { INDEX_op_qemu_st_i32, { R, S } },
186
- { INDEX_op_qemu_st_i64, { R64, S } },
187
-
188
- { INDEX_op_ext8s_i32, { R, R } },
189
- { INDEX_op_ext16s_i32, { R, R } },
190
- { INDEX_op_ext8u_i32, { R, R } },
191
- { INDEX_op_ext16u_i32, { R, R } },
192
-
193
- { INDEX_op_bswap16_i32, { R, R } },
194
- { INDEX_op_bswap32_i32, { R, R } },
195
-
196
- { INDEX_op_mb, { } },
197
- { -1 },
198
-};
199
-
200
-static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
201
+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
202
{
203
- int i, n = ARRAY_SIZE(tcg_target_op_defs);
204
+ switch (op) {
205
+ case INDEX_op_ld8u_i32:
206
+ case INDEX_op_ld8s_i32:
207
+ case INDEX_op_ld16u_i32:
208
+ case INDEX_op_ld16s_i32:
209
+ case INDEX_op_ld_i32:
210
+ case INDEX_op_ld8u_i64:
211
+ case INDEX_op_ld8s_i64:
212
+ case INDEX_op_ld16u_i64:
213
+ case INDEX_op_ld16s_i64:
214
+ case INDEX_op_ld32u_i64:
215
+ case INDEX_op_ld32s_i64:
216
+ case INDEX_op_ld_i64:
217
+ case INDEX_op_not_i32:
218
+ case INDEX_op_not_i64:
219
+ case INDEX_op_neg_i32:
220
+ case INDEX_op_neg_i64:
221
+ case INDEX_op_ext8s_i32:
222
+ case INDEX_op_ext8s_i64:
223
+ case INDEX_op_ext16s_i32:
224
+ case INDEX_op_ext16s_i64:
225
+ case INDEX_op_ext8u_i32:
226
+ case INDEX_op_ext8u_i64:
227
+ case INDEX_op_ext16u_i32:
228
+ case INDEX_op_ext16u_i64:
229
+ case INDEX_op_ext32s_i64:
230
+ case INDEX_op_ext32u_i64:
231
+ case INDEX_op_ext_i32_i64:
232
+ case INDEX_op_extu_i32_i64:
233
+ case INDEX_op_bswap16_i32:
234
+ case INDEX_op_bswap16_i64:
235
+ case INDEX_op_bswap32_i32:
236
+ case INDEX_op_bswap32_i64:
237
+ case INDEX_op_bswap64_i64:
238
+ return C_O1_I1(r, r);
239
240
- for (i = 0; i < n; ++i) {
241
- if (tcg_target_op_defs[i].op == op) {
242
- return &tcg_target_op_defs[i];
243
- }
244
+ case INDEX_op_st8_i32:
245
+ case INDEX_op_st16_i32:
246
+ case INDEX_op_st_i32:
247
+ case INDEX_op_st8_i64:
248
+ case INDEX_op_st16_i64:
249
+ case INDEX_op_st32_i64:
250
+ case INDEX_op_st_i64:
251
+ return C_O0_I2(r, r);
252
+
253
+ case INDEX_op_div_i32:
254
+ case INDEX_op_div_i64:
255
+ case INDEX_op_divu_i32:
256
+ case INDEX_op_divu_i64:
257
+ case INDEX_op_rem_i32:
258
+ case INDEX_op_rem_i64:
259
+ case INDEX_op_remu_i32:
260
+ case INDEX_op_remu_i64:
261
+ return C_O1_I2(r, r, r);
262
+
263
+ case INDEX_op_add_i32:
264
+ case INDEX_op_add_i64:
265
+ case INDEX_op_sub_i32:
266
+ case INDEX_op_sub_i64:
267
+ case INDEX_op_mul_i32:
268
+ case INDEX_op_mul_i64:
269
+ case INDEX_op_and_i32:
270
+ case INDEX_op_and_i64:
271
+ case INDEX_op_andc_i32:
272
+ case INDEX_op_andc_i64:
273
+ case INDEX_op_eqv_i32:
274
+ case INDEX_op_eqv_i64:
275
+ case INDEX_op_nand_i32:
276
+ case INDEX_op_nand_i64:
277
+ case INDEX_op_nor_i32:
278
+ case INDEX_op_nor_i64:
279
+ case INDEX_op_or_i32:
280
+ case INDEX_op_or_i64:
281
+ case INDEX_op_orc_i32:
282
+ case INDEX_op_orc_i64:
283
+ case INDEX_op_xor_i32:
284
+ case INDEX_op_xor_i64:
285
+ case INDEX_op_shl_i32:
286
+ case INDEX_op_shl_i64:
287
+ case INDEX_op_shr_i32:
288
+ case INDEX_op_shr_i64:
289
+ case INDEX_op_sar_i32:
290
+ case INDEX_op_sar_i64:
291
+ case INDEX_op_rotl_i32:
292
+ case INDEX_op_rotl_i64:
293
+ case INDEX_op_rotr_i32:
294
+ case INDEX_op_rotr_i64:
295
+ /* TODO: Does R, RI, RI result in faster code than R, R, RI? */
296
+ return C_O1_I2(r, ri, ri);
297
+
298
+ case INDEX_op_deposit_i32:
299
+ case INDEX_op_deposit_i64:
300
+ return C_O1_I2(r, 0, r);
301
+
302
+ case INDEX_op_brcond_i32:
303
+ case INDEX_op_brcond_i64:
304
+ return C_O0_I2(r, ri);
305
+
306
+ case INDEX_op_setcond_i32:
307
+ case INDEX_op_setcond_i64:
308
+ return C_O1_I2(r, r, ri);
309
+
310
+#if TCG_TARGET_REG_BITS == 32
311
+ /* TODO: Support R, R, R, R, RI, RI? Will it be faster? */
312
+ case INDEX_op_add2_i32:
313
+ case INDEX_op_sub2_i32:
314
+ return C_O2_I4(r, r, r, r, r, r);
315
+ case INDEX_op_brcond2_i32:
316
+ return C_O0_I4(r, r, ri, ri);
317
+ case INDEX_op_mulu2_i32:
318
+ return C_O2_I2(r, r, r, r);
319
+ case INDEX_op_setcond2_i32:
320
+ return C_O1_I4(r, r, r, ri, ri);
321
+#endif
322
+
323
+ case INDEX_op_qemu_ld_i32:
324
+ return (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
325
+ ? C_O1_I1(r, r)
326
+ : C_O1_I2(r, r, r));
327
+ case INDEX_op_qemu_ld_i64:
328
+ return (TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r)
329
+ : TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? C_O2_I1(r, r, r)
330
+ : C_O2_I2(r, r, r, r));
331
+ case INDEX_op_qemu_st_i32:
332
+ return (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
333
+ ? C_O0_I2(r, r)
334
+ : C_O0_I3(r, r, r));
335
+ case INDEX_op_qemu_st_i64:
336
+ return (TCG_TARGET_REG_BITS == 64 ? C_O0_I2(r, r)
337
+ : TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? C_O0_I3(r, r, r)
338
+ : C_O0_I4(r, r, r, r));
339
+
340
+ default:
341
+ g_assert_not_reached();
15
}
342
}
16
#endif
343
- return NULL;
17
/* See if we can patch the calling TB. */
18
- if (last_tb && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
19
+ if (last_tb) {
20
tb_add_jump(last_tb, tb_exit, tb);
21
}
22
return tb;
23
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/tcg/tcg-op.c
26
+++ b/tcg/tcg-op.c
27
@@ -XXX,XX +XXX,XX @@ void tcg_gen_exit_tb(TranslationBlock *tb, unsigned idx)
28
seen this numbered exit before, via tcg_gen_goto_tb. */
29
tcg_debug_assert(tcg_ctx->goto_tb_issue_mask & (1 << idx));
30
#endif
31
+ /* When not chaining, exit without indicating a link. */
32
+ if (qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
33
+ val = 0;
34
+ }
35
} else {
36
/* This is an exit via the exitreq label. */
37
tcg_debug_assert(idx == TB_EXIT_REQUESTED);
38
@@ -XXX,XX +XXX,XX @@ void tcg_gen_goto_tb(unsigned idx)
39
tcg_debug_assert((tcg_ctx->goto_tb_issue_mask & (1 << idx)) == 0);
40
tcg_ctx->goto_tb_issue_mask |= 1 << idx;
41
#endif
42
- tcg_gen_op1i(INDEX_op_goto_tb, idx);
43
+ /* When not chaining, we simply fall through to the "fallback" exit. */
44
+ if (!qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
45
+ tcg_gen_op1i(INDEX_op_goto_tb, idx);
46
+ }
47
}
344
}
48
345
49
void tcg_gen_lookup_and_goto_ptr(void)
346
static const int tcg_target_reg_alloc_order[] = {
50
--
347
--
51
2.17.2
348
2.25.1
52
349
53
350
diff view generated by jsdifflib
1
Reviewed-by: David Hildenbrand <david@redhat.com>
1
All backends have now been converted to tcg-target-con-set.h,
2
so we can remove the fallback code.
3
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
7
---
4
target/s390x/mem_helper.c | 40 +++++++++++++++++++--------------------
8
tcg/aarch64/tcg-target.h | 1 -
5
target/s390x/translate.c | 25 +++++++++++++++++-------
9
tcg/arm/tcg-target.h | 1 -
6
2 files changed, 38 insertions(+), 27 deletions(-)
10
tcg/i386/tcg-target.h | 1 -
11
tcg/mips/tcg-target.h | 1 -
12
tcg/ppc/tcg-target.h | 1 -
13
tcg/riscv/tcg-target.h | 1 -
14
tcg/s390/tcg-target.h | 1 -
15
tcg/sparc/tcg-target.h | 1 -
16
tcg/tci/tcg-target.h | 2 --
17
tcg/tcg.c | 12 ------------
18
10 files changed, 22 deletions(-)
7
19
8
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
20
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
9
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
10
--- a/target/s390x/mem_helper.c
22
--- a/tcg/aarch64/tcg-target.h
11
+++ b/target/s390x/mem_helper.c
23
+++ b/tcg/aarch64/tcg-target.h
12
@@ -XXX,XX +XXX,XX @@ void HELPER(cdsg_parallel)(CPUS390XState *env, uint64_t addr,
24
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
13
Int128 oldv;
25
#define TCG_TARGET_NEED_LDST_LABELS
14
bool fail;
26
#endif
15
27
#define TCG_TARGET_NEED_POOL_LABELS
16
- if (!HAVE_CMPXCHG128) {
28
-#define TCG_TARGET_CON_SET_H
17
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
29
18
- }
30
#endif /* AARCH64_TCG_TARGET_H */
19
+ assert(HAVE_CMPXCHG128);
31
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
20
32
index XXXXXXX..XXXXXXX 100644
21
mem_idx = cpu_mmu_index(env, false);
33
--- a/tcg/arm/tcg-target.h
22
oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
34
+++ b/tcg/arm/tcg-target.h
23
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(lpq_parallel)(CPUS390XState *env, uint64_t addr)
35
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
24
{
36
#define TCG_TARGET_NEED_LDST_LABELS
25
uintptr_t ra = GETPC();
37
#endif
26
uint64_t hi, lo;
38
#define TCG_TARGET_NEED_POOL_LABELS
27
+ int mem_idx;
39
-#define TCG_TARGET_CON_SET_H
28
+ TCGMemOpIdx oi;
40
29
+ Int128 v;
41
#endif
30
42
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
31
- if (HAVE_ATOMIC128) {
43
index XXXXXXX..XXXXXXX 100644
32
- int mem_idx = cpu_mmu_index(env, false);
44
--- a/tcg/i386/tcg-target.h
33
- TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
45
+++ b/tcg/i386/tcg-target.h
34
- Int128 v = helper_atomic_ldo_be_mmu(env, addr, oi, ra);
46
@@ -XXX,XX +XXX,XX @@ static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
35
- hi = int128_gethi(v);
47
#define TCG_TARGET_NEED_LDST_LABELS
36
- lo = int128_getlo(v);
48
#endif
37
- } else {
49
#define TCG_TARGET_NEED_POOL_LABELS
38
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
50
-#define TCG_TARGET_CON_SET_H
39
- }
51
40
+ assert(HAVE_ATOMIC128);
52
#endif
41
+
53
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
42
+ mem_idx = cpu_mmu_index(env, false);
54
index XXXXXXX..XXXXXXX 100644
43
+ oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
55
--- a/tcg/mips/tcg-target.h
44
+ v = helper_atomic_ldo_be_mmu(env, addr, oi, ra);
56
+++ b/tcg/mips/tcg-target.h
45
+ hi = int128_gethi(v);
57
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
46
+ lo = int128_getlo(v);
58
#ifdef CONFIG_SOFTMMU
47
59
#define TCG_TARGET_NEED_LDST_LABELS
48
env->retxl = lo;
60
#endif
49
return hi;
61
-#define TCG_TARGET_CON_SET_H
50
@@ -XXX,XX +XXX,XX @@ void HELPER(stpq_parallel)(CPUS390XState *env, uint64_t addr,
62
51
uint64_t low, uint64_t high)
63
#endif
52
{
64
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
53
uintptr_t ra = GETPC();
65
index XXXXXXX..XXXXXXX 100644
54
+ int mem_idx;
66
--- a/tcg/ppc/tcg-target.h
55
+ TCGMemOpIdx oi;
67
+++ b/tcg/ppc/tcg-target.h
56
+ Int128 v;
68
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
57
69
#define TCG_TARGET_NEED_LDST_LABELS
58
- if (HAVE_ATOMIC128) {
70
#endif
59
- int mem_idx = cpu_mmu_index(env, false);
71
#define TCG_TARGET_NEED_POOL_LABELS
60
- TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
72
-#define TCG_TARGET_CON_SET_H
61
- Int128 v = int128_make128(low, high);
73
62
- helper_atomic_sto_be_mmu(env, addr, v, oi, ra);
74
#endif
63
- } else {
75
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
64
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
76
index XXXXXXX..XXXXXXX 100644
65
- }
77
--- a/tcg/riscv/tcg-target.h
66
+ assert(HAVE_ATOMIC128);
78
+++ b/tcg/riscv/tcg-target.h
67
+
79
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
68
+ mem_idx = cpu_mmu_index(env, false);
80
#define TCG_TARGET_NEED_POOL_LABELS
69
+ oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
81
70
+ v = int128_make128(low, high);
82
#define TCG_TARGET_HAS_MEMORY_BSWAP 0
71
+ helper_atomic_sto_be_mmu(env, addr, v, oi, ra);
83
-#define TCG_TARGET_CON_SET_H
84
85
#endif
86
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
87
index XXXXXXX..XXXXXXX 100644
88
--- a/tcg/s390/tcg-target.h
89
+++ b/tcg/s390/tcg-target.h
90
@@ -XXX,XX +XXX,XX @@ static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
91
#define TCG_TARGET_NEED_LDST_LABELS
92
#endif
93
#define TCG_TARGET_NEED_POOL_LABELS
94
-#define TCG_TARGET_CON_SET_H
95
96
#endif
97
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
98
index XXXXXXX..XXXXXXX 100644
99
--- a/tcg/sparc/tcg-target.h
100
+++ b/tcg/sparc/tcg-target.h
101
@@ -XXX,XX +XXX,XX @@ extern bool use_vis3_instructions;
102
void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
103
104
#define TCG_TARGET_NEED_POOL_LABELS
105
-#define TCG_TARGET_CON_SET_H
106
107
#endif
108
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
109
index XXXXXXX..XXXXXXX 100644
110
--- a/tcg/tci/tcg-target.h
111
+++ b/tcg/tci/tcg-target.h
112
@@ -XXX,XX +XXX,XX @@ static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
113
/* no need to flush icache explicitly */
72
}
114
}
73
115
74
/* Execute instruction. This instruction executes an insn modified with
116
-#define TCG_TARGET_CON_SET_H
75
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
117
-
118
#endif /* TCG_TARGET_H */
119
diff --git a/tcg/tcg.c b/tcg/tcg.c
76
index XXXXXXX..XXXXXXX 100644
120
index XXXXXXX..XXXXXXX 100644
77
--- a/target/s390x/translate.c
121
--- a/tcg/tcg.c
78
+++ b/target/s390x/translate.c
122
+++ b/tcg/tcg.c
79
@@ -XXX,XX +XXX,XX @@
123
@@ -XXX,XX +XXX,XX @@
80
#include "trace-tcg.h"
124
/* Forward declarations for functions declared in tcg-target.c.inc and
81
#include "exec/translator.h"
125
used here. */
82
#include "exec/log.h"
126
static void tcg_target_init(TCGContext *s);
83
+#include "qemu/atomic128.h"
127
-#ifndef TCG_TARGET_CON_SET_H
84
128
-static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode);
85
129
-#endif
86
/* Information that (most) every instruction needs to manipulate. */
130
static void tcg_target_qemu_prologue(TCGContext *s);
87
@@ -XXX,XX +XXX,XX @@ static DisasJumpType op_cdsg(DisasContext *s, DisasOps *o)
131
static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
88
int r3 = get_field(s->fields, r3);
132
intptr_t value, intptr_t addend);
89
int d2 = get_field(s->fields, d2);
133
@@ -XXX,XX +XXX,XX @@ static void set_jmp_reset_offset(TCGContext *s, int which)
90
int b2 = get_field(s->fields, b2);
134
s->tb_jmp_reset_offset[which] = tcg_current_code_size(s);
91
+ DisasJumpType ret = DISAS_NEXT;
92
TCGv_i64 addr;
93
TCGv_i32 t_r1, t_r3;
94
95
@@ -XXX,XX +XXX,XX @@ static DisasJumpType op_cdsg(DisasContext *s, DisasOps *o)
96
addr = get_address(s, 0, b2, d2);
97
t_r1 = tcg_const_i32(r1);
98
t_r3 = tcg_const_i32(r3);
99
- if (tb_cflags(s->base.tb) & CF_PARALLEL) {
100
+ if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
101
+ gen_helper_cdsg(cpu_env, addr, t_r1, t_r3);
102
+ } else if (HAVE_CMPXCHG128) {
103
gen_helper_cdsg_parallel(cpu_env, addr, t_r1, t_r3);
104
} else {
105
- gen_helper_cdsg(cpu_env, addr, t_r1, t_r3);
106
+ gen_helper_exit_atomic(cpu_env);
107
+ ret = DISAS_NORETURN;
108
}
109
tcg_temp_free_i64(addr);
110
tcg_temp_free_i32(t_r1);
111
tcg_temp_free_i32(t_r3);
112
113
set_cc_static(s);
114
- return DISAS_NEXT;
115
+ return ret;
116
}
135
}
117
136
118
static DisasJumpType op_csst(DisasContext *s, DisasOps *o)
137
-#ifdef TCG_TARGET_CON_SET_H
119
@@ -XXX,XX +XXX,XX @@ static DisasJumpType op_lpd(DisasContext *s, DisasOps *o)
138
#define C_PFX1(P, A) P##A
120
139
#define C_PFX2(P, A, B) P##A##_##B
121
static DisasJumpType op_lpq(DisasContext *s, DisasOps *o)
140
#define C_PFX3(P, A, B, C) P##A##_##B##_##C
122
{
141
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef constraint_sets[] = {
123
- if (tb_cflags(s->base.tb) & CF_PARALLEL) {
142
#define C_O2_I3(O1, O2, I1, I2, I3) C_PFX5(c_o2_i3_, O1, O2, I1, I2, I3)
124
+ if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
143
#define C_O2_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_o2_i4_, O1, O2, I1, I2, I3, I4)
125
+ gen_helper_lpq(o->out, cpu_env, o->in2);
144
126
+ } else if (HAVE_ATOMIC128) {
145
-#endif /* TCG_TARGET_CON_SET_H */
127
gen_helper_lpq_parallel(o->out, cpu_env, o->in2);
146
-
128
} else {
147
#include "tcg-target.c.inc"
129
- gen_helper_lpq(o->out, cpu_env, o->in2);
148
130
+ gen_helper_exit_atomic(cpu_env);
149
/* compare a pointer @ptr and a tb_tc @s */
131
+ return DISAS_NORETURN;
150
@@ -XXX,XX +XXX,XX @@ static void process_op_defs(TCGContext *s)
132
}
151
continue;
133
return_low128(o->out2);
152
}
134
return DISAS_NEXT;
153
135
@@ -XXX,XX +XXX,XX @@ static DisasJumpType op_stmh(DisasContext *s, DisasOps *o)
154
-#ifdef TCG_TARGET_CON_SET_H
136
155
/*
137
static DisasJumpType op_stpq(DisasContext *s, DisasOps *o)
156
* Macro magic should make it impossible, but double-check that
138
{
157
* the array index is in range. Since the signness of an enum
139
- if (tb_cflags(s->base.tb) & CF_PARALLEL) {
158
@@ -XXX,XX +XXX,XX @@ static void process_op_defs(TCGContext *s)
140
+ if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
159
unsigned con_set = tcg_target_op_def(op);
141
+ gen_helper_stpq(cpu_env, o->in2, o->out2, o->out);
160
tcg_debug_assert(con_set < ARRAY_SIZE(constraint_sets));
142
+ } else if (HAVE_ATOMIC128) {
161
tdefs = &constraint_sets[con_set];
143
gen_helper_stpq_parallel(cpu_env, o->in2, o->out2, o->out);
162
-#else
144
} else {
163
- tdefs = tcg_target_op_def(op);
145
- gen_helper_stpq(cpu_env, o->in2, o->out2, o->out);
164
- /* Missing TCGTargetOpDef entry. */
146
+ gen_helper_exit_atomic(cpu_env);
165
- tcg_debug_assert(tdefs != NULL);
147
+ return DISAS_NORETURN;
166
-#endif
148
}
167
149
return DISAS_NEXT;
168
for (i = 0; i < nb_args; i++) {
150
}
169
const char *ct_str = tdefs->args_ct_str[i];
151
--
170
--
152
2.17.2
171
2.25.1
153
172
154
173
diff view generated by jsdifflib