1
The following changes since commit 3c8c36c9087da957f580a9bb5ebf7814a753d1c6:
1
The following changes since commit 75d30fde55485b965a1168a21d016dd07b50ed32:
2
2
3
Merge remote-tracking branch 'remotes/kraxel/tags/ui-20201104-pull-request' into staging (2020-11-04 16:52:17 +0000)
3
Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into staging (2022-10-30 15:07:25 -0400)
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-20201104
7
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20221031
8
8
9
for you to fetch changes up to c56caea3b2a4ef5d760266f554df0d92c5a45f87:
9
for you to fetch changes up to cb375590983fc3d23600d02ba05a05d34fe44150:
10
10
11
tcg: Revert "tcg/optimize: Flush data at labels not TCG_OPF_BB_END" (2020-11-04 10:35:40 -0800)
11
target/i386: Expand eflags updates inline (2022-10-31 11:39:10 +1100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Fix assert in set_jmp_reset_offset
14
Remove sparc32plus support from tcg/sparc.
15
Revert cross-branch optimization in tcg/optimize.c.
15
target/i386: Use cpu_unwind_state_data for tpr access.
16
target/i386: Expand eflags updates inline
16
17
17
----------------------------------------------------------------
18
----------------------------------------------------------------
18
Richard Henderson (2):
19
Icenowy Zheng (1):
19
tcg: Remove assert from set_jmp_reset_offset
20
tcg/tci: fix logic error when registering helpers via FFI
20
tcg: Revert "tcg/optimize: Flush data at labels not TCG_OPF_BB_END"
21
21
22
tcg/optimize.c | 35 +++++++++++++++++------------------
22
Richard Henderson (10):
23
tcg/tcg.c | 9 +++++----
23
tcg/sparc: Remove support for sparc32plus
24
2 files changed, 22 insertions(+), 22 deletions(-)
24
tcg/sparc64: Rename from tcg/sparc
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
25
33
34
meson.build | 4 +-
35
accel/tcg/internal.h | 4 +-
36
include/exec/exec-all.h | 24 ++-
37
target/i386/helper.h | 5 -
38
tcg/{sparc => sparc64}/tcg-target-con-set.h | 16 +-
39
tcg/{sparc => sparc64}/tcg-target-con-str.h | 3 -
40
tcg/{sparc => sparc64}/tcg-target.h | 11 --
41
accel/tcg/cpu-exec-common.c | 2 +-
42
accel/tcg/tb-maint.c | 4 +-
43
accel/tcg/translate-all.c | 91 +++++----
44
target/alpha/helper.c | 2 +-
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 6e6c4efed99, there has been a more appropriate range check
1
Since 9b9c37c36439, we have only supported sparc64 cpus.
2
done later at the end of tcg_gen_code. There, a failing range
2
Debian and Gentoo now only support 64-bit sparc64 userland,
3
check results in a returned error code, which causes the TB to
3
so it is time to drop the 32-bit sparc64 userland: sparc32plus.
4
be restarted at half the size.
5
4
6
Reported-by: Sai Pavan Boddu <saipava@xilinx.com>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Tested-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
8
---
11
tcg/tcg.c | 9 +++++----
9
tcg/sparc/tcg-target.h | 11 ---
12
1 file changed, 5 insertions(+), 4 deletions(-)
10
tcg/tcg.c | 75 +----------------
11
tcg/sparc/tcg-target.c.inc | 166 +++++++------------------------------
12
3 files changed, 33 insertions(+), 219 deletions(-)
13
13
14
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tcg/sparc/tcg-target.h
17
+++ b/tcg/sparc/tcg-target.h
18
@@ -XXX,XX +XXX,XX @@
19
#ifndef SPARC_TCG_TARGET_H
20
#define SPARC_TCG_TARGET_H
21
22
-#define TCG_TARGET_REG_BITS 64
23
-
24
#define TCG_TARGET_INSN_UNIT_SIZE 4
25
#define TCG_TARGET_TLB_DISPLACEMENT_BITS 32
26
#define TCG_TARGET_NB_REGS 32
27
@@ -XXX,XX +XXX,XX @@ typedef enum {
28
/* used for function call generation */
29
#define TCG_REG_CALL_STACK TCG_REG_O6
30
31
-#ifdef __arch64__
32
#define TCG_TARGET_STACK_BIAS 2047
33
#define TCG_TARGET_STACK_ALIGN 16
34
#define TCG_TARGET_CALL_STACK_OFFSET (128 + 6*8 + TCG_TARGET_STACK_BIAS)
35
-#else
36
-#define TCG_TARGET_STACK_BIAS 0
37
-#define TCG_TARGET_STACK_ALIGN 8
38
-#define TCG_TARGET_CALL_STACK_OFFSET (64 + 4 + 6*4)
39
-#endif
40
-
41
-#ifdef __arch64__
42
#define TCG_TARGET_EXTEND_ARGS 1
43
-#endif
44
45
#if defined(__VIS__) && __VIS__ >= 0x300
46
#define use_vis3_instructions 1
14
diff --git a/tcg/tcg.c b/tcg/tcg.c
47
diff --git a/tcg/tcg.c b/tcg/tcg.c
15
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
16
--- a/tcg/tcg.c
49
--- a/tcg/tcg.c
17
+++ b/tcg/tcg.c
50
+++ b/tcg/tcg.c
18
@@ -XXX,XX +XXX,XX @@ static bool tcg_resolve_relocs(TCGContext *s)
51
@@ -XXX,XX +XXX,XX @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
19
52
}
20
static void set_jmp_reset_offset(TCGContext *s, int which)
53
#endif
54
55
-#if defined(__sparc__) && !defined(__arch64__) \
56
- && !defined(CONFIG_TCG_INTERPRETER)
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
+
167
#include "../tcg-pool.c.inc"
168
169
#ifdef CONFIG_DEBUG_TCG
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)
21
{
219
{
22
- size_t off = tcg_current_code_size(s);
220
@@ -XXX,XX +XXX,XX @@ static void emit_extend(TCGContext *s, TCGReg r, int op)
23
- s->tb_jmp_reset_offset[which] = off;
221
tcg_out_arithi(s, r, r, 16, SHIFT_SRL);
24
- /* Make sure that we didn't overflow the stored offset. */
222
break;
25
- assert(s->tb_jmp_reset_offset[which] == off);
223
case MO_32:
26
+ /*
224
- if (SPARC64) {
27
+ * We will check for overflow at the end of the opcode loop in
225
- tcg_out_arith(s, r, r, 0, SHIFT_SRL);
28
+ * tcg_gen_code, where we bound tcg_current_code_size to UINT16_MAX.
226
- }
29
+ */
227
+ tcg_out_arith(s, r, r, 0, SHIFT_SRL);
30
+ s->tb_jmp_reset_offset[which] = tcg_current_code_size(s);
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 */
31
}
475
}
32
476
33
#include "tcg-target.c.inc"
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 */
34
--
505
--
35
2.25.1
506
2.34.1
36
507
37
508
diff view generated by jsdifflib
New patch
1
Emphasize that we only support full 64-bit code generation.
1
2
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
New 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.
1
3
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
1
This reverts commit cd0372c515c4732d8bd3777cdd995c139c7ed7ea.
1
From: Icenowy Zheng <uwu@icenowy.me>
2
2
3
The patch is incorrect in that it retains copies between globals and
3
When registering helpers via FFI for TCI, the inner loop that iterates
4
non-local temps, and non-local temps still die at the end of the BB.
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.
5
7
6
Failing test case for hppa:
8
Fix this logic error by using a dedicated temporary variable for the
9
inner loop.
7
10
8
    .globl    _start
11
Fixes: 22f15579fa ("tcg: Build ffi data structures for helpers")
9
_start:
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
    cmpiclr,=    0x24,%r19,%r0
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
    cmpiclr,<>    0x2f,%r19,%r19
14
Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
12
15
Message-Id: <20221028072145.1593205-1-uwu@icenowy.me>
13
---- 00010057 0001005b
16
[rth: Move declaration of j to the for loop itself]
14
movi_i32 tmp0,$0x24
15
sub_i32 tmp1,tmp0,r19
16
mov_i32 tmp2,tmp0
17
mov_i32 tmp3,r19
18
movi_i32 tmp1,$0x0
19
20
---- 0001005b 0001005f
21
brcond_i32 tmp2,tmp3,eq,$L1
22
movi_i32 tmp0,$0x2f
23
sub_i32 tmp1,tmp0,r19
24
mov_i32 tmp2,tmp0
25
mov_i32 tmp3,r19
26
movi_i32 tmp1,$0x0
27
mov_i32 r19,tmp1
28
setcond_i32 psw_n,tmp2,tmp3,ne
29
set_label $L1
30
31
In this case, both copies of "mov_i32 tmp3,r19" are removed. The
32
second because opt thought it was redundant. The first is removed
33
later by liveness because tmp3 is known to be dead. This leaves
34
the setcond_i32 with an uninitialized input.
35
36
Revert the entire patch for 5.2, and a proper optimization across
37
the branch may be considered for the next development cycle.
38
39
Reported-by: qemu@igor2.repo.hu
40
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
41
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
42
---
18
---
43
tcg/optimize.c | 35 +++++++++++++++++------------------
19
tcg/tcg.c | 6 +++---
44
1 file changed, 17 insertions(+), 18 deletions(-)
20
1 file changed, 3 insertions(+), 3 deletions(-)
45
21
46
diff --git a/tcg/optimize.c b/tcg/optimize.c
22
diff --git a/tcg/tcg.c b/tcg/tcg.c
47
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
48
--- a/tcg/optimize.c
24
--- a/tcg/tcg.c
49
+++ b/tcg/optimize.c
25
+++ b/tcg/tcg.c
50
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s)
26
@@ -XXX,XX +XXX,XX @@ static void tcg_context_init(unsigned max_cpus)
51
}
27
52
}
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];
53
}
36
}
54
- /* fall through */
55
+ goto do_reset_output;
56
57
default:
58
do_default:
59
- /*
60
- * Default case: we know nothing about operation (or were unable
61
- * to compute the operation result) so no propagation is done.
62
- */
63
- for (i = 0; i < nb_oargs; i++) {
64
- reset_temp(op->args[i]);
65
- /*
66
- * Save the corresponding known-zero bits mask for the
67
- * first output argument (only one supported so far).
68
- */
69
- if (i == 0) {
70
- arg_info(op->args[i])->mask = mask;
71
+ /* Default case: we know nothing about operation (or were unable
72
+ to compute the operation result) so no propagation is done.
73
+ We trash everything if the operation is the end of a basic
74
+ block, otherwise we only trash the output args. "mask" is
75
+ the non-zero bits mask for the first output arg. */
76
+ if (def->flags & TCG_OPF_BB_END) {
77
+ bitmap_zero(temps_used.l, nb_temps);
78
+ } else {
79
+ do_reset_output:
80
+ for (i = 0; i < nb_oargs; i++) {
81
+ reset_temp(op->args[i]);
82
+ /* Save the corresponding known-zero bits mask for the
83
+ first output argument (only one supported so far). */
84
+ if (i == 0) {
85
+ arg_info(op->args[i])->mask = mask;
86
+ }
87
}
88
}
89
break;
90
-
91
- case INDEX_op_set_label:
92
- /* Trash everything at the start of a new extended bb. */
93
- bitmap_zero(temps_used.l, nb_temps);
94
- break;
95
}
37
}
96
38
97
/* Eliminate duplicate and redundant fence instructions. */
98
--
39
--
99
2.25.1
40
2.34.1
100
41
101
42
diff view generated by jsdifflib
New patch
1
Add a way to examine the unwind data without actually
2
restoring the data back into env.
1
3
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
New 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.
1
5
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
New patch
1
We have called cpu_restore_state asserting will_exit.
2
Do not go back on that promise. This affects icount.
1
3
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
target/openrisc/sys_helper.c | 2 +-
8
1 file changed, 1 insertion(+), 1 deletion(-)
9
10
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/openrisc/sys_helper.c
13
+++ b/target/openrisc/sys_helper.c
14
@@ -XXX,XX +XXX,XX @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
15
if (env->pc != rb) {
16
env->pc = rb;
17
env->dflag = 0;
18
- cpu_loop_exit(cs);
19
}
20
+ cpu_loop_exit(cs);
21
break;
22
23
case TO_SPR(0, 17): /* SR */
24
--
25
2.34.1
26
27
diff view generated by jsdifflib
New patch
1
Since we do not plan to exit, use cpu_unwind_state_data
2
and extract exactly the data requested.
1
3
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
New 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.
1
4
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
New patch
1
The value passed is always true.
1
2
3
Reviewed-by: Claudio Fontana <cfontana@suse.de>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
accel/tcg/internal.h | 2 +-
7
accel/tcg/tb-maint.c | 4 ++--
8
accel/tcg/translate-all.c | 15 +++++++--------
9
3 files changed, 10 insertions(+), 11 deletions(-)
10
11
diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/accel/tcg/internal.h
14
+++ b/accel/tcg/internal.h
15
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
16
tb_page_addr_t phys_page2);
17
bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc);
18
void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
19
- uintptr_t host_pc, bool reset_icount);
20
+ uintptr_t host_pc);
21
22
/* Return the current PC from CPU, which may be cached in TB. */
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
}
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
--
103
2.34.1
diff view generated by jsdifflib
New patch
1
The helpers for reset_rf, cli, sti, clac, stac are
2
completely trivial; implement them inline.
1
3
4
Drop some nearby #if 0 code.
5
6
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
10
target/i386/helper.h | 5 -----
11
target/i386/tcg/cc_helper.c | 41 -------------------------------------
12
target/i386/tcg/translate.c | 30 ++++++++++++++++++++++-----
13
3 files changed, 25 insertions(+), 51 deletions(-)
14
15
diff --git a/target/i386/helper.h b/target/i386/helper.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/i386/helper.h
18
+++ b/target/i386/helper.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(syscall, void, env, int)
20
DEF_HELPER_2(sysret, void, env, int)
21
#endif
22
DEF_HELPER_FLAGS_2(pause, TCG_CALL_NO_WG, noreturn, env, int)
23
-DEF_HELPER_1(reset_rf, void, env)
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
-{
44
- env->eflags &= ~RF_MASK;
45
-}
46
-
47
-void helper_cli(CPUX86State *env)
48
-{
49
- env->eflags &= ~IF_MASK;
50
-}
51
-
52
-void helper_sti(CPUX86State *env)
53
-{
54
- env->eflags |= IF_MASK;
55
-}
56
-
57
-void helper_clac(CPUX86State *env)
58
-{
59
- env->eflags &= ~AC_MASK;
60
-}
61
-
62
-void helper_stac(CPUX86State *env)
63
-{
64
- env->eflags |= AC_MASK;
65
-}
66
-
67
-#if 0
68
-/* vm86plus instructions */
69
-void helper_cli_vm(CPUX86State *env)
70
-{
71
- env->eflags &= ~VIF_MASK;
72
-}
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
}
88
}
89
90
+static void gen_set_eflags(DisasContext *s, target_ulong mask)
91
+{
92
+ TCGv t = tcg_temp_new();
93
+
94
+ tcg_gen_ld_tl(t, cpu_env, offsetof(CPUX86State, eflags));
95
+ tcg_gen_ori_tl(t, t, mask);
96
+ tcg_gen_st_tl(t, cpu_env, offsetof(CPUX86State, eflags));
97
+ tcg_temp_free(t);
98
+}
99
+
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
}
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
--
156
2.34.1
157
158
diff view generated by jsdifflib