1
The following changes since commit 75d30fde55485b965a1168a21d016dd07b50ed32:
1
Pretty small still, but there are two patches that ought
2
to get backported to stable, so no point in delaying.
2
3
3
Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into staging (2022-10-30 15:07:25 -0400)
4
r~
5
6
The following changes since commit a5ba0a7e4e150d1350a041f0d0ef9ca6c8d7c307:
7
8
Merge tag 'pull-aspeed-20241211' of https://github.com/legoater/qemu into staging (2024-12-11 15:16:47 +0000)
4
9
5
are available in the Git repository at:
10
are available in the Git repository at:
6
11
7
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20221031
12
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20241212
8
13
9
for you to fetch changes up to cb375590983fc3d23600d02ba05a05d34fe44150:
14
for you to fetch changes up to 7ac87b14a92234b6a89b701b4043ad6cf8bdcccf:
10
15
11
target/i386: Expand eflags updates inline (2022-10-31 11:39:10 +1100)
16
target/sparc: Use memcpy() and remove memcpy32() (2024-12-12 14:28:38 -0600)
12
17
13
----------------------------------------------------------------
18
----------------------------------------------------------------
14
Remove sparc32plus support from tcg/sparc.
19
tcg: Reset free_temps before tcg_optimize
15
target/i386: Use cpu_unwind_state_data for tpr access.
20
tcg/riscv: Fix StoreStore barrier generation
16
target/i386: Expand eflags updates inline
21
include/exec: Introduce fpst alias in helper-head.h.inc
22
target/sparc: Use memcpy() and remove memcpy32()
17
23
18
----------------------------------------------------------------
24
----------------------------------------------------------------
19
Icenowy Zheng (1):
25
Philippe Mathieu-Daudé (1):
20
tcg/tci: fix logic error when registering helpers via FFI
26
target/sparc: Use memcpy() and remove memcpy32()
21
27
22
Richard Henderson (10):
28
Richard Henderson (2):
23
tcg/sparc: Remove support for sparc32plus
29
tcg: Reset free_temps before tcg_optimize
24
tcg/sparc64: Rename from tcg/sparc
30
include/exec: Introduce fpst alias in helper-head.h.inc
25
tcg/sparc64: Remove sparc32plus constraints
26
accel/tcg: Introduce cpu_unwind_state_data
27
target/i386: Use cpu_unwind_state_data for tpr access
28
target/openrisc: Always exit after mtspr npc
29
target/openrisc: Use cpu_unwind_state_data for mfspr
30
accel/tcg: Remove will_exit argument from cpu_restore_state
31
accel/tcg: Remove reset_icount argument from cpu_restore_state_from_tb
32
target/i386: Expand eflags updates inline
33
31
34
meson.build | 4 +-
32
Roman Artemev (1):
35
accel/tcg/internal.h | 4 +-
33
tcg/riscv: Fix StoreStore barrier generation
36
include/exec/exec-all.h | 24 ++-
34
37
target/i386/helper.h | 5 -
35
include/tcg/tcg-temp-internal.h | 6 ++++++
38
tcg/{sparc => sparc64}/tcg-target-con-set.h | 16 +-
36
accel/tcg/plugin-gen.c | 2 +-
39
tcg/{sparc => sparc64}/tcg-target-con-str.h | 3 -
37
target/sparc/win_helper.c | 26 ++++++++------------------
40
tcg/{sparc => sparc64}/tcg-target.h | 11 --
38
tcg/tcg.c | 5 ++++-
41
accel/tcg/cpu-exec-common.c | 2 +-
39
include/exec/helper-head.h.inc | 3 +++
42
accel/tcg/tb-maint.c | 4 +-
40
tcg/riscv/tcg-target.c.inc | 2 +-
43
accel/tcg/translate-all.c | 91 +++++----
41
6 files changed, 23 insertions(+), 21 deletions(-)
44
target/alpha/helper.c | 2 +-
42
45
target/alpha/mem_helper.c | 2 +-
46
target/arm/op_helper.c | 2 +-
47
target/arm/tlb_helper.c | 8 +-
48
target/cris/helper.c | 2 +-
49
target/i386/helper.c | 21 ++-
50
target/i386/tcg/cc_helper.c | 41 -----
51
target/i386/tcg/sysemu/svm_helper.c | 2 +-
52
target/i386/tcg/translate.c | 30 ++-
53
target/m68k/op_helper.c | 4 +-
54
target/microblaze/helper.c | 2 +-
55
target/nios2/op_helper.c | 2 +-
56
target/openrisc/sys_helper.c | 17 +-
57
target/ppc/excp_helper.c | 2 +-
58
target/s390x/tcg/excp_helper.c | 2 +-
59
target/tricore/op_helper.c | 2 +-
60
target/xtensa/helper.c | 6 +-
61
tcg/tcg.c | 81 +-------
62
tcg/{sparc => sparc64}/tcg-target.c.inc | 275 ++++++++--------------------
63
MAINTAINERS | 2 +-
64
30 files changed, 232 insertions(+), 437 deletions(-)
65
rename tcg/{sparc => sparc64}/tcg-target-con-set.h (69%)
66
rename tcg/{sparc => sparc64}/tcg-target-con-str.h (77%)
67
rename tcg/{sparc => sparc64}/tcg-target.h (95%)
68
rename tcg/{sparc => sparc64}/tcg-target.c.inc (91%)
diff view generated by jsdifflib
1
Since 9b9c37c36439, we have only supported sparc64 cpus.
1
When allocating new temps during tcg_optmize, do not re-use
2
Debian and Gentoo now only support 64-bit sparc64 userland,
2
any EBB temps that were used within the TB. We do not have
3
so it is time to drop the 32-bit sparc64 userland: sparc32plus.
3
any idea what span of the TB in which the temp was live.
4
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Introduce tcg_temp_ebb_reset_freed and use before tcg_optimize,
6
as well as replacing the equivalent in plugin_gen_inject and
7
tcg_func_start.
8
9
Cc: qemu-stable@nongnu.org
10
Fixes: fb04ab7ddd8 ("tcg/optimize: Lower TCG_COND_TST{EQ,NE} if unsupported")
11
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2711
12
Reported-by: wannacu <wannacu2049@gmail.com>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
16
---
9
tcg/sparc/tcg-target.h | 11 ---
17
include/tcg/tcg-temp-internal.h | 6 ++++++
10
tcg/tcg.c | 75 +----------------
18
accel/tcg/plugin-gen.c | 2 +-
11
tcg/sparc/tcg-target.c.inc | 166 +++++++------------------------------
19
tcg/tcg.c | 5 ++++-
12
3 files changed, 33 insertions(+), 219 deletions(-)
20
3 files changed, 11 insertions(+), 2 deletions(-)
13
21
14
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
22
diff --git a/include/tcg/tcg-temp-internal.h b/include/tcg/tcg-temp-internal.h
15
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
16
--- a/tcg/sparc/tcg-target.h
24
--- a/include/tcg/tcg-temp-internal.h
17
+++ b/tcg/sparc/tcg-target.h
25
+++ b/include/tcg/tcg-temp-internal.h
18
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@ TCGv_i64 tcg_temp_ebb_new_i64(void);
19
#ifndef SPARC_TCG_TARGET_H
27
TCGv_ptr tcg_temp_ebb_new_ptr(void);
20
#define SPARC_TCG_TARGET_H
28
TCGv_i128 tcg_temp_ebb_new_i128(void);
21
29
22
-#define TCG_TARGET_REG_BITS 64
30
+/* Forget all freed EBB temps, so that new allocations produce new temps. */
23
-
31
+static inline void tcg_temp_ebb_reset_freed(TCGContext *s)
24
#define TCG_TARGET_INSN_UNIT_SIZE 4
32
+{
25
#define TCG_TARGET_TLB_DISPLACEMENT_BITS 32
33
+ memset(s->free_temps, 0, sizeof(s->free_temps));
26
#define TCG_TARGET_NB_REGS 32
34
+}
27
@@ -XXX,XX +XXX,XX @@ typedef enum {
35
+
28
/* used for function call generation */
36
#endif /* TCG_TEMP_FREE_H */
29
#define TCG_REG_CALL_STACK TCG_REG_O6
37
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
30
38
index XXXXXXX..XXXXXXX 100644
31
-#ifdef __arch64__
39
--- a/accel/tcg/plugin-gen.c
32
#define TCG_TARGET_STACK_BIAS 2047
40
+++ b/accel/tcg/plugin-gen.c
33
#define TCG_TARGET_STACK_ALIGN 16
41
@@ -XXX,XX +XXX,XX @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
34
#define TCG_TARGET_CALL_STACK_OFFSET (128 + 6*8 + TCG_TARGET_STACK_BIAS)
42
* that might be live within the existing opcode stream.
35
-#else
43
* The simplest solution is to release them all and create new.
36
-#define TCG_TARGET_STACK_BIAS 0
44
*/
37
-#define TCG_TARGET_STACK_ALIGN 8
45
- memset(tcg_ctx->free_temps, 0, sizeof(tcg_ctx->free_temps));
38
-#define TCG_TARGET_CALL_STACK_OFFSET (64 + 4 + 6*4)
46
+ tcg_temp_ebb_reset_freed(tcg_ctx);
39
-#endif
47
40
-
48
QTAILQ_FOREACH_SAFE(op, &tcg_ctx->ops, link, next) {
41
-#ifdef __arch64__
49
switch (op->opc) {
42
#define TCG_TARGET_EXTEND_ARGS 1
43
-#endif
44
45
#if defined(__VIS__) && __VIS__ >= 0x300
46
#define use_vis3_instructions 1
47
diff --git a/tcg/tcg.c b/tcg/tcg.c
50
diff --git a/tcg/tcg.c b/tcg/tcg.c
48
index XXXXXXX..XXXXXXX 100644
51
index XXXXXXX..XXXXXXX 100644
49
--- a/tcg/tcg.c
52
--- a/tcg/tcg.c
50
+++ b/tcg/tcg.c
53
+++ b/tcg/tcg.c
51
@@ -XXX,XX +XXX,XX @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
54
@@ -XXX,XX +XXX,XX @@ void tcg_func_start(TCGContext *s)
55
s->nb_temps = s->nb_globals;
56
57
/* No temps have been previously allocated for size or locality. */
58
- memset(s->free_temps, 0, sizeof(s->free_temps));
59
+ tcg_temp_ebb_reset_freed(s);
60
61
/* No constant temps have been previously allocated. */
62
for (int i = 0; i < TCG_TYPE_COUNT; ++i) {
63
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
52
}
64
}
53
#endif
65
#endif
54
66
55
-#if defined(__sparc__) && !defined(__arch64__) \
67
+ /* Do not reuse any EBB that may be allocated within the TB. */
56
- && !defined(CONFIG_TCG_INTERPRETER)
68
+ tcg_temp_ebb_reset_freed(s);
57
- /* We have 64-bit values in one register, but need to pass as two
58
- separate parameters. Split them. */
59
- int orig_typemask = typemask;
60
- int orig_nargs = nargs;
61
- TCGv_i64 retl, reth;
62
- TCGTemp *split_args[MAX_OPC_PARAM];
63
-
64
- retl = NULL;
65
- reth = NULL;
66
- typemask = 0;
67
- for (i = real_args = 0; i < nargs; ++i) {
68
- int argtype = extract32(orig_typemask, (i + 1) * 3, 3);
69
- bool is_64bit = (argtype & ~1) == dh_typecode_i64;
70
-
71
- if (is_64bit) {
72
- TCGv_i64 orig = temp_tcgv_i64(args[i]);
73
- TCGv_i32 h = tcg_temp_new_i32();
74
- TCGv_i32 l = tcg_temp_new_i32();
75
- tcg_gen_extr_i64_i32(l, h, orig);
76
- split_args[real_args++] = tcgv_i32_temp(h);
77
- typemask |= dh_typecode_i32 << (real_args * 3);
78
- split_args[real_args++] = tcgv_i32_temp(l);
79
- typemask |= dh_typecode_i32 << (real_args * 3);
80
- } else {
81
- split_args[real_args++] = args[i];
82
- typemask |= argtype << (real_args * 3);
83
- }
84
- }
85
- nargs = real_args;
86
- args = split_args;
87
-#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
88
+#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
89
for (i = 0; i < nargs; ++i) {
90
int argtype = extract32(typemask, (i + 1) * 3, 3);
91
bool is_32bit = (argtype & ~1) == dh_typecode_i32;
92
@@ -XXX,XX +XXX,XX @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
93
94
pi = 0;
95
if (ret != NULL) {
96
-#if defined(__sparc__) && !defined(__arch64__) \
97
- && !defined(CONFIG_TCG_INTERPRETER)
98
- if ((typemask & 6) == dh_typecode_i64) {
99
- /* The 32-bit ABI is going to return the 64-bit value in
100
- the %o0/%o1 register pair. Prepare for this by using
101
- two return temporaries, and reassemble below. */
102
- retl = tcg_temp_new_i64();
103
- reth = tcg_temp_new_i64();
104
- op->args[pi++] = tcgv_i64_arg(reth);
105
- op->args[pi++] = tcgv_i64_arg(retl);
106
- nb_rets = 2;
107
- } else {
108
- op->args[pi++] = temp_arg(ret);
109
- nb_rets = 1;
110
- }
111
-#else
112
if (TCG_TARGET_REG_BITS < 64 && (typemask & 6) == dh_typecode_i64) {
113
#if HOST_BIG_ENDIAN
114
op->args[pi++] = temp_arg(ret + 1);
115
@@ -XXX,XX +XXX,XX @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
116
op->args[pi++] = temp_arg(ret);
117
nb_rets = 1;
118
}
119
-#endif
120
} else {
121
nb_rets = 0;
122
}
123
@@ -XXX,XX +XXX,XX @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
124
tcg_debug_assert(TCGOP_CALLI(op) == real_args);
125
tcg_debug_assert(pi <= ARRAY_SIZE(op->args));
126
127
-#if defined(__sparc__) && !defined(__arch64__) \
128
- && !defined(CONFIG_TCG_INTERPRETER)
129
- /* Free all of the parts we allocated above. */
130
- for (i = real_args = 0; i < orig_nargs; ++i) {
131
- int argtype = extract32(orig_typemask, (i + 1) * 3, 3);
132
- bool is_64bit = (argtype & ~1) == dh_typecode_i64;
133
-
134
- if (is_64bit) {
135
- tcg_temp_free_internal(args[real_args++]);
136
- tcg_temp_free_internal(args[real_args++]);
137
- } else {
138
- real_args++;
139
- }
140
- }
141
- if ((orig_typemask & 6) == dh_typecode_i64) {
142
- /* The 32-bit ABI returned two 32-bit pieces. Re-assemble them.
143
- Note that describing these as TCGv_i64 eliminates an unnecessary
144
- zero-extension that tcg_gen_concat_i32_i64 would create. */
145
- tcg_gen_concat32_i64(temp_tcgv_i64(ret), retl, reth);
146
- tcg_temp_free_i64(retl);
147
- tcg_temp_free_i64(reth);
148
- }
149
-#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
150
+#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
151
for (i = 0; i < nargs; ++i) {
152
int argtype = extract32(typemask, (i + 1) * 3, 3);
153
bool is_32bit = (argtype & ~1) == dh_typecode_i32;
154
diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc/tcg-target.c.inc
155
index XXXXXXX..XXXXXXX 100644
156
--- a/tcg/sparc/tcg-target.c.inc
157
+++ b/tcg/sparc/tcg-target.c.inc
158
@@ -XXX,XX +XXX,XX @@
159
* THE SOFTWARE.
160
*/
161
162
+/* We only support generating code for 64-bit mode. */
163
+#ifndef __arch64__
164
+#error "unsupported code generation mode"
165
+#endif
166
+
69
+
167
#include "../tcg-pool.c.inc"
70
tcg_optimize(s);
168
71
169
#ifdef CONFIG_DEBUG_TCG
72
reachable_code_pass(s);
170
@@ -XXX,XX +XXX,XX @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
171
};
172
#endif
173
174
-#ifdef __arch64__
175
-# define SPARC64 1
176
-#else
177
-# define SPARC64 0
178
-#endif
179
-
180
#define TCG_CT_CONST_S11 0x100
181
#define TCG_CT_CONST_S13 0x200
182
#define TCG_CT_CONST_ZERO 0x400
183
@@ -XXX,XX +XXX,XX @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
184
* high bits of the %i and %l registers garbage at all times.
185
*/
186
#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32)
187
-#if SPARC64
188
# define ALL_GENERAL_REGS64 ALL_GENERAL_REGS
189
-#else
190
-# define ALL_GENERAL_REGS64 MAKE_64BIT_MASK(0, 16)
191
-#endif
192
#define ALL_QLDST_REGS (ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS)
193
#define ALL_QLDST_REGS64 (ALL_GENERAL_REGS64 & ~SOFTMMU_RESERVE_REGS)
194
195
@@ -XXX,XX +XXX,XX @@ static bool check_fit_i32(int32_t val, unsigned int bits)
196
}
197
198
#define check_fit_tl check_fit_i64
199
-#if SPARC64
200
-# define check_fit_ptr check_fit_i64
201
-#else
202
-# define check_fit_ptr check_fit_i32
203
-#endif
204
+#define check_fit_ptr check_fit_i64
205
206
static bool patch_reloc(tcg_insn_unit *src_rw, int type,
207
intptr_t value, intptr_t addend)
208
@@ -XXX,XX +XXX,XX @@ static void tcg_out_sety(TCGContext *s, TCGReg rs)
209
tcg_out32(s, WRY | INSN_RS1(TCG_REG_G0) | INSN_RS2(rs));
210
}
211
212
-static void tcg_out_rdy(TCGContext *s, TCGReg rd)
213
-{
214
- tcg_out32(s, RDY | INSN_RD(rd));
215
-}
216
-
217
static void tcg_out_div32(TCGContext *s, TCGReg rd, TCGReg rs1,
218
int32_t val2, int val2const, int uns)
219
{
220
@@ -XXX,XX +XXX,XX @@ static void emit_extend(TCGContext *s, TCGReg r, int op)
221
tcg_out_arithi(s, r, r, 16, SHIFT_SRL);
222
break;
223
case MO_32:
224
- if (SPARC64) {
225
- tcg_out_arith(s, r, r, 0, SHIFT_SRL);
226
- }
227
+ tcg_out_arith(s, r, r, 0, SHIFT_SRL);
228
break;
229
case MO_64:
230
break;
231
@@ -XXX,XX +XXX,XX @@ static void build_trampolines(TCGContext *s)
232
};
233
234
int i;
235
- TCGReg ra;
236
237
for (i = 0; i < ARRAY_SIZE(qemu_ld_helpers); ++i) {
238
if (qemu_ld_helpers[i] == NULL) {
239
@@ -XXX,XX +XXX,XX @@ static void build_trampolines(TCGContext *s)
240
}
241
qemu_ld_trampoline[i] = tcg_splitwx_to_rx(s->code_ptr);
242
243
- if (SPARC64 || TARGET_LONG_BITS == 32) {
244
- ra = TCG_REG_O3;
245
- } else {
246
- /* Install the high part of the address. */
247
- tcg_out_arithi(s, TCG_REG_O1, TCG_REG_O2, 32, SHIFT_SRLX);
248
- ra = TCG_REG_O4;
249
- }
250
-
251
/* Set the retaddr operand. */
252
- tcg_out_mov(s, TCG_TYPE_PTR, ra, TCG_REG_O7);
253
+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O3, TCG_REG_O7);
254
/* Tail call. */
255
tcg_out_jmpl_const(s, qemu_ld_helpers[i], true, true);
256
/* delay slot -- set the env argument */
257
@@ -XXX,XX +XXX,XX @@ static void build_trampolines(TCGContext *s)
258
}
259
qemu_st_trampoline[i] = tcg_splitwx_to_rx(s->code_ptr);
260
261
- if (SPARC64) {
262
- emit_extend(s, TCG_REG_O2, i);
263
- ra = TCG_REG_O4;
264
- } else {
265
- ra = TCG_REG_O1;
266
- if (TARGET_LONG_BITS == 64) {
267
- /* Install the high part of the address. */
268
- tcg_out_arithi(s, ra, ra + 1, 32, SHIFT_SRLX);
269
- ra += 2;
270
- } else {
271
- ra += 1;
272
- }
273
- if ((i & MO_SIZE) == MO_64) {
274
- /* Install the high part of the data. */
275
- tcg_out_arithi(s, ra, ra + 1, 32, SHIFT_SRLX);
276
- ra += 2;
277
- } else {
278
- emit_extend(s, ra, i);
279
- ra += 1;
280
- }
281
- /* Skip the oi argument. */
282
- ra += 1;
283
- }
284
-
285
+ emit_extend(s, TCG_REG_O2, i);
286
+
287
/* Set the retaddr operand. */
288
- if (ra >= TCG_REG_O6) {
289
- tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_O7, TCG_REG_CALL_STACK,
290
- TCG_TARGET_CALL_STACK_OFFSET);
291
- } else {
292
- tcg_out_mov(s, TCG_TYPE_PTR, ra, TCG_REG_O7);
293
- }
294
+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O4, TCG_REG_O7);
295
296
/* Tail call. */
297
tcg_out_jmpl_const(s, qemu_st_helpers[i], true, true);
298
@@ -XXX,XX +XXX,XX @@ static void build_trampolines(TCGContext *s)
299
qemu_unalign_st_trampoline = tcg_splitwx_to_rx(s->code_ptr);
300
}
301
302
- if (!SPARC64 && TARGET_LONG_BITS == 64) {
303
- /* Install the high part of the address. */
304
- tcg_out_arithi(s, TCG_REG_O1, TCG_REG_O2, 32, SHIFT_SRLX);
305
- }
306
-
307
/* Tail call. */
308
tcg_out_jmpl_const(s, helper, true, true);
309
/* delay slot -- set the env argument */
310
@@ -XXX,XX +XXX,XX @@ static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addr, int mem_index,
311
tcg_out_cmp(s, r0, r2, 0);
312
313
/* If the guest address must be zero-extended, do so now. */
314
- if (SPARC64 && TARGET_LONG_BITS == 32) {
315
+ if (TARGET_LONG_BITS == 32) {
316
tcg_out_arithi(s, r0, addr, 0, SHIFT_SRL);
317
return r0;
318
}
319
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr,
320
321
#ifdef CONFIG_SOFTMMU
322
unsigned memi = get_mmuidx(oi);
323
- TCGReg addrz, param;
324
+ TCGReg addrz;
325
const tcg_insn_unit *func;
326
327
addrz = tcg_out_tlb_load(s, addr, memi, memop,
328
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr,
329
330
/* TLB Miss. */
331
332
- param = TCG_REG_O1;
333
- if (!SPARC64 && TARGET_LONG_BITS == 64) {
334
- /* Skip the high-part; we'll perform the extract in the trampoline. */
335
- param++;
336
- }
337
- tcg_out_mov(s, TCG_TYPE_REG, param++, addrz);
338
+ tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_O1, addrz);
339
340
/* We use the helpers to extend SB and SW data, leaving the case
341
of SL needing explicit extending below. */
342
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr,
343
tcg_debug_assert(func != NULL);
344
tcg_out_call_nodelay(s, func, false);
345
/* delay slot */
346
- tcg_out_movi(s, TCG_TYPE_I32, param, oi);
347
+ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_O2, oi);
348
349
- /* Recall that all of the helpers return 64-bit results.
350
- Which complicates things for sparcv8plus. */
351
- if (SPARC64) {
352
- /* We let the helper sign-extend SB and SW, but leave SL for here. */
353
- if (is_64 && (memop & MO_SSIZE) == MO_SL) {
354
- tcg_out_arithi(s, data, TCG_REG_O0, 0, SHIFT_SRA);
355
- } else {
356
- tcg_out_mov(s, TCG_TYPE_REG, data, TCG_REG_O0);
357
- }
358
+ /* We let the helper sign-extend SB and SW, but leave SL for here. */
359
+ if (is_64 && (memop & MO_SSIZE) == MO_SL) {
360
+ tcg_out_arithi(s, data, TCG_REG_O0, 0, SHIFT_SRA);
361
} else {
362
- if ((memop & MO_SIZE) == MO_64) {
363
- tcg_out_arithi(s, TCG_REG_O0, TCG_REG_O0, 32, SHIFT_SLLX);
364
- tcg_out_arithi(s, TCG_REG_O1, TCG_REG_O1, 0, SHIFT_SRL);
365
- tcg_out_arith(s, data, TCG_REG_O0, TCG_REG_O1, ARITH_OR);
366
- } else if (is_64) {
367
- /* Re-extend from 32-bit rather than reassembling when we
368
- know the high register must be an extension. */
369
- tcg_out_arithi(s, data, TCG_REG_O1, 0,
370
- memop & MO_SIGN ? SHIFT_SRA : SHIFT_SRL);
371
- } else {
372
- tcg_out_mov(s, TCG_TYPE_I32, data, TCG_REG_O1);
373
- }
374
+ tcg_out_mov(s, TCG_TYPE_REG, data, TCG_REG_O0);
375
}
376
377
*label_ptr |= INSN_OFF19(tcg_ptr_byte_diff(s->code_ptr, label_ptr));
378
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr,
379
unsigned s_bits = memop & MO_SIZE;
380
unsigned t_bits;
381
382
- if (SPARC64 && TARGET_LONG_BITS == 32) {
383
+ if (TARGET_LONG_BITS == 32) {
384
tcg_out_arithi(s, TCG_REG_T1, addr, 0, SHIFT_SRL);
385
addr = TCG_REG_T1;
386
}
387
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr,
388
* operation in the delay slot, and failure need only invoke the
389
* handler for SIGBUS.
390
*/
391
- TCGReg arg_low = TCG_REG_O1 + (!SPARC64 && TARGET_LONG_BITS == 64);
392
tcg_out_call_nodelay(s, qemu_unalign_ld_trampoline, false);
393
/* delay slot -- move to low part of argument reg */
394
- tcg_out_mov_delay(s, arg_low, addr);
395
+ tcg_out_mov_delay(s, TCG_REG_O1, addr);
396
} else {
397
/* Underalignment: load by pieces of minimum alignment. */
398
int ld_opc, a_size, s_size, i;
399
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr,
400
401
#ifdef CONFIG_SOFTMMU
402
unsigned memi = get_mmuidx(oi);
403
- TCGReg addrz, param;
404
+ TCGReg addrz;
405
const tcg_insn_unit *func;
406
407
addrz = tcg_out_tlb_load(s, addr, memi, memop,
408
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr,
409
410
/* TLB Miss. */
411
412
- param = TCG_REG_O1;
413
- if (!SPARC64 && TARGET_LONG_BITS == 64) {
414
- /* Skip the high-part; we'll perform the extract in the trampoline. */
415
- param++;
416
- }
417
- tcg_out_mov(s, TCG_TYPE_REG, param++, addrz);
418
- if (!SPARC64 && (memop & MO_SIZE) == MO_64) {
419
- /* Skip the high-part; we'll perform the extract in the trampoline. */
420
- param++;
421
- }
422
- tcg_out_mov(s, TCG_TYPE_REG, param++, data);
423
+ tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_O1, addrz);
424
+ tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_O2, data);
425
426
func = qemu_st_trampoline[memop & (MO_BSWAP | MO_SIZE)];
427
tcg_debug_assert(func != NULL);
428
tcg_out_call_nodelay(s, func, false);
429
/* delay slot */
430
- tcg_out_movi(s, TCG_TYPE_I32, param, oi);
431
+ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_O3, oi);
432
433
*label_ptr |= INSN_OFF19(tcg_ptr_byte_diff(s->code_ptr, label_ptr));
434
#else
435
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr,
436
unsigned s_bits = memop & MO_SIZE;
437
unsigned t_bits;
438
439
- if (SPARC64 && TARGET_LONG_BITS == 32) {
440
+ if (TARGET_LONG_BITS == 32) {
441
tcg_out_arithi(s, TCG_REG_T1, addr, 0, SHIFT_SRL);
442
addr = TCG_REG_T1;
443
}
444
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr,
445
* operation in the delay slot, and failure need only invoke the
446
* handler for SIGBUS.
447
*/
448
- TCGReg arg_low = TCG_REG_O1 + (!SPARC64 && TARGET_LONG_BITS == 64);
449
tcg_out_call_nodelay(s, qemu_unalign_st_trampoline, false);
450
/* delay slot -- move to low part of argument reg */
451
- tcg_out_mov_delay(s, arg_low, addr);
452
+ tcg_out_mov_delay(s, TCG_REG_O1, addr);
453
} else {
454
/* Underalignment: store by pieces of minimum alignment. */
455
int st_opc, a_size, s_size, i;
456
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
457
case INDEX_op_muls2_i32:
458
c = ARITH_SMUL;
459
do_mul2:
460
- /* The 32-bit multiply insns produce a full 64-bit result. If the
461
- destination register can hold it, we can avoid the slower RDY. */
462
+ /* The 32-bit multiply insns produce a full 64-bit result. */
463
tcg_out_arithc(s, a0, a2, args[3], const_args[3], c);
464
- if (SPARC64 || a0 <= TCG_REG_O7) {
465
- tcg_out_arithi(s, a1, a0, 32, SHIFT_SRLX);
466
- } else {
467
- tcg_out_rdy(s, a1);
468
- }
469
+ tcg_out_arithi(s, a1, a0, 32, SHIFT_SRLX);
470
break;
471
472
case INDEX_op_qemu_ld_i32:
473
@@ -XXX,XX +XXX,XX @@ static void tcg_target_init(TCGContext *s)
474
tcg_regset_set_reg(s->reserved_regs, TCG_REG_T2); /* for internal use */
475
}
476
477
-#if SPARC64
478
-# define ELF_HOST_MACHINE EM_SPARCV9
479
-#else
480
-# define ELF_HOST_MACHINE EM_SPARC32PLUS
481
-# define ELF_HOST_FLAGS EF_SPARC_32PLUS
482
-#endif
483
+#define ELF_HOST_MACHINE EM_SPARCV9
484
485
typedef struct {
486
DebugFrameHeader h;
487
- uint8_t fde_def_cfa[SPARC64 ? 4 : 2];
488
+ uint8_t fde_def_cfa[4];
489
uint8_t fde_win_save;
490
uint8_t fde_ret_save[3];
491
} DebugFrame;
492
@@ -XXX,XX +XXX,XX @@ static const DebugFrame debug_frame = {
493
.h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
494
495
.fde_def_cfa = {
496
-#if SPARC64
497
12, 30, /* DW_CFA_def_cfa i6, 2047 */
498
(2047 & 0x7f) | 0x80, (2047 >> 7)
499
-#else
500
- 13, 30 /* DW_CFA_def_cfa_register i6 */
501
-#endif
502
},
503
.fde_win_save = 0x2d, /* DW_CFA_GNU_window_save */
504
.fde_ret_save = { 9, 15, 31 }, /* DW_CFA_register o7, i7 */
505
--
73
--
506
2.34.1
74
2.43.0
507
75
508
76
diff view generated by jsdifflib
Deleted patch
1
Emphasize that we only support full 64-bit code generation.
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
meson.build | 4 +---
8
tcg/{sparc => sparc64}/tcg-target-con-set.h | 0
9
tcg/{sparc => sparc64}/tcg-target-con-str.h | 0
10
tcg/{sparc => sparc64}/tcg-target.h | 0
11
tcg/{sparc => sparc64}/tcg-target.c.inc | 0
12
MAINTAINERS | 2 +-
13
6 files changed, 2 insertions(+), 4 deletions(-)
14
rename tcg/{sparc => sparc64}/tcg-target-con-set.h (100%)
15
rename tcg/{sparc => sparc64}/tcg-target-con-str.h (100%)
16
rename tcg/{sparc => sparc64}/tcg-target.h (100%)
17
rename tcg/{sparc => sparc64}/tcg-target.c.inc (100%)
18
19
diff --git a/meson.build b/meson.build
20
index XXXXXXX..XXXXXXX 100644
21
--- a/meson.build
22
+++ b/meson.build
23
@@ -XXX,XX +XXX,XX @@ qapi_trace_events = []
24
bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin']
25
supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
26
supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
27
- 'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc', 'sparc64']
28
+ 'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc64']
29
30
cpu = host_machine.cpu_family()
31
32
@@ -XXX,XX +XXX,XX @@ if get_option('tcg').allowed()
33
endif
34
if get_option('tcg_interpreter')
35
tcg_arch = 'tci'
36
- elif host_arch == 'sparc64'
37
- tcg_arch = 'sparc'
38
elif host_arch == 'x86_64'
39
tcg_arch = 'i386'
40
elif host_arch == 'ppc64'
41
diff --git a/tcg/sparc/tcg-target-con-set.h b/tcg/sparc64/tcg-target-con-set.h
42
similarity index 100%
43
rename from tcg/sparc/tcg-target-con-set.h
44
rename to tcg/sparc64/tcg-target-con-set.h
45
diff --git a/tcg/sparc/tcg-target-con-str.h b/tcg/sparc64/tcg-target-con-str.h
46
similarity index 100%
47
rename from tcg/sparc/tcg-target-con-str.h
48
rename to tcg/sparc64/tcg-target-con-str.h
49
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc64/tcg-target.h
50
similarity index 100%
51
rename from tcg/sparc/tcg-target.h
52
rename to tcg/sparc64/tcg-target.h
53
diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
54
similarity index 100%
55
rename from tcg/sparc/tcg-target.c.inc
56
rename to tcg/sparc64/tcg-target.c.inc
57
diff --git a/MAINTAINERS b/MAINTAINERS
58
index XXXXXXX..XXXXXXX 100644
59
--- a/MAINTAINERS
60
+++ b/MAINTAINERS
61
@@ -XXX,XX +XXX,XX @@ L: qemu-s390x@nongnu.org
62
63
SPARC TCG target
64
S: Odd Fixes
65
-F: tcg/sparc/
66
+F: tcg/sparc64/
67
F: disas/sparc.c
68
69
TCI TCG target
70
--
71
2.34.1
72
73
diff view generated by jsdifflib
Deleted patch
1
With sparc64 we need not distinguish between registers that
2
can hold 32-bit values and those that can hold 64-bit values.
3
1
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
tcg/sparc64/tcg-target-con-set.h | 16 +----
8
tcg/sparc64/tcg-target-con-str.h | 3 -
9
tcg/sparc64/tcg-target.c.inc | 109 ++++++++++++-------------------
10
3 files changed, 44 insertions(+), 84 deletions(-)
11
12
diff --git a/tcg/sparc64/tcg-target-con-set.h b/tcg/sparc64/tcg-target-con-set.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/tcg/sparc64/tcg-target-con-set.h
15
+++ b/tcg/sparc64/tcg-target-con-set.h
16
@@ -XXX,XX +XXX,XX @@
17
*/
18
C_O0_I1(r)
19
C_O0_I2(rZ, r)
20
-C_O0_I2(RZ, r)
21
C_O0_I2(rZ, rJ)
22
-C_O0_I2(RZ, RJ)
23
-C_O0_I2(sZ, A)
24
-C_O0_I2(SZ, A)
25
-C_O1_I1(r, A)
26
-C_O1_I1(R, A)
27
+C_O0_I2(sZ, s)
28
+C_O1_I1(r, s)
29
C_O1_I1(r, r)
30
-C_O1_I1(r, R)
31
-C_O1_I1(R, r)
32
-C_O1_I1(R, R)
33
-C_O1_I2(R, R, R)
34
+C_O1_I2(r, r, r)
35
C_O1_I2(r, rZ, rJ)
36
-C_O1_I2(R, RZ, RJ)
37
C_O1_I4(r, rZ, rJ, rI, 0)
38
-C_O1_I4(R, RZ, RJ, RI, 0)
39
C_O2_I2(r, r, rZ, rJ)
40
-C_O2_I4(R, R, RZ, RZ, RJ, RI)
41
C_O2_I4(r, r, rZ, rZ, rJ, rJ)
42
diff --git a/tcg/sparc64/tcg-target-con-str.h b/tcg/sparc64/tcg-target-con-str.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/tcg/sparc64/tcg-target-con-str.h
45
+++ b/tcg/sparc64/tcg-target-con-str.h
46
@@ -XXX,XX +XXX,XX @@
47
* REGS(letter, register_mask)
48
*/
49
REGS('r', ALL_GENERAL_REGS)
50
-REGS('R', ALL_GENERAL_REGS64)
51
REGS('s', ALL_QLDST_REGS)
52
-REGS('S', ALL_QLDST_REGS64)
53
-REGS('A', TARGET_LONG_BITS == 64 ? ALL_QLDST_REGS64 : ALL_QLDST_REGS)
54
55
/*
56
* Define constraint letters for constants:
57
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
58
index XXXXXXX..XXXXXXX 100644
59
--- a/tcg/sparc64/tcg-target.c.inc
60
+++ b/tcg/sparc64/tcg-target.c.inc
61
@@ -XXX,XX +XXX,XX @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
62
#else
63
#define SOFTMMU_RESERVE_REGS 0
64
#endif
65
-
66
-/*
67
- * Note that sparcv8plus can only hold 64 bit quantities in %g and %o
68
- * registers. These are saved manually by the kernel in full 64-bit
69
- * slots. The %i and %l registers are saved by the register window
70
- * mechanism, which only allocates space for 32 bits. Given that this
71
- * window spill/fill can happen on any signal, we must consider the
72
- * high bits of the %i and %l registers garbage at all times.
73
- */
74
#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32)
75
-# define ALL_GENERAL_REGS64 ALL_GENERAL_REGS
76
#define ALL_QLDST_REGS (ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS)
77
-#define ALL_QLDST_REGS64 (ALL_GENERAL_REGS64 & ~SOFTMMU_RESERVE_REGS)
78
79
/* Define some temporary registers. T2 is used for constant generation. */
80
#define TCG_REG_T1 TCG_REG_G1
81
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
82
return C_O0_I1(r);
83
84
case INDEX_op_ld8u_i32:
85
+ case INDEX_op_ld8u_i64:
86
case INDEX_op_ld8s_i32:
87
+ case INDEX_op_ld8s_i64:
88
case INDEX_op_ld16u_i32:
89
+ case INDEX_op_ld16u_i64:
90
case INDEX_op_ld16s_i32:
91
+ case INDEX_op_ld16s_i64:
92
case INDEX_op_ld_i32:
93
+ case INDEX_op_ld32u_i64:
94
+ case INDEX_op_ld32s_i64:
95
+ case INDEX_op_ld_i64:
96
case INDEX_op_neg_i32:
97
+ case INDEX_op_neg_i64:
98
case INDEX_op_not_i32:
99
+ case INDEX_op_not_i64:
100
+ case INDEX_op_ext32s_i64:
101
+ case INDEX_op_ext32u_i64:
102
+ case INDEX_op_ext_i32_i64:
103
+ case INDEX_op_extu_i32_i64:
104
+ case INDEX_op_extrl_i64_i32:
105
+ case INDEX_op_extrh_i64_i32:
106
return C_O1_I1(r, r);
107
108
case INDEX_op_st8_i32:
109
+ case INDEX_op_st8_i64:
110
case INDEX_op_st16_i32:
111
+ case INDEX_op_st16_i64:
112
case INDEX_op_st_i32:
113
+ case INDEX_op_st32_i64:
114
+ case INDEX_op_st_i64:
115
return C_O0_I2(rZ, r);
116
117
case INDEX_op_add_i32:
118
+ case INDEX_op_add_i64:
119
case INDEX_op_mul_i32:
120
+ case INDEX_op_mul_i64:
121
case INDEX_op_div_i32:
122
+ case INDEX_op_div_i64:
123
case INDEX_op_divu_i32:
124
+ case INDEX_op_divu_i64:
125
case INDEX_op_sub_i32:
126
+ case INDEX_op_sub_i64:
127
case INDEX_op_and_i32:
128
+ case INDEX_op_and_i64:
129
case INDEX_op_andc_i32:
130
+ case INDEX_op_andc_i64:
131
case INDEX_op_or_i32:
132
+ case INDEX_op_or_i64:
133
case INDEX_op_orc_i32:
134
+ case INDEX_op_orc_i64:
135
case INDEX_op_xor_i32:
136
+ case INDEX_op_xor_i64:
137
case INDEX_op_shl_i32:
138
+ case INDEX_op_shl_i64:
139
case INDEX_op_shr_i32:
140
+ case INDEX_op_shr_i64:
141
case INDEX_op_sar_i32:
142
+ case INDEX_op_sar_i64:
143
case INDEX_op_setcond_i32:
144
+ case INDEX_op_setcond_i64:
145
return C_O1_I2(r, rZ, rJ);
146
147
case INDEX_op_brcond_i32:
148
+ case INDEX_op_brcond_i64:
149
return C_O0_I2(rZ, rJ);
150
case INDEX_op_movcond_i32:
151
+ case INDEX_op_movcond_i64:
152
return C_O1_I4(r, rZ, rJ, rI, 0);
153
case INDEX_op_add2_i32:
154
+ case INDEX_op_add2_i64:
155
case INDEX_op_sub2_i32:
156
+ case INDEX_op_sub2_i64:
157
return C_O2_I4(r, r, rZ, rZ, rJ, rJ);
158
case INDEX_op_mulu2_i32:
159
case INDEX_op_muls2_i32:
160
return C_O2_I2(r, r, rZ, rJ);
161
-
162
- case INDEX_op_ld8u_i64:
163
- case INDEX_op_ld8s_i64:
164
- case INDEX_op_ld16u_i64:
165
- case INDEX_op_ld16s_i64:
166
- case INDEX_op_ld32u_i64:
167
- case INDEX_op_ld32s_i64:
168
- case INDEX_op_ld_i64:
169
- case INDEX_op_ext_i32_i64:
170
- case INDEX_op_extu_i32_i64:
171
- return C_O1_I1(R, r);
172
-
173
- case INDEX_op_st8_i64:
174
- case INDEX_op_st16_i64:
175
- case INDEX_op_st32_i64:
176
- case INDEX_op_st_i64:
177
- return C_O0_I2(RZ, r);
178
-
179
- case INDEX_op_add_i64:
180
- case INDEX_op_mul_i64:
181
- case INDEX_op_div_i64:
182
- case INDEX_op_divu_i64:
183
- case INDEX_op_sub_i64:
184
- case INDEX_op_and_i64:
185
- case INDEX_op_andc_i64:
186
- case INDEX_op_or_i64:
187
- case INDEX_op_orc_i64:
188
- case INDEX_op_xor_i64:
189
- case INDEX_op_shl_i64:
190
- case INDEX_op_shr_i64:
191
- case INDEX_op_sar_i64:
192
- case INDEX_op_setcond_i64:
193
- return C_O1_I2(R, RZ, RJ);
194
-
195
- case INDEX_op_neg_i64:
196
- case INDEX_op_not_i64:
197
- case INDEX_op_ext32s_i64:
198
- case INDEX_op_ext32u_i64:
199
- return C_O1_I1(R, R);
200
-
201
- case INDEX_op_extrl_i64_i32:
202
- case INDEX_op_extrh_i64_i32:
203
- return C_O1_I1(r, R);
204
-
205
- case INDEX_op_brcond_i64:
206
- return C_O0_I2(RZ, RJ);
207
- case INDEX_op_movcond_i64:
208
- return C_O1_I4(R, RZ, RJ, RI, 0);
209
- case INDEX_op_add2_i64:
210
- case INDEX_op_sub2_i64:
211
- return C_O2_I4(R, R, RZ, RZ, RJ, RI);
212
case INDEX_op_muluh_i64:
213
- return C_O1_I2(R, R, R);
214
+ return C_O1_I2(r, r, r);
215
216
case INDEX_op_qemu_ld_i32:
217
- return C_O1_I1(r, A);
218
case INDEX_op_qemu_ld_i64:
219
- return C_O1_I1(R, A);
220
+ return C_O1_I1(r, s);
221
case INDEX_op_qemu_st_i32:
222
- return C_O0_I2(sZ, A);
223
case INDEX_op_qemu_st_i64:
224
- return C_O0_I2(SZ, A);
225
+ return C_O0_I2(sZ, s);
226
227
default:
228
g_assert_not_reached();
229
@@ -XXX,XX +XXX,XX @@ static void tcg_target_init(TCGContext *s)
230
#endif
231
232
tcg_target_available_regs[TCG_TYPE_I32] = ALL_GENERAL_REGS;
233
- tcg_target_available_regs[TCG_TYPE_I64] = ALL_GENERAL_REGS64;
234
+ tcg_target_available_regs[TCG_TYPE_I64] = ALL_GENERAL_REGS;
235
236
tcg_target_call_clobber_regs = 0;
237
tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G1);
238
--
239
2.34.1
diff view generated by jsdifflib
Deleted patch
1
From: Icenowy Zheng <uwu@icenowy.me>
2
1
3
When registering helpers via FFI for TCI, the inner loop that iterates
4
parameters of the helper reuses (and thus pollutes) the same variable
5
used by the outer loop that iterates all helpers, thus made some helpers
6
unregistered.
7
8
Fix this logic error by using a dedicated temporary variable for the
9
inner loop.
10
11
Fixes: 22f15579fa ("tcg: Build ffi data structures for helpers")
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
15
Message-Id: <20221028072145.1593205-1-uwu@icenowy.me>
16
[rth: Move declaration of j to the for loop itself]
17
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
18
---
19
tcg/tcg.c | 6 +++---
20
1 file changed, 3 insertions(+), 3 deletions(-)
21
22
diff --git a/tcg/tcg.c b/tcg/tcg.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/tcg/tcg.c
25
+++ b/tcg/tcg.c
26
@@ -XXX,XX +XXX,XX @@ static void tcg_context_init(unsigned max_cpus)
27
28
if (nargs != 0) {
29
ca->cif.arg_types = ca->args;
30
- for (i = 0; i < nargs; ++i) {
31
- int typecode = extract32(typemask, (i + 1) * 3, 3);
32
- ca->args[i] = typecode_to_ffi[typecode];
33
+ for (int j = 0; j < nargs; ++j) {
34
+ int typecode = extract32(typemask, (j + 1) * 3, 3);
35
+ ca->args[j] = typecode_to_ffi[typecode];
36
}
37
}
38
39
--
40
2.34.1
41
42
diff view generated by jsdifflib
Deleted patch
1
Add a way to examine the unwind data without actually
2
restoring the data back into env.
3
1
4
Reviewed-by: Claudio Fontana <cfontana@suse.de>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
accel/tcg/internal.h | 4 +--
8
include/exec/exec-all.h | 21 ++++++++---
9
accel/tcg/translate-all.c | 74 ++++++++++++++++++++++++++-------------
10
3 files changed, 68 insertions(+), 31 deletions(-)
11
12
diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/accel/tcg/internal.h
15
+++ b/accel/tcg/internal.h
16
@@ -XXX,XX +XXX,XX @@ void tb_reset_jump(TranslationBlock *tb, int n);
17
TranslationBlock *tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
18
tb_page_addr_t phys_page2);
19
bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc);
20
-int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
21
- uintptr_t searched_pc, bool reset_icount);
22
+void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
23
+ uintptr_t host_pc, bool reset_icount);
24
25
/* Return the current PC from CPU, which may be cached in TB. */
26
static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb)
27
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/include/exec/exec-all.h
30
+++ b/include/exec/exec-all.h
31
@@ -XXX,XX +XXX,XX @@ typedef ram_addr_t tb_page_addr_t;
32
#define TB_PAGE_ADDR_FMT RAM_ADDR_FMT
33
#endif
34
35
+/**
36
+ * cpu_unwind_state_data:
37
+ * @cpu: the cpu context
38
+ * @host_pc: the host pc within the translation
39
+ * @data: output data
40
+ *
41
+ * Attempt to load the the unwind state for a host pc occurring in
42
+ * translated code. If @host_pc is not in translated code, the
43
+ * function returns false; otherwise @data is loaded.
44
+ * This is the same unwind info as given to restore_state_to_opc.
45
+ */
46
+bool cpu_unwind_state_data(CPUState *cpu, uintptr_t host_pc, uint64_t *data);
47
+
48
/**
49
* cpu_restore_state:
50
- * @cpu: the vCPU state is to be restore to
51
- * @searched_pc: the host PC the fault occurred at
52
+ * @cpu: the cpu context
53
+ * @host_pc: the host pc within the translation
54
* @will_exit: true if the TB executed will be interrupted after some
55
cpu adjustments. Required for maintaining the correct
56
icount valus
57
* @return: true if state was restored, false otherwise
58
*
59
* Attempt to restore the state for a fault occurring in translated
60
- * code. If the searched_pc is not in translated code no state is
61
+ * code. If @host_pc is not in translated code no state is
62
* restored and the function returns false.
63
*/
64
-bool cpu_restore_state(CPUState *cpu, uintptr_t searched_pc, bool will_exit);
65
+bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit);
66
67
G_NORETURN void cpu_loop_exit_noexc(CPUState *cpu);
68
G_NORETURN void cpu_loop_exit(CPUState *cpu);
69
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/accel/tcg/translate-all.c
72
+++ b/accel/tcg/translate-all.c
73
@@ -XXX,XX +XXX,XX @@ static int encode_search(TranslationBlock *tb, uint8_t *block)
74
return p - block;
75
}
76
77
-/* The cpu state corresponding to 'searched_pc' is restored.
78
- * When reset_icount is true, current TB will be interrupted and
79
- * icount should be recalculated.
80
- */
81
-int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
82
- uintptr_t searched_pc, bool reset_icount)
83
+static int cpu_unwind_data_from_tb(TranslationBlock *tb, uintptr_t host_pc,
84
+ uint64_t *data)
85
{
86
- uint64_t data[TARGET_INSN_START_WORDS];
87
- uintptr_t host_pc = (uintptr_t)tb->tc.ptr;
88
+ uintptr_t iter_pc = (uintptr_t)tb->tc.ptr;
89
const uint8_t *p = tb->tc.ptr + tb->tc.size;
90
int i, j, num_insns = tb->icount;
91
-#ifdef CONFIG_PROFILER
92
- TCGProfile *prof = &tcg_ctx->prof;
93
- int64_t ti = profile_getclock();
94
-#endif
95
96
- searched_pc -= GETPC_ADJ;
97
+ host_pc -= GETPC_ADJ;
98
99
- if (searched_pc < host_pc) {
100
+ if (host_pc < iter_pc) {
101
return -1;
102
}
103
104
- memset(data, 0, sizeof(data));
105
+ memset(data, 0, sizeof(uint64_t) * TARGET_INSN_START_WORDS);
106
if (!TARGET_TB_PCREL) {
107
data[0] = tb_pc(tb);
108
}
109
110
- /* Reconstruct the stored insn data while looking for the point at
111
- which the end of the insn exceeds the searched_pc. */
112
+ /*
113
+ * Reconstruct the stored insn data while looking for the point
114
+ * at which the end of the insn exceeds host_pc.
115
+ */
116
for (i = 0; i < num_insns; ++i) {
117
for (j = 0; j < TARGET_INSN_START_WORDS; ++j) {
118
data[j] += decode_sleb128(&p);
119
}
120
- host_pc += decode_sleb128(&p);
121
- if (host_pc > searched_pc) {
122
- goto found;
123
+ iter_pc += decode_sleb128(&p);
124
+ if (iter_pc > host_pc) {
125
+ return num_insns - i;
126
}
127
}
128
return -1;
129
+}
130
+
131
+/*
132
+ * The cpu state corresponding to 'host_pc' is restored.
133
+ * When reset_icount is true, current TB will be interrupted and
134
+ * icount should be recalculated.
135
+ */
136
+void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
137
+ uintptr_t host_pc, bool reset_icount)
138
+{
139
+ uint64_t data[TARGET_INSN_START_WORDS];
140
+#ifdef CONFIG_PROFILER
141
+ TCGProfile *prof = &tcg_ctx->prof;
142
+ int64_t ti = profile_getclock();
143
+#endif
144
+ int insns_left = cpu_unwind_data_from_tb(tb, host_pc, data);
145
+
146
+ if (insns_left < 0) {
147
+ return;
148
+ }
149
150
- found:
151
if (reset_icount && (tb_cflags(tb) & CF_USE_ICOUNT)) {
152
assert(icount_enabled());
153
- /* Reset the cycle counter to the start of the block
154
- and shift if to the number of actually executed instructions */
155
- cpu_neg(cpu)->icount_decr.u16.low += num_insns - i;
156
+ /*
157
+ * Reset the cycle counter to the start of the block and
158
+ * shift if to the number of actually executed instructions.
159
+ */
160
+ cpu_neg(cpu)->icount_decr.u16.low += insns_left;
161
}
162
163
cpu->cc->tcg_ops->restore_state_to_opc(cpu, tb, data);
164
@@ -XXX,XX +XXX,XX @@ int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
165
prof->restore_time + profile_getclock() - ti);
166
qatomic_set(&prof->restore_count, prof->restore_count + 1);
167
#endif
168
- return 0;
169
}
170
171
bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit)
172
@@ -XXX,XX +XXX,XX @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit)
173
return false;
174
}
175
176
+bool cpu_unwind_state_data(CPUState *cpu, uintptr_t host_pc, uint64_t *data)
177
+{
178
+ if (in_code_gen_buffer((const void *)(host_pc - tcg_splitwx_diff))) {
179
+ TranslationBlock *tb = tcg_tb_lookup(host_pc);
180
+ if (tb) {
181
+ return cpu_unwind_data_from_tb(tb, host_pc, data) >= 0;
182
+ }
183
+ }
184
+ return false;
185
+}
186
+
187
void page_init(void)
188
{
189
page_size_init();
190
--
191
2.34.1
diff view generated by jsdifflib
Deleted patch
1
Avoid cpu_restore_state, and modifying env->eip out from
2
underneath the translator with TARGET_TB_PCREL. There is
3
some slight duplication from x86_restore_state_to_opc,
4
but it's just a few lines.
5
1
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1269
7
Reviewed-by: Claudio Fontana <cfontana@suse.de>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
10
target/i386/helper.c | 21 +++++++++++++++++++--
11
1 file changed, 19 insertions(+), 2 deletions(-)
12
13
diff --git a/target/i386/helper.c b/target/i386/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/i386/helper.c
16
+++ b/target/i386/helper.c
17
@@ -XXX,XX +XXX,XX @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
18
}
19
}
20
21
+static target_ulong get_memio_eip(CPUX86State *env)
22
+{
23
+ uint64_t data[TARGET_INSN_START_WORDS];
24
+ CPUState *cs = env_cpu(env);
25
+
26
+ if (!cpu_unwind_state_data(cs, cs->mem_io_pc, data)) {
27
+ return env->eip;
28
+ }
29
+
30
+ /* Per x86_restore_state_to_opc. */
31
+ if (TARGET_TB_PCREL) {
32
+ return (env->eip & TARGET_PAGE_MASK) | data[0];
33
+ } else {
34
+ return data[0] - env->segs[R_CS].base;
35
+ }
36
+}
37
+
38
void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
39
{
40
X86CPU *cpu = env_archcpu(env);
41
@@ -XXX,XX +XXX,XX @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
42
43
cpu_interrupt(cs, CPU_INTERRUPT_TPR);
44
} else if (tcg_enabled()) {
45
- cpu_restore_state(cs, cs->mem_io_pc, false);
46
+ target_ulong eip = get_memio_eip(env);
47
48
- apic_handle_tpr_access_report(cpu->apic_state, env->eip, access);
49
+ apic_handle_tpr_access_report(cpu->apic_state, eip, access);
50
}
51
}
52
#endif /* !CONFIG_USER_ONLY */
53
--
54
2.34.1
diff view generated by jsdifflib
1
The value passed is always true.
1
From: Roman Artemev <roman.artemev@syntacore.com>
2
2
3
Reviewed-by: Claudio Fontana <cfontana@suse.de>
3
On RISC-V to StoreStore barrier corresponds
4
`fence w, w` not `fence r, r`
5
6
Cc: qemu-stable@nongnu.org
7
Fixes: efbea94c76b ("tcg/riscv: Add slowpath load and store instructions")
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Denis Tomashev <denis.tomashev@syntacore.com>
10
Signed-off-by: Roman Artemev <roman.artemev@syntacore.com>
11
Message-ID: <e2f2131e294a49e79959d4fa9ec02cf4@syntacore.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
13
---
6
accel/tcg/internal.h | 2 +-
14
tcg/riscv/tcg-target.c.inc | 2 +-
7
accel/tcg/tb-maint.c | 4 ++--
15
1 file changed, 1 insertion(+), 1 deletion(-)
8
accel/tcg/translate-all.c | 15 +++++++--------
9
3 files changed, 10 insertions(+), 11 deletions(-)
10
16
11
diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
17
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/accel/tcg/internal.h
19
--- a/tcg/riscv/tcg-target.c.inc
14
+++ b/accel/tcg/internal.h
20
+++ b/tcg/riscv/tcg-target.c.inc
15
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
21
@@ -XXX,XX +XXX,XX @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
16
tb_page_addr_t phys_page2);
22
insn |= 0x02100000;
17
bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc);
23
}
18
void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
24
if (a0 & TCG_MO_ST_ST) {
19
- uintptr_t host_pc, bool reset_icount);
25
- insn |= 0x02200000;
20
+ uintptr_t host_pc);
26
+ insn |= 0x01100000;
21
27
}
22
/* Return the current PC from CPU, which may be cached in TB. */
28
tcg_out32(s, insn);
23
static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb)
24
diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/accel/tcg/tb-maint.c
27
+++ b/accel/tcg/tb-maint.c
28
@@ -XXX,XX +XXX,XX @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages,
29
* restore the CPU state.
30
*/
31
current_tb_modified = true;
32
- cpu_restore_state_from_tb(cpu, current_tb, retaddr, true);
33
+ cpu_restore_state_from_tb(cpu, current_tb, retaddr);
34
}
35
#endif /* TARGET_HAS_PRECISE_SMC */
36
tb_phys_invalidate__locked(tb);
37
@@ -XXX,XX +XXX,XX @@ bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc)
38
* function to partially restore the CPU state.
39
*/
40
current_tb_modified = true;
41
- cpu_restore_state_from_tb(cpu, current_tb, pc, true);
42
+ cpu_restore_state_from_tb(cpu, current_tb, pc);
43
}
44
#endif /* TARGET_HAS_PRECISE_SMC */
45
tb_phys_invalidate(tb, addr);
46
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/accel/tcg/translate-all.c
49
+++ b/accel/tcg/translate-all.c
50
@@ -XXX,XX +XXX,XX @@ static int cpu_unwind_data_from_tb(TranslationBlock *tb, uintptr_t host_pc,
51
}
29
}
52
53
/*
54
- * The cpu state corresponding to 'host_pc' is restored.
55
- * When reset_icount is true, current TB will be interrupted and
56
- * icount should be recalculated.
57
+ * The cpu state corresponding to 'host_pc' is restored in
58
+ * preparation for exiting the TB.
59
*/
60
void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
61
- uintptr_t host_pc, bool reset_icount)
62
+ uintptr_t host_pc)
63
{
64
uint64_t data[TARGET_INSN_START_WORDS];
65
#ifdef CONFIG_PROFILER
66
@@ -XXX,XX +XXX,XX @@ void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
67
return;
68
}
69
70
- if (reset_icount && (tb_cflags(tb) & CF_USE_ICOUNT)) {
71
+ if (tb_cflags(tb) & CF_USE_ICOUNT) {
72
assert(icount_enabled());
73
/*
74
* Reset the cycle counter to the start of the block and
75
@@ -XXX,XX +XXX,XX @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc)
76
if (in_code_gen_buffer((const void *)(host_pc - tcg_splitwx_diff))) {
77
TranslationBlock *tb = tcg_tb_lookup(host_pc);
78
if (tb) {
79
- cpu_restore_state_from_tb(cpu, tb, host_pc, true);
80
+ cpu_restore_state_from_tb(cpu, tb, host_pc);
81
return true;
82
}
83
}
84
@@ -XXX,XX +XXX,XX @@ void tb_check_watchpoint(CPUState *cpu, uintptr_t retaddr)
85
tb = tcg_tb_lookup(retaddr);
86
if (tb) {
87
/* We can use retranslation to find the PC. */
88
- cpu_restore_state_from_tb(cpu, tb, retaddr, true);
89
+ cpu_restore_state_from_tb(cpu, tb, retaddr);
90
tb_phys_invalidate(tb, -1);
91
} else {
92
/* The exception probably happened in a helper. The CPU state should
93
@@ -XXX,XX +XXX,XX @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
94
cpu_abort(cpu, "cpu_io_recompile: could not find TB for pc=%p",
95
(void *)retaddr);
96
}
97
- cpu_restore_state_from_tb(cpu, tb, retaddr, true);
98
+ cpu_restore_state_from_tb(cpu, tb, retaddr);
99
100
/*
101
* Some guests must re-execute the branch when re-executing a delay
102
--
30
--
103
2.34.1
31
2.43.0
diff view generated by jsdifflib
1
We have called cpu_restore_state asserting will_exit.
1
This allows targets to declare that the helper requires a
2
Do not go back on that promise. This affects icount.
2
float_status pointer and instead of a generic void pointer.
3
3
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
6
---
7
target/openrisc/sys_helper.c | 2 +-
7
include/exec/helper-head.h.inc | 3 +++
8
1 file changed, 1 insertion(+), 1 deletion(-)
8
1 file changed, 3 insertions(+)
9
9
10
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
10
diff --git a/include/exec/helper-head.h.inc b/include/exec/helper-head.h.inc
11
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/openrisc/sys_helper.c
12
--- a/include/exec/helper-head.h.inc
13
+++ b/target/openrisc/sys_helper.c
13
+++ b/include/exec/helper-head.h.inc
14
@@ -XXX,XX +XXX,XX @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
14
@@ -XXX,XX +XXX,XX @@
15
if (env->pc != rb) {
15
#define dh_alias_ptr ptr
16
env->pc = rb;
16
#define dh_alias_cptr ptr
17
env->dflag = 0;
17
#define dh_alias_env ptr
18
- cpu_loop_exit(cs);
18
+#define dh_alias_fpst ptr
19
}
19
#define dh_alias_void void
20
+ cpu_loop_exit(cs);
20
#define dh_alias_noreturn noreturn
21
break;
21
#define dh_alias(t) glue(dh_alias_, t)
22
22
@@ -XXX,XX +XXX,XX @@
23
case TO_SPR(0, 17): /* SR */
23
#define dh_ctype_ptr void *
24
#define dh_ctype_cptr const void *
25
#define dh_ctype_env CPUArchState *
26
+#define dh_ctype_fpst float_status *
27
#define dh_ctype_void void
28
#define dh_ctype_noreturn G_NORETURN void
29
#define dh_ctype(t) dh_ctype_##t
30
@@ -XXX,XX +XXX,XX @@
31
#define dh_typecode_f64 dh_typecode_i64
32
#define dh_typecode_cptr dh_typecode_ptr
33
#define dh_typecode_env dh_typecode_ptr
34
+#define dh_typecode_fpst dh_typecode_ptr
35
#define dh_typecode(t) dh_typecode_##t
36
37
#define dh_callflag_i32 0
24
--
38
--
25
2.34.1
39
2.43.0
26
40
27
41
diff view generated by jsdifflib
Deleted patch
1
Since we do not plan to exit, use cpu_unwind_state_data
2
and extract exactly the data requested.
3
1
4
This is a bug fix, in that we no longer clobber dflag.
5
6
Consider:
7
8
l.j L2 // branch
9
l.mfspr r1, ppc // delay
10
11
L1: boom
12
L2: l.lwa r3, (r4)
13
14
Here, dflag would be set by cpu_restore_state (because that is the current
15
state of the cpu), but but not cleared by tb_stop on exiting the TB
16
(because DisasContext has recorded the current value as zero).
17
18
The next TB begins at L2 with dflag incorrectly set. If the load has a
19
tlb miss, then the exception will be delivered as per a delay slot:
20
with DSX set in the status register and PC decremented (delay slots
21
restart by re-executing the branch). This will cause the return from
22
interrupt to go to L1, and boom!
23
24
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
25
---
26
target/openrisc/sys_helper.c | 11 +++++++++--
27
1 file changed, 9 insertions(+), 2 deletions(-)
28
29
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/openrisc/sys_helper.c
32
+++ b/target/openrisc/sys_helper.c
33
@@ -XXX,XX +XXX,XX @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
34
target_ulong spr)
35
{
36
#ifndef CONFIG_USER_ONLY
37
+ uint64_t data[TARGET_INSN_START_WORDS];
38
MachineState *ms = MACHINE(qdev_get_machine());
39
OpenRISCCPU *cpu = env_archcpu(env);
40
CPUState *cs = env_cpu(env);
41
@@ -XXX,XX +XXX,XX @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
42
return env->evbar;
43
44
case TO_SPR(0, 16): /* NPC (equals PC) */
45
- cpu_restore_state(cs, GETPC(), false);
46
+ if (cpu_unwind_state_data(cs, GETPC(), data)) {
47
+ return data[0];
48
+ }
49
return env->pc;
50
51
case TO_SPR(0, 17): /* SR */
52
return cpu_get_sr(env);
53
54
case TO_SPR(0, 18): /* PPC */
55
- cpu_restore_state(cs, GETPC(), false);
56
+ if (cpu_unwind_state_data(cs, GETPC(), data)) {
57
+ if (data[1] & 2) {
58
+ return data[0] - 4;
59
+ }
60
+ }
61
return env->ppc;
62
63
case TO_SPR(0, 32): /* EPCR */
64
--
65
2.34.1
diff view generated by jsdifflib
Deleted patch
1
The value passed is always true, and if the target's
2
synchronize_from_tb hook is non-trivial, not exiting
3
may be erroneous.
4
1
5
Reviewed-by: Claudio Fontana <cfontana@suse.de>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
include/exec/exec-all.h | 5 +----
9
accel/tcg/cpu-exec-common.c | 2 +-
10
accel/tcg/translate-all.c | 12 ++----------
11
target/alpha/helper.c | 2 +-
12
target/alpha/mem_helper.c | 2 +-
13
target/arm/op_helper.c | 2 +-
14
target/arm/tlb_helper.c | 8 ++++----
15
target/cris/helper.c | 2 +-
16
target/i386/tcg/sysemu/svm_helper.c | 2 +-
17
target/m68k/op_helper.c | 4 ++--
18
target/microblaze/helper.c | 2 +-
19
target/nios2/op_helper.c | 2 +-
20
target/openrisc/sys_helper.c | 4 ++--
21
target/ppc/excp_helper.c | 2 +-
22
target/s390x/tcg/excp_helper.c | 2 +-
23
target/tricore/op_helper.c | 2 +-
24
target/xtensa/helper.c | 6 +++---
25
17 files changed, 25 insertions(+), 36 deletions(-)
26
27
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/include/exec/exec-all.h
30
+++ b/include/exec/exec-all.h
31
@@ -XXX,XX +XXX,XX @@ bool cpu_unwind_state_data(CPUState *cpu, uintptr_t host_pc, uint64_t *data);
32
* cpu_restore_state:
33
* @cpu: the cpu context
34
* @host_pc: the host pc within the translation
35
- * @will_exit: true if the TB executed will be interrupted after some
36
- cpu adjustments. Required for maintaining the correct
37
- icount valus
38
* @return: true if state was restored, false otherwise
39
*
40
* Attempt to restore the state for a fault occurring in translated
41
* code. If @host_pc is not in translated code no state is
42
* restored and the function returns false.
43
*/
44
-bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit);
45
+bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc);
46
47
G_NORETURN void cpu_loop_exit_noexc(CPUState *cpu);
48
G_NORETURN void cpu_loop_exit(CPUState *cpu);
49
diff --git a/accel/tcg/cpu-exec-common.c b/accel/tcg/cpu-exec-common.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/accel/tcg/cpu-exec-common.c
52
+++ b/accel/tcg/cpu-exec-common.c
53
@@ -XXX,XX +XXX,XX @@ void cpu_loop_exit(CPUState *cpu)
54
void cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc)
55
{
56
if (pc) {
57
- cpu_restore_state(cpu, pc, true);
58
+ cpu_restore_state(cpu, pc);
59
}
60
cpu_loop_exit(cpu);
61
}
62
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/accel/tcg/translate-all.c
65
+++ b/accel/tcg/translate-all.c
66
@@ -XXX,XX +XXX,XX @@ void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
67
#endif
68
}
69
70
-bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit)
71
+bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc)
72
{
73
- /*
74
- * The pc update associated with restore without exit will
75
- * break the relative pc adjustments performed by TARGET_TB_PCREL.
76
- */
77
- if (TARGET_TB_PCREL) {
78
- assert(will_exit);
79
- }
80
-
81
/*
82
* The host_pc has to be in the rx region of the code buffer.
83
* If it is not we will not be able to resolve it here.
84
@@ -XXX,XX +XXX,XX @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit)
85
if (in_code_gen_buffer((const void *)(host_pc - tcg_splitwx_diff))) {
86
TranslationBlock *tb = tcg_tb_lookup(host_pc);
87
if (tb) {
88
- cpu_restore_state_from_tb(cpu, tb, host_pc, will_exit);
89
+ cpu_restore_state_from_tb(cpu, tb, host_pc, true);
90
return true;
91
}
92
}
93
diff --git a/target/alpha/helper.c b/target/alpha/helper.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/target/alpha/helper.c
96
+++ b/target/alpha/helper.c
97
@@ -XXX,XX +XXX,XX @@ G_NORETURN void dynamic_excp(CPUAlphaState *env, uintptr_t retaddr,
98
cs->exception_index = excp;
99
env->error_code = error;
100
if (retaddr) {
101
- cpu_restore_state(cs, retaddr, true);
102
+ cpu_restore_state(cs, retaddr);
103
/* Floating-point exceptions (our only users) point to the next PC. */
104
env->pc += 4;
105
}
106
diff --git a/target/alpha/mem_helper.c b/target/alpha/mem_helper.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/alpha/mem_helper.c
109
+++ b/target/alpha/mem_helper.c
110
@@ -XXX,XX +XXX,XX @@ static void do_unaligned_access(CPUAlphaState *env, vaddr addr, uintptr_t retadd
111
uint64_t pc;
112
uint32_t insn;
113
114
- cpu_restore_state(env_cpu(env), retaddr, true);
115
+ cpu_restore_state(env_cpu(env), retaddr);
116
117
pc = env->pc;
118
insn = cpu_ldl_code(env, pc);
119
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
120
index XXXXXXX..XXXXXXX 100644
121
--- a/target/arm/op_helper.c
122
+++ b/target/arm/op_helper.c
123
@@ -XXX,XX +XXX,XX @@ void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome,
124
* we must restore CPU state here before setting the syndrome
125
* the caller passed us, and cannot use cpu_loop_exit_restore().
126
*/
127
- cpu_restore_state(cs, ra, true);
128
+ cpu_restore_state(cs, ra);
129
raise_exception(env, excp, syndrome, target_el);
130
}
131
132
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/target/arm/tlb_helper.c
135
+++ b/target/arm/tlb_helper.c
136
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
137
ARMMMUFaultInfo fi = {};
138
139
/* now we have a real cpu fault */
140
- cpu_restore_state(cs, retaddr, true);
141
+ cpu_restore_state(cs, retaddr);
142
143
fi.type = ARMFault_Alignment;
144
arm_deliver_fault(cpu, vaddr, access_type, mmu_idx, &fi);
145
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
146
ARMMMUFaultInfo fi = {};
147
148
/* now we have a real cpu fault */
149
- cpu_restore_state(cs, retaddr, true);
150
+ cpu_restore_state(cs, retaddr);
151
152
fi.ea = arm_extabort_type(response);
153
fi.type = ARMFault_SyncExternal;
154
@@ -XXX,XX +XXX,XX @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
155
return false;
156
} else {
157
/* now we have a real cpu fault */
158
- cpu_restore_state(cs, retaddr, true);
159
+ cpu_restore_state(cs, retaddr);
160
arm_deliver_fault(cpu, address, access_type, mmu_idx, fi);
161
}
162
}
163
@@ -XXX,XX +XXX,XX @@ void arm_cpu_record_sigsegv(CPUState *cs, vaddr addr,
164
* We report both ESR and FAR to signal handlers.
165
* For now, it's easiest to deliver the fault normally.
166
*/
167
- cpu_restore_state(cs, ra, true);
168
+ cpu_restore_state(cs, ra);
169
arm_deliver_fault(cpu, addr, access_type, MMU_USER_IDX, &fi);
170
}
171
172
diff --git a/target/cris/helper.c b/target/cris/helper.c
173
index XXXXXXX..XXXXXXX 100644
174
--- a/target/cris/helper.c
175
+++ b/target/cris/helper.c
176
@@ -XXX,XX +XXX,XX @@ bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
177
cs->exception_index = EXCP_BUSFAULT;
178
env->fault_vector = res.bf_vec;
179
if (retaddr) {
180
- if (cpu_restore_state(cs, retaddr, true)) {
181
+ if (cpu_restore_state(cs, retaddr)) {
182
/* Evaluate flags after retranslation. */
183
helper_top_evaluate_flags(env);
184
}
185
diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c
186
index XXXXXXX..XXXXXXX 100644
187
--- a/target/i386/tcg/sysemu/svm_helper.c
188
+++ b/target/i386/tcg/sysemu/svm_helper.c
189
@@ -XXX,XX +XXX,XX @@ void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1,
190
{
191
CPUState *cs = env_cpu(env);
192
193
- cpu_restore_state(cs, retaddr, true);
194
+ cpu_restore_state(cs, retaddr);
195
196
qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmexit(%08x, %016" PRIx64 ", %016"
197
PRIx64 ", " TARGET_FMT_lx ")!\n",
198
diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
199
index XXXXXXX..XXXXXXX 100644
200
--- a/target/m68k/op_helper.c
201
+++ b/target/m68k/op_helper.c
202
@@ -XXX,XX +XXX,XX @@ void m68k_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
203
M68kCPU *cpu = M68K_CPU(cs);
204
CPUM68KState *env = &cpu->env;
205
206
- cpu_restore_state(cs, retaddr, true);
207
+ cpu_restore_state(cs, retaddr);
208
209
if (m68k_feature(env, M68K_FEATURE_M68040)) {
210
env->mmu.mmusr = 0;
211
@@ -XXX,XX +XXX,XX @@ raise_exception_format2(CPUM68KState *env, int tt, int ilen, uintptr_t raddr)
212
cs->exception_index = tt;
213
214
/* Recover PC and CC_OP for the beginning of the insn. */
215
- cpu_restore_state(cs, raddr, true);
216
+ cpu_restore_state(cs, raddr);
217
218
/* Flags are current in env->cc_*, or are undefined. */
219
env->cc_op = CC_OP_FLAGS;
220
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
221
index XXXXXXX..XXXXXXX 100644
222
--- a/target/microblaze/helper.c
223
+++ b/target/microblaze/helper.c
224
@@ -XXX,XX +XXX,XX @@ void mb_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
225
uint32_t esr, iflags;
226
227
/* Recover the pc and iflags from the corresponding insn_start. */
228
- cpu_restore_state(cs, retaddr, true);
229
+ cpu_restore_state(cs, retaddr);
230
iflags = cpu->env.iflags;
231
232
qemu_log_mask(CPU_LOG_INT,
233
diff --git a/target/nios2/op_helper.c b/target/nios2/op_helper.c
234
index XXXXXXX..XXXXXXX 100644
235
--- a/target/nios2/op_helper.c
236
+++ b/target/nios2/op_helper.c
237
@@ -XXX,XX +XXX,XX @@ void nios2_cpu_loop_exit_advance(CPUNios2State *env, uintptr_t retaddr)
238
* Do this here, rather than in restore_state_to_opc(),
239
* lest we affect QEMU internal exceptions, like EXCP_DEBUG.
240
*/
241
- cpu_restore_state(cs, retaddr, true);
242
+ cpu_restore_state(cs, retaddr);
243
env->pc += 4;
244
cpu_loop_exit(cs);
245
}
246
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
247
index XXXXXXX..XXXXXXX 100644
248
--- a/target/openrisc/sys_helper.c
249
+++ b/target/openrisc/sys_helper.c
250
@@ -XXX,XX +XXX,XX @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
251
break;
252
253
case TO_SPR(0, 16): /* NPC */
254
- cpu_restore_state(cs, GETPC(), true);
255
+ cpu_restore_state(cs, GETPC());
256
/* ??? Mirror or1ksim in not trashing delayed branch state
257
when "jumping" to the current instruction. */
258
if (env->pc != rb) {
259
@@ -XXX,XX +XXX,XX @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
260
case TO_SPR(8, 0): /* PMR */
261
env->pmr = rb;
262
if (env->pmr & PMR_DME || env->pmr & PMR_SME) {
263
- cpu_restore_state(cs, GETPC(), true);
264
+ cpu_restore_state(cs, GETPC());
265
env->pc += 4;
266
cs->halted = 1;
267
raise_exception(cpu, EXCP_HALTED);
268
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
269
index XXXXXXX..XXXXXXX 100644
270
--- a/target/ppc/excp_helper.c
271
+++ b/target/ppc/excp_helper.c
272
@@ -XXX,XX +XXX,XX @@ void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
273
uint32_t insn;
274
275
/* Restore state and reload the insn we executed, for filling in DSISR. */
276
- cpu_restore_state(cs, retaddr, true);
277
+ cpu_restore_state(cs, retaddr);
278
insn = cpu_ldl_code(env, env->nip);
279
280
switch (env->mmu_model) {
281
diff --git a/target/s390x/tcg/excp_helper.c b/target/s390x/tcg/excp_helper.c
282
index XXXXXXX..XXXXXXX 100644
283
--- a/target/s390x/tcg/excp_helper.c
284
+++ b/target/s390x/tcg/excp_helper.c
285
@@ -XXX,XX +XXX,XX @@ G_NORETURN void tcg_s390_program_interrupt(CPUS390XState *env,
286
{
287
CPUState *cs = env_cpu(env);
288
289
- cpu_restore_state(cs, ra, true);
290
+ cpu_restore_state(cs, ra);
291
qemu_log_mask(CPU_LOG_INT, "program interrupt at %#" PRIx64 "\n",
292
env->psw.addr);
293
trigger_pgm_exception(env, code);
294
diff --git a/target/tricore/op_helper.c b/target/tricore/op_helper.c
295
index XXXXXXX..XXXXXXX 100644
296
--- a/target/tricore/op_helper.c
297
+++ b/target/tricore/op_helper.c
298
@@ -XXX,XX +XXX,XX @@ void raise_exception_sync_internal(CPUTriCoreState *env, uint32_t class, int tin
299
{
300
CPUState *cs = env_cpu(env);
301
/* in case we come from a helper-call we need to restore the PC */
302
- cpu_restore_state(cs, pc, true);
303
+ cpu_restore_state(cs, pc);
304
305
/* Tin is loaded into d[15] */
306
env->gpr_d[15] = tin;
307
diff --git a/target/xtensa/helper.c b/target/xtensa/helper.c
308
index XXXXXXX..XXXXXXX 100644
309
--- a/target/xtensa/helper.c
310
+++ b/target/xtensa/helper.c
311
@@ -XXX,XX +XXX,XX @@ void xtensa_cpu_do_unaligned_access(CPUState *cs,
312
313
assert(xtensa_option_enabled(env->config,
314
XTENSA_OPTION_UNALIGNED_EXCEPTION));
315
- cpu_restore_state(CPU(cpu), retaddr, true);
316
+ cpu_restore_state(CPU(cpu), retaddr);
317
HELPER(exception_cause_vaddr)(env,
318
env->pc, LOAD_STORE_ALIGNMENT_CAUSE,
319
addr);
320
@@ -XXX,XX +XXX,XX @@ bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
321
} else if (probe) {
322
return false;
323
} else {
324
- cpu_restore_state(cs, retaddr, true);
325
+ cpu_restore_state(cs, retaddr);
326
HELPER(exception_cause_vaddr)(env, env->pc, ret, address);
327
}
328
}
329
@@ -XXX,XX +XXX,XX @@ void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
330
XtensaCPU *cpu = XTENSA_CPU(cs);
331
CPUXtensaState *env = &cpu->env;
332
333
- cpu_restore_state(cs, retaddr, true);
334
+ cpu_restore_state(cs, retaddr);
335
HELPER(exception_cause_vaddr)(env, env->pc,
336
access_type == MMU_INST_FETCH ?
337
INSTR_PIF_ADDR_ERROR_CAUSE :
338
--
339
2.34.1
diff view generated by jsdifflib
1
The helpers for reset_rf, cli, sti, clac, stac are
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
completely trivial; implement them inline.
3
2
4
Drop some nearby #if 0 code.
3
Rather than manually copying each register, use
4
the libc memcpy(), which is well optimized nowadays.
5
5
6
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
6
Suggested-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-ID: <20241205205418.67613-1-philmd@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
12
---
10
target/i386/helper.h | 5 -----
13
target/sparc/win_helper.c | 26 ++++++++------------------
11
target/i386/tcg/cc_helper.c | 41 -------------------------------------
14
1 file changed, 8 insertions(+), 18 deletions(-)
12
target/i386/tcg/translate.c | 30 ++++++++++++++++++++++-----
13
3 files changed, 25 insertions(+), 51 deletions(-)
14
15
15
diff --git a/target/i386/helper.h b/target/i386/helper.h
16
diff --git a/target/sparc/win_helper.c b/target/sparc/win_helper.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/target/i386/helper.h
18
--- a/target/sparc/win_helper.c
18
+++ b/target/i386/helper.h
19
+++ b/target/sparc/win_helper.c
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(syscall, void, env, int)
20
@@ -XXX,XX +XXX,XX @@
20
DEF_HELPER_2(sysret, void, env, int)
21
#include "exec/helper-proto.h"
21
#endif
22
#include "trace.h"
22
DEF_HELPER_FLAGS_2(pause, TCG_CALL_NO_WG, noreturn, env, int)
23
23
-DEF_HELPER_1(reset_rf, void, env)
24
-static inline void memcpy32(target_ulong *dst, const target_ulong *src)
24
DEF_HELPER_FLAGS_3(raise_interrupt, TCG_CALL_NO_WG, noreturn, env, int, int)
25
DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_WG, noreturn, env, int)
26
-DEF_HELPER_1(cli, void, env)
27
-DEF_HELPER_1(sti, void, env)
28
-DEF_HELPER_1(clac, void, env)
29
-DEF_HELPER_1(stac, void, env)
30
DEF_HELPER_3(boundw, void, env, tl, int)
31
DEF_HELPER_3(boundl, void, env, tl, int)
32
33
diff --git a/target/i386/tcg/cc_helper.c b/target/i386/tcg/cc_helper.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/i386/tcg/cc_helper.c
36
+++ b/target/i386/tcg/cc_helper.c
37
@@ -XXX,XX +XXX,XX @@ void helper_clts(CPUX86State *env)
38
env->cr[0] &= ~CR0_TS_MASK;
39
env->hflags &= ~HF_TS_MASK;
40
}
41
-
42
-void helper_reset_rf(CPUX86State *env)
43
-{
25
-{
44
- env->eflags &= ~RF_MASK;
26
- dst[0] = src[0];
27
- dst[1] = src[1];
28
- dst[2] = src[2];
29
- dst[3] = src[3];
30
- dst[4] = src[4];
31
- dst[5] = src[5];
32
- dst[6] = src[6];
33
- dst[7] = src[7];
45
-}
34
-}
46
-
35
-
47
-void helper_cli(CPUX86State *env)
36
void cpu_set_cwp(CPUSPARCState *env, int new_cwp)
48
-{
37
{
49
- env->eflags &= ~IF_MASK;
38
/* put the modified wrap registers at their proper location */
50
-}
39
if (env->cwp == env->nwindows - 1) {
51
-
40
- memcpy32(env->regbase, env->regbase + env->nwindows * 16);
52
-void helper_sti(CPUX86State *env)
41
+ memcpy(env->regbase, env->regbase + env->nwindows * 16,
53
-{
42
+ sizeof(env->gregs));
54
- env->eflags |= IF_MASK;
43
}
55
-}
44
env->cwp = new_cwp;
56
-
45
57
-void helper_clac(CPUX86State *env)
46
/* put the wrap registers at their temporary location */
58
-{
47
if (new_cwp == env->nwindows - 1) {
59
- env->eflags &= ~AC_MASK;
48
- memcpy32(env->regbase + env->nwindows * 16, env->regbase);
60
-}
49
+ memcpy(env->regbase + env->nwindows * 16, env->regbase,
61
-
50
+ sizeof(env->gregs));
62
-void helper_stac(CPUX86State *env)
51
}
63
-{
52
env->regwptr = env->regbase + (new_cwp * 16);
64
- env->eflags |= AC_MASK;
53
}
65
-}
54
@@ -XXX,XX +XXX,XX @@ void cpu_gl_switch_gregs(CPUSPARCState *env, uint32_t new_gl)
66
-
55
dst = get_gl_gregset(env, env->gl);
67
-#if 0
56
68
-/* vm86plus instructions */
57
if (src != dst) {
69
-void helper_cli_vm(CPUX86State *env)
58
- memcpy32(dst, env->gregs);
70
-{
59
- memcpy32(env->gregs, src);
71
- env->eflags &= ~VIF_MASK;
60
+ memcpy(dst, env->gregs, sizeof(env->gregs));
72
-}
61
+ memcpy(env->gregs, src, sizeof(env->gregs));
73
-
74
-void helper_sti_vm(CPUX86State *env)
75
-{
76
- env->eflags |= VIF_MASK;
77
- if (env->eflags & VIP_MASK) {
78
- raise_exception_ra(env, EXCP0D_GPF, GETPC());
79
- }
80
-}
81
-#endif
82
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/target/i386/tcg/translate.c
85
+++ b/target/i386/tcg/translate.c
86
@@ -XXX,XX +XXX,XX @@ static void gen_reset_hflag(DisasContext *s, uint32_t mask)
87
}
62
}
88
}
63
}
89
64
90
+static void gen_set_eflags(DisasContext *s, target_ulong mask)
65
@@ -XXX,XX +XXX,XX @@ void cpu_change_pstate(CPUSPARCState *env, uint32_t new_pstate)
91
+{
66
/* Switch global register bank */
92
+ TCGv t = tcg_temp_new();
67
src = get_gregset(env, new_pstate_regs);
93
+
68
dst = get_gregset(env, pstate_regs);
94
+ tcg_gen_ld_tl(t, cpu_env, offsetof(CPUX86State, eflags));
69
- memcpy32(dst, env->gregs);
95
+ tcg_gen_ori_tl(t, t, mask);
70
- memcpy32(env->gregs, src);
96
+ tcg_gen_st_tl(t, cpu_env, offsetof(CPUX86State, eflags));
71
+ memcpy(dst, env->gregs, sizeof(env->gregs));
97
+ tcg_temp_free(t);
72
+ memcpy(env->gregs, src, sizeof(env->gregs));
98
+}
73
} else {
99
+
74
trace_win_helper_no_switch_pstate(new_pstate_regs);
100
+static void gen_reset_eflags(DisasContext *s, target_ulong mask)
101
+{
102
+ TCGv t = tcg_temp_new();
103
+
104
+ tcg_gen_ld_tl(t, cpu_env, offsetof(CPUX86State, eflags));
105
+ tcg_gen_andi_tl(t, t, ~mask);
106
+ tcg_gen_st_tl(t, cpu_env, offsetof(CPUX86State, eflags));
107
+ tcg_temp_free(t);
108
+}
109
+
110
/* Clear BND registers during legacy branches. */
111
static void gen_bnd_jmp(DisasContext *s)
112
{
113
@@ -XXX,XX +XXX,XX @@ do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr)
114
}
75
}
115
116
if (s->base.tb->flags & HF_RF_MASK) {
117
- gen_helper_reset_rf(cpu_env);
118
+ gen_reset_eflags(s, RF_MASK);
119
}
120
if (recheck_tf) {
121
gen_helper_rechecking_single_step(cpu_env);
122
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
123
#endif
124
case 0xfa: /* cli */
125
if (check_iopl(s)) {
126
- gen_helper_cli(cpu_env);
127
+ gen_reset_eflags(s, IF_MASK);
128
}
129
break;
130
case 0xfb: /* sti */
131
if (check_iopl(s)) {
132
- gen_helper_sti(cpu_env);
133
+ gen_set_eflags(s, IF_MASK);
134
/* interruptions are enabled only the first insn after sti */
135
gen_update_eip_next(s);
136
gen_eob_inhibit_irq(s, true);
137
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
138
|| CPL(s) != 0) {
139
goto illegal_op;
140
}
141
- gen_helper_clac(cpu_env);
142
+ gen_reset_eflags(s, AC_MASK);
143
s->base.is_jmp = DISAS_EOB_NEXT;
144
break;
145
146
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
147
|| CPL(s) != 0) {
148
goto illegal_op;
149
}
150
- gen_helper_stac(cpu_env);
151
+ gen_set_eflags(s, AC_MASK);
152
s->base.is_jmp = DISAS_EOB_NEXT;
153
break;
154
155
--
76
--
156
2.34.1
77
2.43.0
157
78
158
79
diff view generated by jsdifflib