1
The following changes since commit 6587b0c1331d427b0939c37e763842550ed581db:
1
The following changes since commit 75d30fde55485b965a1168a21d016dd07b50ed32:
2
2
3
Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2021-10-15' into staging (2021-10-15 14:16:28 -0700)
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://gitlab.com/rth7680/qemu.git tags/pull-tcg-20211016
7
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20221031
8
8
9
for you to fetch changes up to 995b87dedc78b0467f5f18bbc3546072ba97516a:
9
for you to fetch changes up to cb375590983fc3d23600d02ba05a05d34fe44150:
10
10
11
Revert "cpu: Move cpu_common_props to hw/core/cpu.c" (2021-10-15 16:39:15 -0700)
11
target/i386: Expand eflags updates inline (2022-10-31 11:39:10 +1100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Move gdb singlestep to generic code
14
Remove sparc32plus support from tcg/sparc.
15
Fix cpu_common_props
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 (24):
19
Icenowy Zheng (1):
19
accel/tcg: Handle gdb singlestep in cpu_tb_exec
20
tcg/tci: fix logic error when registering helpers via FFI
20
target/alpha: Drop checks for singlestep_enabled
21
target/avr: Drop checks for singlestep_enabled
22
target/cris: Drop checks for singlestep_enabled
23
target/hexagon: Drop checks for singlestep_enabled
24
target/arm: Drop checks for singlestep_enabled
25
target/hppa: Drop checks for singlestep_enabled
26
target/i386: Check CF_NO_GOTO_TB for dc->jmp_opt
27
target/i386: Drop check for singlestep_enabled
28
target/m68k: Drop checks for singlestep_enabled
29
target/microblaze: Check CF_NO_GOTO_TB for DISAS_JUMP
30
target/microblaze: Drop checks for singlestep_enabled
31
target/mips: Fix single stepping
32
target/mips: Drop exit checks for singlestep_enabled
33
target/openrisc: Drop checks for singlestep_enabled
34
target/ppc: Drop exit checks for singlestep_enabled
35
target/riscv: Remove dead code after exception
36
target/riscv: Remove exit_tb and lookup_and_goto_ptr
37
target/rx: Drop checks for singlestep_enabled
38
target/s390x: Drop check for singlestep_enabled
39
target/sh4: Drop check for singlestep_enabled
40
target/tricore: Drop check for singlestep_enabled
41
target/xtensa: Drop check for singlestep_enabled
42
Revert "cpu: Move cpu_common_props to hw/core/cpu.c"
43
21
44
include/hw/core/cpu.h | 1 +
22
Richard Henderson (10):
45
target/i386/helper.h | 1 -
23
tcg/sparc: Remove support for sparc32plus
46
target/rx/helper.h | 1 -
24
tcg/sparc64: Rename from tcg/sparc
47
target/sh4/helper.h | 1 -
25
tcg/sparc64: Remove sparc32plus constraints
48
target/tricore/helper.h | 1 -
26
accel/tcg: Introduce cpu_unwind_state_data
49
accel/tcg/cpu-exec.c | 11 ++++
27
target/i386: Use cpu_unwind_state_data for tpr access
50
cpu.c | 21 ++++++++
28
target/openrisc: Always exit after mtspr npc
51
hw/core/cpu-common.c | 17 +-----
29
target/openrisc: Use cpu_unwind_state_data for mfspr
52
target/alpha/translate.c | 13 ++---
30
accel/tcg: Remove will_exit argument from cpu_restore_state
53
target/arm/translate-a64.c | 10 +---
31
accel/tcg: Remove reset_icount argument from cpu_restore_state_from_tb
54
target/arm/translate.c | 36 +++----------
32
target/i386: Expand eflags updates inline
55
target/avr/translate.c | 19 ++-----
56
target/cris/translate.c | 16 ------
57
target/hexagon/translate.c | 12 +----
58
target/hppa/translate.c | 17 ++----
59
target/i386/tcg/misc_helper.c | 8 ---
60
target/i386/tcg/translate.c | 9 ++--
61
target/m68k/translate.c | 44 ++++-----------
62
target/microblaze/translate.c | 18 ++-----
63
target/mips/tcg/translate.c | 75 ++++++++++++--------------
64
target/openrisc/translate.c | 18 ++-----
65
target/ppc/translate.c | 38 +++----------
66
target/riscv/translate.c | 27 +---------
67
target/rx/op_helper.c | 8 ---
68
target/rx/translate.c | 12 +----
69
target/s390x/tcg/translate.c | 8 +--
70
target/sh4/op_helper.c | 5 --
71
target/sh4/translate.c | 14 ++---
72
target/tricore/op_helper.c | 7 ---
73
target/tricore/translate.c | 14 +----
74
target/xtensa/translate.c | 25 +++------
75
target/riscv/insn_trans/trans_privileged.c.inc | 10 ++--
76
target/riscv/insn_trans/trans_rvi.c.inc | 8 ++-
77
target/riscv/insn_trans/trans_rvv.c.inc | 2 +-
78
34 files changed, 141 insertions(+), 386 deletions(-)
79
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
Deleted patch
1
Currently the change in cpu_tb_exec is masked by the debug exception
2
being raised by the translators. But this allows us to remove that code.
3
1
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
accel/tcg/cpu-exec.c | 11 +++++++++++
7
1 file changed, 11 insertions(+)
8
9
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/accel/tcg/cpu-exec.c
12
+++ b/accel/tcg/cpu-exec.c
13
@@ -XXX,XX +XXX,XX @@ cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit)
14
cc->set_pc(cpu, last_tb->pc);
15
}
16
}
17
+
18
+ /*
19
+ * If gdb single-step, and we haven't raised another exception,
20
+ * raise a debug exception. Single-step with another exception
21
+ * is handled in cpu_handle_exception.
22
+ */
23
+ if (unlikely(cpu->singlestep_enabled) && cpu->exception_index == -1) {
24
+ cpu->exception_index = EXCP_DEBUG;
25
+ cpu_loop_exit(cpu);
26
+ }
27
+
28
return last_tb;
29
}
30
31
--
32
2.25.1
33
34
diff view generated by jsdifflib
Deleted patch
1
GDB single-stepping is now handled generically.
2
1
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
target/alpha/translate.c | 13 +++----------
7
1 file changed, 3 insertions(+), 10 deletions(-)
8
9
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/target/alpha/translate.c
12
+++ b/target/alpha/translate.c
13
@@ -XXX,XX +XXX,XX @@ static void alpha_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
14
tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
15
/* FALLTHRU */
16
case DISAS_PC_UPDATED:
17
- if (!ctx->base.singlestep_enabled) {
18
- tcg_gen_lookup_and_goto_ptr();
19
- break;
20
- }
21
- /* FALLTHRU */
22
+ tcg_gen_lookup_and_goto_ptr();
23
+ break;
24
case DISAS_PC_UPDATED_NOCHAIN:
25
- if (ctx->base.singlestep_enabled) {
26
- gen_excp_1(EXCP_DEBUG, 0);
27
- } else {
28
- tcg_gen_exit_tb(NULL, 0);
29
- }
30
+ tcg_gen_exit_tb(NULL, 0);
31
break;
32
default:
33
g_assert_not_reached();
34
--
35
2.25.1
36
37
diff view generated by jsdifflib
Deleted patch
1
GDB single-stepping is now handled generically.
2
1
3
Tested-by: Michael Rolnik <mrolnik@gmail.com>
4
Reviewed-by: Michael Rolnik <mrolnik@gmail.com>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
target/avr/translate.c | 19 ++++---------------
9
1 file changed, 4 insertions(+), 15 deletions(-)
10
11
diff --git a/target/avr/translate.c b/target/avr/translate.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/avr/translate.c
14
+++ b/target/avr/translate.c
15
@@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
16
tcg_gen_exit_tb(tb, n);
17
} else {
18
tcg_gen_movi_i32(cpu_pc, dest);
19
- if (ctx->base.singlestep_enabled) {
20
- gen_helper_debug(cpu_env);
21
- } else {
22
- tcg_gen_lookup_and_goto_ptr();
23
- }
24
+ tcg_gen_lookup_and_goto_ptr();
25
}
26
ctx->base.is_jmp = DISAS_NORETURN;
27
}
28
@@ -XXX,XX +XXX,XX @@ static void avr_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
29
tcg_gen_movi_tl(cpu_pc, ctx->npc);
30
/* fall through */
31
case DISAS_LOOKUP:
32
- if (!ctx->base.singlestep_enabled) {
33
- tcg_gen_lookup_and_goto_ptr();
34
- break;
35
- }
36
- /* fall through */
37
+ tcg_gen_lookup_and_goto_ptr();
38
+ break;
39
case DISAS_EXIT:
40
- if (ctx->base.singlestep_enabled) {
41
- gen_helper_debug(cpu_env);
42
- } else {
43
- tcg_gen_exit_tb(NULL, 0);
44
- }
45
+ tcg_gen_exit_tb(NULL, 0);
46
break;
47
default:
48
g_assert_not_reached();
49
--
50
2.25.1
51
52
diff view generated by jsdifflib
Deleted patch
1
GDB single-stepping is now handled generically.
2
1
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
5
target/cris/translate.c | 16 ----------------
6
1 file changed, 16 deletions(-)
7
8
diff --git a/target/cris/translate.c b/target/cris/translate.c
9
index XXXXXXX..XXXXXXX 100644
10
--- a/target/cris/translate.c
11
+++ b/target/cris/translate.c
12
@@ -XXX,XX +XXX,XX @@ static void cris_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
13
}
14
}
15
16
- if (unlikely(dc->base.singlestep_enabled)) {
17
- switch (is_jmp) {
18
- case DISAS_TOO_MANY:
19
- case DISAS_UPDATE_NEXT:
20
- tcg_gen_movi_tl(env_pc, npc);
21
- /* fall through */
22
- case DISAS_JUMP:
23
- case DISAS_UPDATE:
24
- t_gen_raise_exception(EXCP_DEBUG);
25
- return;
26
- default:
27
- break;
28
- }
29
- g_assert_not_reached();
30
- }
31
-
32
switch (is_jmp) {
33
case DISAS_TOO_MANY:
34
gen_goto_tb(dc, 0, npc);
35
--
36
2.25.1
37
38
diff view generated by jsdifflib
Deleted patch
1
GDB single-stepping is now handled generically.
2
1
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
target/hexagon/translate.c | 12 ++----------
7
1 file changed, 2 insertions(+), 10 deletions(-)
8
9
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/target/hexagon/translate.c
12
+++ b/target/hexagon/translate.c
13
@@ -XXX,XX +XXX,XX @@ static void gen_end_tb(DisasContext *ctx)
14
{
15
gen_exec_counters(ctx);
16
tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], hex_next_PC);
17
- if (ctx->base.singlestep_enabled) {
18
- gen_exception_raw(EXCP_DEBUG);
19
- } else {
20
- tcg_gen_exit_tb(NULL, 0);
21
- }
22
+ tcg_gen_exit_tb(NULL, 0);
23
ctx->base.is_jmp = DISAS_NORETURN;
24
}
25
26
@@ -XXX,XX +XXX,XX @@ static void hexagon_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
27
case DISAS_TOO_MANY:
28
gen_exec_counters(ctx);
29
tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], ctx->base.pc_next);
30
- if (ctx->base.singlestep_enabled) {
31
- gen_exception_raw(EXCP_DEBUG);
32
- } else {
33
- tcg_gen_exit_tb(NULL, 0);
34
- }
35
+ tcg_gen_exit_tb(NULL, 0);
36
break;
37
case DISAS_NORETURN:
38
break;
39
--
40
2.25.1
41
42
diff view generated by jsdifflib
Deleted patch
1
GDB single-stepping is now handled generically.
2
1
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
5
target/arm/translate-a64.c | 10 ++--------
6
target/arm/translate.c | 36 ++++++------------------------------
7
2 files changed, 8 insertions(+), 38 deletions(-)
8
9
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/target/arm/translate-a64.c
12
+++ b/target/arm/translate-a64.c
13
@@ -XXX,XX +XXX,XX @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
14
gen_a64_set_pc_im(dest);
15
if (s->ss_active) {
16
gen_step_complete_exception(s);
17
- } else if (s->base.singlestep_enabled) {
18
- gen_exception_internal(EXCP_DEBUG);
19
} else {
20
tcg_gen_lookup_and_goto_ptr();
21
s->base.is_jmp = DISAS_NORETURN;
22
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
23
{
24
DisasContext *dc = container_of(dcbase, DisasContext, base);
25
26
- if (unlikely(dc->base.singlestep_enabled || dc->ss_active)) {
27
+ if (unlikely(dc->ss_active)) {
28
/* Note that this means single stepping WFI doesn't halt the CPU.
29
* For conditional branch insns this is harmless unreachable code as
30
* gen_goto_tb() has already handled emitting the debug exception
31
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
32
/* fall through */
33
case DISAS_EXIT:
34
case DISAS_JUMP:
35
- if (dc->base.singlestep_enabled) {
36
- gen_exception_internal(EXCP_DEBUG);
37
- } else {
38
- gen_step_complete_exception(dc);
39
- }
40
+ gen_step_complete_exception(dc);
41
break;
42
case DISAS_NORETURN:
43
break;
44
diff --git a/target/arm/translate.c b/target/arm/translate.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/translate.c
47
+++ b/target/arm/translate.c
48
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal(int excp)
49
tcg_temp_free_i32(tcg_excp);
50
}
51
52
-static void gen_step_complete_exception(DisasContext *s)
53
+static void gen_singlestep_exception(DisasContext *s)
54
{
55
/* We just completed step of an insn. Move from Active-not-pending
56
* to Active-pending, and then also take the swstep exception.
57
@@ -XXX,XX +XXX,XX @@ static void gen_step_complete_exception(DisasContext *s)
58
s->base.is_jmp = DISAS_NORETURN;
59
}
60
61
-static void gen_singlestep_exception(DisasContext *s)
62
-{
63
- /* Generate the right kind of exception for singlestep, which is
64
- * either the architectural singlestep or EXCP_DEBUG for QEMU's
65
- * gdb singlestepping.
66
- */
67
- if (s->ss_active) {
68
- gen_step_complete_exception(s);
69
- } else {
70
- gen_exception_internal(EXCP_DEBUG);
71
- }
72
-}
73
-
74
-static inline bool is_singlestepping(DisasContext *s)
75
-{
76
- /* Return true if we are singlestepping either because of
77
- * architectural singlestep or QEMU gdbstub singlestep. This does
78
- * not include the command line '-singlestep' mode which is rather
79
- * misnamed as it only means "one instruction per TB" and doesn't
80
- * affect the code we generate.
81
- */
82
- return s->base.singlestep_enabled || s->ss_active;
83
-}
84
-
85
void clear_eci_state(DisasContext *s)
86
{
87
/*
88
@@ -XXX,XX +XXX,XX @@ static inline void gen_bx_excret_final_code(DisasContext *s)
89
/* Is the new PC value in the magic range indicating exception return? */
90
tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
91
/* No: end the TB as we would for a DISAS_JMP */
92
- if (is_singlestepping(s)) {
93
+ if (s->ss_active) {
94
gen_singlestep_exception(s);
95
} else {
96
tcg_gen_exit_tb(NULL, 0);
97
@@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
98
/* Jump, specifying which TB number to use if we gen_goto_tb() */
99
static inline void gen_jmp_tb(DisasContext *s, uint32_t dest, int tbno)
100
{
101
- if (unlikely(is_singlestepping(s))) {
102
+ if (unlikely(s->ss_active)) {
103
/* An indirect jump so that we still trigger the debug exception. */
104
gen_set_pc_im(s, dest);
105
s->base.is_jmp = DISAS_JUMP;
106
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
107
dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
108
109
/* If architectural single step active, limit to 1. */
110
- if (is_singlestepping(dc)) {
111
+ if (dc->ss_active) {
112
dc->base.max_insns = 1;
113
}
114
115
@@ -XXX,XX +XXX,XX @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
116
* insn codepath itself.
117
*/
118
gen_bx_excret_final_code(dc);
119
- } else if (unlikely(is_singlestepping(dc))) {
120
+ } else if (unlikely(dc->ss_active)) {
121
/* Unconditional and "condition passed" instruction codepath. */
122
switch (dc->base.is_jmp) {
123
case DISAS_SWI:
124
@@ -XXX,XX +XXX,XX @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
125
/* "Condition failed" instruction codepath for the branch/trap insn */
126
gen_set_label(dc->condlabel);
127
gen_set_condexec(dc);
128
- if (unlikely(is_singlestepping(dc))) {
129
+ if (unlikely(dc->ss_active)) {
130
gen_set_pc_im(dc, dc->base.pc_next);
131
gen_singlestep_exception(dc);
132
} else {
133
--
134
2.25.1
135
136
diff view generated by jsdifflib
Deleted patch
1
GDB single-stepping is now handled generically.
2
1
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
target/hppa/translate.c | 17 ++++-------------
7
1 file changed, 4 insertions(+), 13 deletions(-)
8
9
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/target/hppa/translate.c
12
+++ b/target/hppa/translate.c
13
@@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *ctx, int which,
14
} else {
15
copy_iaoq_entry(cpu_iaoq_f, f, cpu_iaoq_b);
16
copy_iaoq_entry(cpu_iaoq_b, b, ctx->iaoq_n_var);
17
- if (ctx->base.singlestep_enabled) {
18
- gen_excp_1(EXCP_DEBUG);
19
- } else {
20
- tcg_gen_lookup_and_goto_ptr();
21
- }
22
+ tcg_gen_lookup_and_goto_ptr();
23
}
24
}
25
26
@@ -XXX,XX +XXX,XX @@ static bool do_rfi(DisasContext *ctx, bool rfi_r)
27
gen_helper_rfi(cpu_env);
28
}
29
/* Exit the TB to recognize new interrupts. */
30
- if (ctx->base.singlestep_enabled) {
31
- gen_excp_1(EXCP_DEBUG);
32
- } else {
33
- tcg_gen_exit_tb(NULL, 0);
34
- }
35
+ tcg_gen_exit_tb(NULL, 0);
36
ctx->base.is_jmp = DISAS_NORETURN;
37
38
return nullify_end(ctx);
39
@@ -XXX,XX +XXX,XX @@ static void hppa_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
40
nullify_save(ctx);
41
/* FALLTHRU */
42
case DISAS_IAQ_N_UPDATED:
43
- if (ctx->base.singlestep_enabled) {
44
- gen_excp_1(EXCP_DEBUG);
45
- } else if (is_jmp != DISAS_IAQ_N_STALE_EXIT) {
46
+ if (is_jmp != DISAS_IAQ_N_STALE_EXIT) {
47
tcg_gen_lookup_and_goto_ptr();
48
+ break;
49
}
50
/* FALLTHRU */
51
case DISAS_EXIT:
52
--
53
2.25.1
54
55
diff view generated by jsdifflib
Deleted patch
1
We were using singlestep_enabled as a proxy for whether
2
translator_use_goto_tb would always return false.
3
1
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
target/i386/tcg/translate.c | 5 +++--
7
1 file changed, 3 insertions(+), 2 deletions(-)
8
9
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/target/i386/tcg/translate.c
12
+++ b/target/i386/tcg/translate.c
13
@@ -XXX,XX +XXX,XX @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
14
DisasContext *dc = container_of(dcbase, DisasContext, base);
15
CPUX86State *env = cpu->env_ptr;
16
uint32_t flags = dc->base.tb->flags;
17
+ uint32_t cflags = tb_cflags(dc->base.tb);
18
int cpl = (flags >> HF_CPL_SHIFT) & 3;
19
int iopl = (flags >> IOPL_SHIFT) & 3;
20
21
@@ -XXX,XX +XXX,XX @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
22
dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX];
23
dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX];
24
dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
25
- dc->jmp_opt = !(dc->base.singlestep_enabled ||
26
+ dc->jmp_opt = !((cflags & CF_NO_GOTO_TB) ||
27
(flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)));
28
/*
29
* If jmp_opt, we want to handle each string instruction individually.
30
* For icount also disable repz optimization so that each iteration
31
* is accounted separately.
32
*/
33
- dc->repz_opt = !dc->jmp_opt && !(tb_cflags(dc->base.tb) & CF_USE_ICOUNT);
34
+ dc->repz_opt = !dc->jmp_opt && !(cflags & CF_USE_ICOUNT);
35
36
dc->T0 = tcg_temp_new();
37
dc->T1 = tcg_temp_new();
38
--
39
2.25.1
40
41
diff view generated by jsdifflib
1
GDB single-stepping is now handled generically.
1
Since 9b9c37c36439, we have only supported sparc64 cpus.
2
Debian and Gentoo now only support 64-bit sparc64 userland,
3
so it is time to drop the 32-bit sparc64 userland: sparc32plus.
2
4
3
Acked-by: Laurent Vivier <laurent@vivier.eu>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
8
---
6
target/m68k/translate.c | 44 +++++++++--------------------------------
9
tcg/sparc/tcg-target.h | 11 ---
7
1 file changed, 9 insertions(+), 35 deletions(-)
10
tcg/tcg.c | 75 +----------------
11
tcg/sparc/tcg-target.c.inc | 166 +++++++------------------------------
12
3 files changed, 33 insertions(+), 219 deletions(-)
8
13
9
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
14
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
10
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
11
--- a/target/m68k/translate.c
16
--- a/tcg/sparc/tcg-target.h
12
+++ b/target/m68k/translate.c
17
+++ b/tcg/sparc/tcg-target.h
13
@@ -XXX,XX +XXX,XX @@ static void do_writebacks(DisasContext *s)
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
47
diff --git a/tcg/tcg.c b/tcg/tcg.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/tcg/tcg.c
50
+++ b/tcg/tcg.c
51
@@ -XXX,XX +XXX,XX @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
14
}
52
}
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)
15
}
196
}
16
197
17
-static bool is_singlestepping(DisasContext *s)
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)
18
-{
213
-{
19
- /*
214
- tcg_out32(s, RDY | INSN_RD(rd));
20
- * Return true if we are singlestepping either because of
21
- * architectural singlestep or QEMU gdbstub singlestep. This does
22
- * not include the command line '-singlestep' mode which is rather
23
- * misnamed as it only means "one instruction per TB" and doesn't
24
- * affect the code we generate.
25
- */
26
- return s->base.singlestep_enabled || s->ss_active;
27
-}
215
-}
28
-
216
-
29
/* is_jmp field values */
217
static void tcg_out_div32(TCGContext *s, TCGReg rd, TCGReg rs1,
30
#define DISAS_JUMP DISAS_TARGET_0 /* only pc was modified dynamically */
218
int32_t val2, int val2const, int uns)
31
#define DISAS_EXIT DISAS_TARGET_1 /* cpu state was modified dynamically */
219
{
32
@@ -XXX,XX +XXX,XX @@ static void gen_exception(DisasContext *s, uint32_t dest, int nr)
220
@@ -XXX,XX +XXX,XX @@ static void emit_extend(TCGContext *s, TCGReg r, int op)
33
s->base.is_jmp = DISAS_NORETURN;
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 */
34
}
475
}
35
476
36
-static void gen_singlestep_exception(DisasContext *s)
477
-#if SPARC64
37
-{
478
-# define ELF_HOST_MACHINE EM_SPARCV9
38
- /*
479
-#else
39
- * Generate the right kind of exception for singlestep, which is
480
-# define ELF_HOST_MACHINE EM_SPARC32PLUS
40
- * either the architectural singlestep or EXCP_DEBUG for QEMU's
481
-# define ELF_HOST_FLAGS EF_SPARC_32PLUS
41
- * gdb singlestepping.
482
-#endif
42
- */
483
+#define ELF_HOST_MACHINE EM_SPARCV9
43
- if (s->ss_active) {
484
44
- gen_raise_exception(EXCP_TRACE);
485
typedef struct {
45
- } else {
486
DebugFrameHeader h;
46
- gen_raise_exception(EXCP_DEBUG);
487
- uint8_t fde_def_cfa[SPARC64 ? 4 : 2];
47
- }
488
+ uint8_t fde_def_cfa[4];
48
-}
489
uint8_t fde_win_save;
49
-
490
uint8_t fde_ret_save[3];
50
static inline void gen_addr_fault(DisasContext *s)
491
} DebugFrame;
51
{
492
@@ -XXX,XX +XXX,XX @@ static const DebugFrame debug_frame = {
52
gen_exception(s, s->base.pc_next, EXCP_ADDRESS);
493
.h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
53
@@ -XXX,XX +XXX,XX @@ static void gen_exit_tb(DisasContext *s)
494
54
/* Generate a jump to an immediate address. */
495
.fde_def_cfa = {
55
static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
496
-#if SPARC64
56
{
497
12, 30, /* DW_CFA_def_cfa i6, 2047 */
57
- if (unlikely(is_singlestepping(s))) {
498
(2047 & 0x7f) | 0x80, (2047 >> 7)
58
+ if (unlikely(s->ss_active)) {
499
-#else
59
update_cc_op(s);
500
- 13, 30 /* DW_CFA_def_cfa_register i6 */
60
tcg_gen_movi_i32(QREG_PC, dest);
501
-#endif
61
- gen_singlestep_exception(s);
502
},
62
+ gen_raise_exception(EXCP_TRACE);
503
.fde_win_save = 0x2d, /* DW_CFA_GNU_window_save */
63
} else if (translator_use_goto_tb(&s->base, dest)) {
504
.fde_ret_save = { 9, 15, 31 }, /* DW_CFA_register o7, i7 */
64
tcg_gen_goto_tb(n);
65
tcg_gen_movi_i32(QREG_PC, dest);
66
@@ -XXX,XX +XXX,XX @@ static void m68k_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
67
68
dc->ss_active = (M68K_SR_TRACE(env->sr) == M68K_SR_TRACE_ANY_INS);
69
/* If architectural single step active, limit to 1 */
70
- if (is_singlestepping(dc)) {
71
+ if (dc->ss_active) {
72
dc->base.max_insns = 1;
73
}
74
}
75
@@ -XXX,XX +XXX,XX @@ static void m68k_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
76
break;
77
case DISAS_TOO_MANY:
78
update_cc_op(dc);
79
- if (is_singlestepping(dc)) {
80
+ if (dc->ss_active) {
81
tcg_gen_movi_i32(QREG_PC, dc->pc);
82
- gen_singlestep_exception(dc);
83
+ gen_raise_exception(EXCP_TRACE);
84
} else {
85
gen_jmp_tb(dc, 0, dc->pc);
86
}
87
break;
88
case DISAS_JUMP:
89
/* We updated CC_OP and PC in gen_jmp/gen_jmp_im. */
90
- if (is_singlestepping(dc)) {
91
- gen_singlestep_exception(dc);
92
+ if (dc->ss_active) {
93
+ gen_raise_exception(EXCP_TRACE);
94
} else {
95
tcg_gen_lookup_and_goto_ptr();
96
}
97
@@ -XXX,XX +XXX,XX @@ static void m68k_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
98
* We updated CC_OP and PC in gen_exit_tb, but also modified
99
* other state that may require returning to the main loop.
100
*/
101
- if (is_singlestepping(dc)) {
102
- gen_singlestep_exception(dc);
103
+ if (dc->ss_active) {
104
+ gen_raise_exception(EXCP_TRACE);
105
} else {
106
tcg_gen_exit_tb(NULL, 0);
107
}
108
--
505
--
109
2.25.1
506
2.34.1
110
507
111
508
diff view generated by jsdifflib
1
This reverts commit 1b36e4f5a5de585210ea95f2257839c2312be28f.
1
Emphasize that we only support full 64-bit code generation.
2
2
3
Despite a comment saying why cpu_common_props cannot be placed in
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
a file that is compiled once, it was moved anyway. Revert that.
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
6
Since then, Property is not defined in hw/core/cpu.h, so it is now
7
easier to declare a function to install the properties rather than
8
the Property array itself.
9
10
Cc: Eduardo Habkost <ehabkost@redhat.com>
11
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
---
6
---
14
include/hw/core/cpu.h | 1 +
7
meson.build | 4 +---
15
cpu.c | 21 +++++++++++++++++++++
8
tcg/{sparc => sparc64}/tcg-target-con-set.h | 0
16
hw/core/cpu-common.c | 17 +----------------
9
tcg/{sparc => sparc64}/tcg-target-con-str.h | 0
17
3 files changed, 23 insertions(+), 16 deletions(-)
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
18
19
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
19
diff --git a/meson.build b/meson.build
20
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/core/cpu.h
21
--- a/meson.build
22
+++ b/include/hw/core/cpu.h
22
+++ b/meson.build
23
@@ -XXX,XX +XXX,XX @@ void QEMU_NORETURN cpu_abort(CPUState *cpu, const char *fmt, ...)
23
@@ -XXX,XX +XXX,XX @@ qapi_trace_events = []
24
GCC_FMT_ATTR(2, 3);
24
bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin']
25
25
supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
26
/* $(top_srcdir)/cpu.c */
26
supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
27
+void cpu_class_init_props(DeviceClass *dc);
27
- 'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc', 'sparc64']
28
void cpu_exec_initfn(CPUState *cpu);
28
+ 'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc64']
29
void cpu_exec_realizefn(CPUState *cpu, Error **errp);
29
30
void cpu_exec_unrealizefn(CPUState *cpu);
30
cpu = host_machine.cpu_family()
31
diff --git a/cpu.c b/cpu.c
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
32
index XXXXXXX..XXXXXXX 100644
58
index XXXXXXX..XXXXXXX 100644
33
--- a/cpu.c
59
--- a/MAINTAINERS
34
+++ b/cpu.c
60
+++ b/MAINTAINERS
35
@@ -XXX,XX +XXX,XX @@ void cpu_exec_unrealizefn(CPUState *cpu)
61
@@ -XXX,XX +XXX,XX @@ L: qemu-s390x@nongnu.org
36
cpu_list_remove(cpu);
62
37
}
63
SPARC TCG target
38
64
S: Odd Fixes
39
+static Property cpu_common_props[] = {
65
-F: tcg/sparc/
40
+#ifndef CONFIG_USER_ONLY
66
+F: tcg/sparc64/
41
+ /*
67
F: disas/sparc.c
42
+ * Create a memory property for softmmu CPU object,
68
43
+ * so users can wire up its memory. (This can't go in hw/core/cpu.c
69
TCI TCG target
44
+ * because that file is compiled only once for both user-mode
45
+ * and system builds.) The default if no link is set up is to use
46
+ * the system address space.
47
+ */
48
+ DEFINE_PROP_LINK("memory", CPUState, memory, TYPE_MEMORY_REGION,
49
+ MemoryRegion *),
50
+#endif
51
+ DEFINE_PROP_BOOL("start-powered-off", CPUState, start_powered_off, false),
52
+ DEFINE_PROP_END_OF_LIST(),
53
+};
54
+
55
+void cpu_class_init_props(DeviceClass *dc)
56
+{
57
+ device_class_set_props(dc, cpu_common_props);
58
+}
59
+
60
void cpu_exec_initfn(CPUState *cpu)
61
{
62
cpu->as = NULL;
63
diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/core/cpu-common.c
66
+++ b/hw/core/cpu-common.c
67
@@ -XXX,XX +XXX,XX @@ static int64_t cpu_common_get_arch_id(CPUState *cpu)
68
return cpu->cpu_index;
69
}
70
71
-static Property cpu_common_props[] = {
72
-#ifndef CONFIG_USER_ONLY
73
- /* Create a memory property for softmmu CPU object,
74
- * so users can wire up its memory. (This can't go in hw/core/cpu.c
75
- * because that file is compiled only once for both user-mode
76
- * and system builds.) The default if no link is set up is to use
77
- * the system address space.
78
- */
79
- DEFINE_PROP_LINK("memory", CPUState, memory, TYPE_MEMORY_REGION,
80
- MemoryRegion *),
81
-#endif
82
- DEFINE_PROP_BOOL("start-powered-off", CPUState, start_powered_off, false),
83
- DEFINE_PROP_END_OF_LIST(),
84
-};
85
-
86
static void cpu_class_init(ObjectClass *klass, void *data)
87
{
88
DeviceClass *dc = DEVICE_CLASS(klass);
89
@@ -XXX,XX +XXX,XX @@ static void cpu_class_init(ObjectClass *klass, void *data)
90
dc->realize = cpu_common_realizefn;
91
dc->unrealize = cpu_common_unrealizefn;
92
dc->reset = cpu_common_reset;
93
- device_class_set_props(dc, cpu_common_props);
94
+ cpu_class_init_props(dc);
95
/*
96
* Reason: CPUs still need special care by board code: wiring up
97
* IRQs, adding reset handlers, halting non-first CPUs, ...
98
--
70
--
99
2.25.1
71
2.34.1
100
72
101
73
diff view generated by jsdifflib
1
GDB single-stepping is now handled generically.
1
With sparc64 we need not distinguish between registers that
2
can hold 32-bit values and those that can hold 64-bit values.
2
3
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
6
---
5
target/xtensa/translate.c | 25 ++++++++-----------------
7
tcg/sparc64/tcg-target-con-set.h | 16 +----
6
1 file changed, 8 insertions(+), 17 deletions(-)
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(-)
7
11
8
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
12
diff --git a/tcg/sparc64/tcg-target-con-set.h b/tcg/sparc64/tcg-target-con-set.h
9
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
10
--- a/target/xtensa/translate.c
14
--- a/tcg/sparc64/tcg-target-con-set.h
11
+++ b/target/xtensa/translate.c
15
+++ b/tcg/sparc64/tcg-target-con-set.h
12
@@ -XXX,XX +XXX,XX @@ static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot)
16
@@ -XXX,XX +XXX,XX @@
13
if (dc->icount) {
17
*/
14
tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount);
18
C_O0_I1(r)
15
}
19
C_O0_I2(rZ, r)
16
- if (dc->base.singlestep_enabled) {
20
-C_O0_I2(RZ, r)
17
- gen_exception(dc, EXCP_DEBUG);
21
C_O0_I2(rZ, rJ)
18
+ if (dc->op_flags & XTENSA_OP_POSTPROCESS) {
22
-C_O0_I2(RZ, RJ)
19
+ slot = gen_postprocess(dc, slot);
23
-C_O0_I2(sZ, A)
20
+ }
24
-C_O0_I2(SZ, A)
21
+ if (slot >= 0) {
25
-C_O1_I1(r, A)
22
+ tcg_gen_goto_tb(slot);
26
-C_O1_I1(R, A)
23
+ tcg_gen_exit_tb(dc->base.tb, slot);
27
+C_O0_I2(sZ, s)
24
} else {
28
+C_O1_I1(r, s)
25
- if (dc->op_flags & XTENSA_OP_POSTPROCESS) {
29
C_O1_I1(r, r)
26
- slot = gen_postprocess(dc, slot);
30
-C_O1_I1(r, R)
27
- }
31
-C_O1_I1(R, r)
28
- if (slot >= 0) {
32
-C_O1_I1(R, R)
29
- tcg_gen_goto_tb(slot);
33
-C_O1_I2(R, R, R)
30
- tcg_gen_exit_tb(dc->base.tb, slot);
34
+C_O1_I2(r, r, r)
31
- } else {
35
C_O1_I2(r, rZ, rJ)
32
- tcg_gen_exit_tb(NULL, 0);
36
-C_O1_I2(R, RZ, RJ)
33
- }
37
C_O1_I4(r, rZ, rJ, rI, 0)
34
+ tcg_gen_exit_tb(NULL, 0);
38
-C_O1_I4(R, RZ, RJ, RI, 0)
35
}
39
C_O2_I2(r, r, rZ, rJ)
36
dc->base.is_jmp = DISAS_NORETURN;
40
-C_O2_I4(R, R, RZ, RZ, RJ, RI)
37
}
41
C_O2_I4(r, r, rZ, rZ, rJ, rJ)
38
@@ -XXX,XX +XXX,XX @@ static void xtensa_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
42
diff --git a/tcg/sparc64/tcg-target-con-str.h b/tcg/sparc64/tcg-target-con-str.h
39
case DISAS_NORETURN:
43
index XXXXXXX..XXXXXXX 100644
40
break;
44
--- a/tcg/sparc64/tcg-target-con-str.h
41
case DISAS_TOO_MANY:
45
+++ b/tcg/sparc64/tcg-target-con-str.h
42
- if (dc->base.singlestep_enabled) {
46
@@ -XXX,XX +XXX,XX @@
43
- tcg_gen_movi_i32(cpu_pc, dc->pc);
47
* REGS(letter, register_mask)
44
- gen_exception(dc, EXCP_DEBUG);
48
*/
45
- } else {
49
REGS('r', ALL_GENERAL_REGS)
46
- gen_jumpi(dc, dc->pc, 0);
50
-REGS('R', ALL_GENERAL_REGS64)
47
- }
51
REGS('s', ALL_QLDST_REGS)
48
+ gen_jumpi(dc, dc->pc, 0);
52
-REGS('S', ALL_QLDST_REGS64)
49
break;
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
50
default:
227
default:
51
g_assert_not_reached();
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);
52
--
238
--
53
2.25.1
239
2.34.1
54
55
diff view generated by jsdifflib
1
We have already set DISAS_NORETURN in generate_exception,
1
From: Icenowy Zheng <uwu@icenowy.me>
2
which makes the exit_tb unreachable.
3
2
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
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]
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
18
---
7
target/riscv/insn_trans/trans_privileged.c.inc | 6 +-----
19
tcg/tcg.c | 6 +++---
8
1 file changed, 1 insertion(+), 5 deletions(-)
20
1 file changed, 3 insertions(+), 3 deletions(-)
9
21
10
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
22
diff --git a/tcg/tcg.c b/tcg/tcg.c
11
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
12
--- a/target/riscv/insn_trans/trans_privileged.c.inc
24
--- a/tcg/tcg.c
13
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
25
+++ b/tcg/tcg.c
14
@@ -XXX,XX +XXX,XX @@ static bool trans_ecall(DisasContext *ctx, arg_ecall *a)
26
@@ -XXX,XX +XXX,XX @@ static void tcg_context_init(unsigned max_cpus)
15
{
27
16
/* always generates U-level ECALL, fixed in do_interrupt handler */
28
if (nargs != 0) {
17
generate_exception(ctx, RISCV_EXCP_U_ECALL);
29
ca->cif.arg_types = ca->args;
18
- exit_tb(ctx); /* no chaining */
30
- for (i = 0; i < nargs; ++i) {
19
- ctx->base.is_jmp = DISAS_NORETURN;
31
- int typecode = extract32(typemask, (i + 1) * 3, 3);
20
return true;
32
- ca->args[i] = typecode_to_ffi[typecode];
21
}
33
+ for (int j = 0; j < nargs; ++j) {
22
34
+ int typecode = extract32(typemask, (j + 1) * 3, 3);
23
@@ -XXX,XX +XXX,XX @@ static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a)
35
+ ca->args[j] = typecode_to_ffi[typecode];
24
post = opcode_at(&ctx->base, post_addr);
36
}
25
}
37
}
26
27
- if (pre == 0x01f01013 && ebreak == 0x00100073 && post == 0x40705013) {
28
+ if (pre == 0x01f01013 && ebreak == 0x00100073 && post == 0x40705013) {
29
generate_exception(ctx, RISCV_EXCP_SEMIHOST);
30
} else {
31
generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
32
}
33
- exit_tb(ctx); /* no chaining */
34
- ctx->base.is_jmp = DISAS_NORETURN;
35
return true;
36
}
37
38
38
--
39
--
39
2.25.1
40
2.34.1
40
41
41
42
diff view generated by jsdifflib
1
GDB single-stepping is now handled generically, which means
1
Add a way to examine the unwind data without actually
2
we don't need to do anything in the wrappers.
2
restoring the data back into env.
3
3
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
4
Reviewed-by: Claudio Fontana <cfontana@suse.de>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
6
---
7
target/riscv/translate.c | 27 +------------------
7
accel/tcg/internal.h | 4 +--
8
.../riscv/insn_trans/trans_privileged.c.inc | 4 +--
8
include/exec/exec-all.h | 21 ++++++++---
9
target/riscv/insn_trans/trans_rvi.c.inc | 8 +++---
9
accel/tcg/translate-all.c | 74 ++++++++++++++++++++++++++-------------
10
target/riscv/insn_trans/trans_rvv.c.inc | 2 +-
10
3 files changed, 68 insertions(+), 31 deletions(-)
11
4 files changed, 7 insertions(+), 34 deletions(-)
12
11
13
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
12
diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
14
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/translate.c
14
--- a/accel/tcg/internal.h
16
+++ b/target/riscv/translate.c
15
+++ b/accel/tcg/internal.h
17
@@ -XXX,XX +XXX,XX @@ static void generate_exception_mtval(DisasContext *ctx, int excp)
16
@@ -XXX,XX +XXX,XX @@ void tb_reset_jump(TranslationBlock *tb, int n);
18
ctx->base.is_jmp = DISAS_NORETURN;
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;
19
}
75
}
20
76
21
-static void gen_exception_debug(void)
77
-/* The cpu state corresponding to 'searched_pc' is restored.
22
-{
78
- * When reset_icount is true, current TB will be interrupted and
23
- gen_helper_raise_exception(cpu_env, tcg_constant_i32(EXCP_DEBUG));
79
- * icount should be recalculated.
24
-}
80
- */
25
-
81
-int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
26
-/* Wrapper around tcg_gen_exit_tb that handles single stepping */
82
- uintptr_t searched_pc, bool reset_icount)
27
-static void exit_tb(DisasContext *ctx)
83
+static int cpu_unwind_data_from_tb(TranslationBlock *tb, uintptr_t host_pc,
28
-{
84
+ uint64_t *data)
29
- if (ctx->base.singlestep_enabled) {
30
- gen_exception_debug();
31
- } else {
32
- tcg_gen_exit_tb(NULL, 0);
33
- }
34
-}
35
-
36
-/* Wrapper around tcg_gen_lookup_and_goto_ptr that handles single stepping */
37
-static void lookup_and_goto_ptr(DisasContext *ctx)
38
-{
39
- if (ctx->base.singlestep_enabled) {
40
- gen_exception_debug();
41
- } else {
42
- tcg_gen_lookup_and_goto_ptr();
43
- }
44
-}
45
-
46
static void gen_exception_illegal(DisasContext *ctx)
47
{
85
{
48
generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
86
- uint64_t data[TARGET_INSN_START_WORDS];
49
@@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
87
- uintptr_t host_pc = (uintptr_t)tb->tc.ptr;
50
tcg_gen_exit_tb(ctx->base.tb, n);
88
+ uintptr_t iter_pc = (uintptr_t)tb->tc.ptr;
51
} else {
89
const uint8_t *p = tb->tc.ptr + tb->tc.size;
52
tcg_gen_movi_tl(cpu_pc, dest);
90
int i, j, num_insns = tb->icount;
53
- lookup_and_goto_ptr(ctx);
91
-#ifdef CONFIG_PROFILER
54
+ tcg_gen_lookup_and_goto_ptr();
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;
55
}
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;
56
}
169
}
57
170
58
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
171
bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit)
59
index XXXXXXX..XXXXXXX 100644
172
@@ -XXX,XX +XXX,XX @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit)
60
--- a/target/riscv/insn_trans/trans_privileged.c.inc
173
return false;
61
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
62
@@ -XXX,XX +XXX,XX @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
63
64
if (has_ext(ctx, RVS)) {
65
gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
66
- exit_tb(ctx); /* no chaining */
67
+ tcg_gen_exit_tb(NULL, 0); /* no chaining */
68
ctx->base.is_jmp = DISAS_NORETURN;
69
} else {
70
return false;
71
@@ -XXX,XX +XXX,XX @@ static bool trans_mret(DisasContext *ctx, arg_mret *a)
72
#ifndef CONFIG_USER_ONLY
73
tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
74
gen_helper_mret(cpu_pc, cpu_env, cpu_pc);
75
- exit_tb(ctx); /* no chaining */
76
+ tcg_gen_exit_tb(NULL, 0); /* no chaining */
77
ctx->base.is_jmp = DISAS_NORETURN;
78
return true;
79
#else
80
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/riscv/insn_trans/trans_rvi.c.inc
83
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
84
@@ -XXX,XX +XXX,XX @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
85
if (a->rd != 0) {
86
tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->pc_succ_insn);
87
}
88
-
89
- /* No chaining with JALR. */
90
- lookup_and_goto_ptr(ctx);
91
+ tcg_gen_lookup_and_goto_ptr();
92
93
if (misaligned) {
94
gen_set_label(misaligned);
95
@@ -XXX,XX +XXX,XX @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
96
* however we need to end the translation block
97
*/
98
tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
99
- exit_tb(ctx);
100
+ tcg_gen_exit_tb(NULL, 0);
101
ctx->base.is_jmp = DISAS_NORETURN;
102
return true;
103
}
174
}
104
@@ -XXX,XX +XXX,XX @@ static bool do_csr_post(DisasContext *ctx)
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)
105
{
188
{
106
/* We may have changed important cpu state -- exit to main loop. */
189
page_size_init();
107
tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
108
- exit_tb(ctx);
109
+ tcg_gen_exit_tb(NULL, 0);
110
ctx->base.is_jmp = DISAS_NORETURN;
111
return true;
112
}
113
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
114
index XXXXXXX..XXXXXXX 100644
115
--- a/target/riscv/insn_trans/trans_rvv.c.inc
116
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
117
@@ -XXX,XX +XXX,XX @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
118
gen_set_gpr(ctx, a->rd, dst);
119
120
tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
121
- lookup_and_goto_ptr(ctx);
122
+ tcg_gen_lookup_and_goto_ptr();
123
ctx->base.is_jmp = DISAS_NORETURN;
124
return true;
125
}
126
--
190
--
127
2.25.1
191
2.34.1
128
129
diff view generated by jsdifflib
1
GDB single-stepping is now handled generically.
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.
2
5
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1269
7
Reviewed-by: Claudio Fontana <cfontana@suse.de>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
9
---
6
target/mips/tcg/translate.c | 50 +++++++++++++------------------------
10
target/i386/helper.c | 21 +++++++++++++++++++--
7
1 file changed, 18 insertions(+), 32 deletions(-)
11
1 file changed, 19 insertions(+), 2 deletions(-)
8
12
9
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
13
diff --git a/target/i386/helper.c b/target/i386/helper.c
10
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
11
--- a/target/mips/tcg/translate.c
15
--- a/target/i386/helper.c
12
+++ b/target/mips/tcg/translate.c
16
+++ b/target/i386/helper.c
13
@@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
17
@@ -XXX,XX +XXX,XX @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
14
tcg_gen_exit_tb(ctx->base.tb, n);
15
} else {
16
gen_save_pc(dest);
17
- if (ctx->base.singlestep_enabled) {
18
- save_cpu_state(ctx, 0);
19
- gen_helper_raise_exception_debug(cpu_env);
20
- } else {
21
- tcg_gen_lookup_and_goto_ptr();
22
- }
23
+ tcg_gen_lookup_and_goto_ptr();
24
}
18
}
25
}
19
}
26
20
27
@@ -XXX,XX +XXX,XX @@ static void gen_branch(DisasContext *ctx, int insn_bytes)
21
+static target_ulong get_memio_eip(CPUX86State *env)
28
} else {
22
+{
29
tcg_gen_mov_tl(cpu_PC, btarget);
23
+ uint64_t data[TARGET_INSN_START_WORDS];
30
}
24
+ CPUState *cs = env_cpu(env);
31
- if (ctx->base.singlestep_enabled) {
25
+
32
- save_cpu_state(ctx, 0);
26
+ if (!cpu_unwind_state_data(cs, cs->mem_io_pc, data)) {
33
- gen_helper_raise_exception_debug(cpu_env);
27
+ return env->eip;
34
- }
28
+ }
35
tcg_gen_lookup_and_goto_ptr();
29
+
36
break;
30
+ /* Per x86_restore_state_to_opc. */
37
default:
31
+ if (TARGET_TB_PCREL) {
38
@@ -XXX,XX +XXX,XX @@ static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
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
{
39
{
40
DisasContext *ctx = container_of(dcbase, DisasContext, base);
40
X86CPU *cpu = env_archcpu(env);
41
41
@@ -XXX,XX +XXX,XX @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
42
- if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
42
43
- save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
43
cpu_interrupt(cs, CPU_INTERRUPT_TPR);
44
- gen_helper_raise_exception_debug(cpu_env);
44
} else if (tcg_enabled()) {
45
- } else {
45
- cpu_restore_state(cs, cs->mem_io_pc, false);
46
- switch (ctx->base.is_jmp) {
46
+ target_ulong eip = get_memio_eip(env);
47
- case DISAS_STOP:
47
48
- gen_save_pc(ctx->base.pc_next);
48
- apic_handle_tpr_access_report(cpu->apic_state, env->eip, access);
49
- tcg_gen_lookup_and_goto_ptr();
49
+ apic_handle_tpr_access_report(cpu->apic_state, eip, access);
50
- break;
51
- case DISAS_NEXT:
52
- case DISAS_TOO_MANY:
53
- save_cpu_state(ctx, 0);
54
- gen_goto_tb(ctx, 0, ctx->base.pc_next);
55
- break;
56
- case DISAS_EXIT:
57
- tcg_gen_exit_tb(NULL, 0);
58
- break;
59
- case DISAS_NORETURN:
60
- break;
61
- default:
62
- g_assert_not_reached();
63
- }
64
+ switch (ctx->base.is_jmp) {
65
+ case DISAS_STOP:
66
+ gen_save_pc(ctx->base.pc_next);
67
+ tcg_gen_lookup_and_goto_ptr();
68
+ break;
69
+ case DISAS_NEXT:
70
+ case DISAS_TOO_MANY:
71
+ save_cpu_state(ctx, 0);
72
+ gen_goto_tb(ctx, 0, ctx->base.pc_next);
73
+ break;
74
+ case DISAS_EXIT:
75
+ tcg_gen_exit_tb(NULL, 0);
76
+ break;
77
+ case DISAS_NORETURN:
78
+ break;
79
+ default:
80
+ g_assert_not_reached();
81
}
50
}
82
}
51
}
83
52
#endif /* !CONFIG_USER_ONLY */
84
--
53
--
85
2.25.1
54
2.34.1
86
87
diff view generated by jsdifflib
1
GDB single-stepping is now handled generically.
1
We have called cpu_restore_state asserting will_exit.
2
Do not go back on that promise. This affects icount.
2
3
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
---
6
target/openrisc/translate.c | 18 +++---------------
7
target/openrisc/sys_helper.c | 2 +-
7
1 file changed, 3 insertions(+), 15 deletions(-)
8
1 file changed, 1 insertion(+), 1 deletion(-)
8
9
9
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
10
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
10
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
11
--- a/target/openrisc/translate.c
12
--- a/target/openrisc/sys_helper.c
12
+++ b/target/openrisc/translate.c
13
+++ b/target/openrisc/sys_helper.c
13
@@ -XXX,XX +XXX,XX @@ static void openrisc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
14
@@ -XXX,XX +XXX,XX @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
14
/* The jump destination is indirect/computed; use jmp_pc. */
15
if (env->pc != rb) {
15
tcg_gen_mov_tl(cpu_pc, jmp_pc);
16
env->pc = rb;
16
tcg_gen_discard_tl(jmp_pc);
17
env->dflag = 0;
17
- if (unlikely(dc->base.singlestep_enabled)) {
18
- cpu_loop_exit(cs);
18
- gen_exception(dc, EXCP_DEBUG);
19
- } else {
20
- tcg_gen_lookup_and_goto_ptr();
21
- }
22
+ tcg_gen_lookup_and_goto_ptr();
23
break;
24
}
19
}
25
/* The jump destination is direct; use jmp_pc_imm.
20
+ cpu_loop_exit(cs);
26
@@ -XXX,XX +XXX,XX @@ static void openrisc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
27
break;
28
}
29
tcg_gen_movi_tl(cpu_pc, jmp_dest);
30
- if (unlikely(dc->base.singlestep_enabled)) {
31
- gen_exception(dc, EXCP_DEBUG);
32
- } else {
33
- tcg_gen_lookup_and_goto_ptr();
34
- }
35
+ tcg_gen_lookup_and_goto_ptr();
36
break;
21
break;
37
22
38
case DISAS_EXIT:
23
case TO_SPR(0, 17): /* SR */
39
- if (unlikely(dc->base.singlestep_enabled)) {
40
- gen_exception(dc, EXCP_DEBUG);
41
- } else {
42
- tcg_gen_exit_tb(NULL, 0);
43
- }
44
+ tcg_gen_exit_tb(NULL, 0);
45
break;
46
default:
47
g_assert_not_reached();
48
--
24
--
49
2.25.1
25
2.34.1
50
26
51
27
diff view generated by jsdifflib
1
GDB single-stepping is now handled generically.
1
Since we do not plan to exit, use cpu_unwind_state_data
2
and extract exactly the data requested.
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!
2
23
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
24
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
25
---
5
target/s390x/tcg/translate.c | 8 ++------
26
target/openrisc/sys_helper.c | 11 +++++++++--
6
1 file changed, 2 insertions(+), 6 deletions(-)
27
1 file changed, 9 insertions(+), 2 deletions(-)
7
28
8
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
29
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
9
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
10
--- a/target/s390x/tcg/translate.c
31
--- a/target/openrisc/sys_helper.c
11
+++ b/target/s390x/tcg/translate.c
32
+++ b/target/openrisc/sys_helper.c
12
@@ -XXX,XX +XXX,XX @@ struct DisasContext {
33
@@ -XXX,XX +XXX,XX @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
13
uint64_t pc_tmp;
34
target_ulong spr)
14
uint32_t ilen;
35
{
15
enum cc_op cc_op;
36
#ifndef CONFIG_USER_ONLY
16
- bool do_debug;
37
+ uint64_t data[TARGET_INSN_START_WORDS];
17
};
38
MachineState *ms = MACHINE(qdev_get_machine());
18
39
OpenRISCCPU *cpu = env_archcpu(env);
19
/* Information carried about a condition to be evaluated. */
40
CPUState *cs = env_cpu(env);
20
@@ -XXX,XX +XXX,XX @@ static void s390x_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
41
@@ -XXX,XX +XXX,XX @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
21
42
return env->evbar;
22
dc->cc_op = CC_OP_DYNAMIC;
43
23
dc->ex_value = dc->base.tb->cs_base;
44
case TO_SPR(0, 16): /* NPC (equals PC) */
24
- dc->do_debug = dc->base.singlestep_enabled;
45
- cpu_restore_state(cs, GETPC(), false);
25
}
46
+ if (cpu_unwind_state_data(cs, GETPC(), data)) {
26
47
+ return data[0];
27
static void s390x_tr_tb_start(DisasContextBase *db, CPUState *cs)
48
+ }
28
@@ -XXX,XX +XXX,XX @@ static void s390x_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
49
return env->pc;
29
/* FALLTHRU */
50
30
case DISAS_PC_CC_UPDATED:
51
case TO_SPR(0, 17): /* SR */
31
/* Exit the TB, either by raising a debug exception or by return. */
52
return cpu_get_sr(env);
32
- if (dc->do_debug) {
53
33
- gen_exception(EXCP_DEBUG);
54
case TO_SPR(0, 18): /* PPC */
34
- } else if ((dc->base.tb->flags & FLAG_MASK_PER) ||
55
- cpu_restore_state(cs, GETPC(), false);
35
- dc->base.is_jmp == DISAS_PC_STALE_NOCHAIN) {
56
+ if (cpu_unwind_state_data(cs, GETPC(), data)) {
36
+ if ((dc->base.tb->flags & FLAG_MASK_PER) ||
57
+ if (data[1] & 2) {
37
+ dc->base.is_jmp == DISAS_PC_STALE_NOCHAIN) {
58
+ return data[0] - 4;
38
tcg_gen_exit_tb(NULL, 0);
59
+ }
39
} else {
60
+ }
40
tcg_gen_lookup_and_goto_ptr();
61
return env->ppc;
62
63
case TO_SPR(0, 32): /* EPCR */
41
--
64
--
42
2.25.1
65
2.34.1
43
44
diff view generated by jsdifflib
1
GDB single-stepping is now handled generically.
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.
2
4
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Claudio Fontana <cfontana@suse.de>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
7
---
6
target/tricore/helper.h | 1 -
8
include/exec/exec-all.h | 5 +----
7
target/tricore/op_helper.c | 7 -------
9
accel/tcg/cpu-exec-common.c | 2 +-
8
target/tricore/translate.c | 14 +-------------
10
accel/tcg/translate-all.c | 12 ++----------
9
3 files changed, 1 insertion(+), 21 deletions(-)
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(-)
10
26
11
diff --git a/target/tricore/helper.h b/target/tricore/helper.h
27
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
12
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
13
--- a/target/tricore/helper.h
29
--- a/include/exec/exec-all.h
14
+++ b/target/tricore/helper.h
30
+++ b/include/exec/exec-all.h
15
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(psw_write, void, env, i32)
31
@@ -XXX,XX +XXX,XX @@ bool cpu_unwind_state_data(CPUState *cpu, uintptr_t host_pc, uint64_t *data);
16
DEF_HELPER_1(psw_read, i32, env)
32
* cpu_restore_state:
17
/* Exceptions */
33
* @cpu: the cpu context
18
DEF_HELPER_3(raise_exception_sync, noreturn, env, i32, i32)
34
* @host_pc: the host pc within the translation
19
-DEF_HELPER_2(qemu_excp, noreturn, env, i32)
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);
20
diff --git a/target/tricore/op_helper.c b/target/tricore/op_helper.c
294
diff --git a/target/tricore/op_helper.c b/target/tricore/op_helper.c
21
index XXXXXXX..XXXXXXX 100644
295
index XXXXXXX..XXXXXXX 100644
22
--- a/target/tricore/op_helper.c
296
--- a/target/tricore/op_helper.c
23
+++ b/target/tricore/op_helper.c
297
+++ b/target/tricore/op_helper.c
24
@@ -XXX,XX +XXX,XX @@ static void raise_exception_sync_helper(CPUTriCoreState *env, uint32_t class,
298
@@ -XXX,XX +XXX,XX @@ void raise_exception_sync_internal(CPUTriCoreState *env, uint32_t class, int tin
25
raise_exception_sync_internal(env, class, tin, pc, 0);
299
{
26
}
300
CPUState *cs = env_cpu(env);
27
301
/* in case we come from a helper-call we need to restore the PC */
28
-void helper_qemu_excp(CPUTriCoreState *env, uint32_t excp)
302
- cpu_restore_state(cs, pc, true);
29
-{
303
+ cpu_restore_state(cs, pc);
30
- CPUState *cs = env_cpu(env);
304
31
- cs->exception_index = excp;
305
/* Tin is loaded into d[15] */
32
- cpu_loop_exit(cs);
306
env->gpr_d[15] = tin;
33
-}
307
diff --git a/target/xtensa/helper.c b/target/xtensa/helper.c
34
-
308
index XXXXXXX..XXXXXXX 100644
35
/* Addressing mode helper */
309
--- a/target/xtensa/helper.c
36
310
+++ b/target/xtensa/helper.c
37
static uint16_t reverse16(uint16_t val)
311
@@ -XXX,XX +XXX,XX @@ void xtensa_cpu_do_unaligned_access(CPUState *cs,
38
diff --git a/target/tricore/translate.c b/target/tricore/translate.c
312
39
index XXXXXXX..XXXXXXX 100644
313
assert(xtensa_option_enabled(env->config,
40
--- a/target/tricore/translate.c
314
XTENSA_OPTION_UNALIGNED_EXCEPTION));
41
+++ b/target/tricore/translate.c
315
- cpu_restore_state(CPU(cpu), retaddr, true);
42
@@ -XXX,XX +XXX,XX @@ static inline void gen_save_pc(target_ulong pc)
316
+ cpu_restore_state(CPU(cpu), retaddr);
43
tcg_gen_movi_tl(cpu_PC, pc);
317
HELPER(exception_cause_vaddr)(env,
44
}
318
env->pc, LOAD_STORE_ALIGNMENT_CAUSE,
45
319
addr);
46
-static void generate_qemu_excp(DisasContext *ctx, int excp)
320
@@ -XXX,XX +XXX,XX @@ bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
47
-{
321
} else if (probe) {
48
- TCGv_i32 tmp = tcg_const_i32(excp);
322
return false;
49
- gen_helper_qemu_excp(cpu_env, tmp);
50
- ctx->base.is_jmp = DISAS_NORETURN;
51
- tcg_temp_free(tmp);
52
-}
53
-
54
static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
55
{
56
if (translator_use_goto_tb(&ctx->base, dest)) {
57
@@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
58
tcg_gen_exit_tb(ctx->base.tb, n);
59
} else {
323
} else {
60
gen_save_pc(dest);
324
- cpu_restore_state(cs, retaddr, true);
61
- if (ctx->base.singlestep_enabled) {
325
+ cpu_restore_state(cs, retaddr);
62
- generate_qemu_excp(ctx, EXCP_DEBUG);
326
HELPER(exception_cause_vaddr)(env, env->pc, ret, address);
63
- } else {
327
}
64
- tcg_gen_lookup_and_goto_ptr();
328
}
65
- }
329
@@ -XXX,XX +XXX,XX @@ void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
66
+ tcg_gen_lookup_and_goto_ptr();
330
XtensaCPU *cpu = XTENSA_CPU(cs);
67
}
331
CPUXtensaState *env = &cpu->env;
68
}
332
69
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 :
70
--
338
--
71
2.25.1
339
2.34.1
72
73
diff view generated by jsdifflib
1
GDB single-stepping is now handled generically.
1
The value passed is always true.
2
2
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Reviewed-by: Claudio Fontana <cfontana@suse.de>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
5
---
6
target/sh4/helper.h | 1 -
6
accel/tcg/internal.h | 2 +-
7
target/sh4/op_helper.c | 5 -----
7
accel/tcg/tb-maint.c | 4 ++--
8
target/sh4/translate.c | 14 +++-----------
8
accel/tcg/translate-all.c | 15 +++++++--------
9
3 files changed, 3 insertions(+), 17 deletions(-)
9
3 files changed, 10 insertions(+), 11 deletions(-)
10
10
11
diff --git a/target/sh4/helper.h b/target/sh4/helper.h
11
diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
12
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/sh4/helper.h
13
--- a/accel/tcg/internal.h
14
+++ b/target/sh4/helper.h
14
+++ b/accel/tcg/internal.h
15
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(raise_illegal_instruction, noreturn, env)
15
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
16
DEF_HELPER_1(raise_slot_illegal_instruction, noreturn, env)
16
tb_page_addr_t phys_page2);
17
DEF_HELPER_1(raise_fpu_disable, noreturn, env)
17
bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc);
18
DEF_HELPER_1(raise_slot_fpu_disable, noreturn, env)
18
void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
19
-DEF_HELPER_1(debug, noreturn, env)
19
- uintptr_t host_pc, bool reset_icount);
20
DEF_HELPER_1(sleep, noreturn, env)
20
+ uintptr_t host_pc);
21
DEF_HELPER_2(trapa, noreturn, env, i32)
21
22
DEF_HELPER_1(exclusive, noreturn, env)
22
/* Return the current PC from CPU, which may be cached in TB. */
23
diff --git a/target/sh4/op_helper.c b/target/sh4/op_helper.c
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
24
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
25
--- a/target/sh4/op_helper.c
26
--- a/accel/tcg/tb-maint.c
26
+++ b/target/sh4/op_helper.c
27
+++ b/accel/tcg/tb-maint.c
27
@@ -XXX,XX +XXX,XX @@ void helper_raise_slot_fpu_disable(CPUSH4State *env)
28
@@ -XXX,XX +XXX,XX @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages,
28
raise_exception(env, 0x820, 0);
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,
29
}
51
}
30
52
31
-void helper_debug(CPUSH4State *env)
53
/*
32
-{
54
- * The cpu state corresponding to 'host_pc' is restored.
33
- raise_exception(env, EXCP_DEBUG, 0);
55
- * When reset_icount is true, current TB will be interrupted and
34
-}
56
- * icount should be recalculated.
35
-
57
+ * The cpu state corresponding to 'host_pc' is restored in
36
void helper_sleep(CPUSH4State *env)
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)
37
{
63
{
38
CPUState *cs = env_cpu(env);
64
uint64_t data[TARGET_INSN_START_WORDS];
39
diff --git a/target/sh4/translate.c b/target/sh4/translate.c
65
#ifdef CONFIG_PROFILER
40
index XXXXXXX..XXXXXXX 100644
66
@@ -XXX,XX +XXX,XX @@ void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
41
--- a/target/sh4/translate.c
67
return;
42
+++ b/target/sh4/translate.c
68
}
43
@@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
69
44
tcg_gen_exit_tb(ctx->base.tb, n);
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);
45
} else {
91
} else {
46
tcg_gen_movi_i32(cpu_pc, dest);
92
/* The exception probably happened in a helper. The CPU state should
47
- if (ctx->base.singlestep_enabled) {
93
@@ -XXX,XX +XXX,XX @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
48
- gen_helper_debug(cpu_env);
94
cpu_abort(cpu, "cpu_io_recompile: could not find TB for pc=%p",
49
- } else if (use_exit_tb(ctx)) {
95
(void *)retaddr);
50
+ if (use_exit_tb(ctx)) {
96
}
51
tcg_gen_exit_tb(NULL, 0);
97
- cpu_restore_state_from_tb(cpu, tb, retaddr, true);
52
} else {
98
+ cpu_restore_state_from_tb(cpu, tb, retaddr);
53
tcg_gen_lookup_and_goto_ptr();
99
54
@@ -XXX,XX +XXX,XX @@ static void gen_jump(DisasContext * ctx)
100
/*
55
     delayed jump as immediate jump are conditinal jumps */
101
* Some guests must re-execute the branch when re-executing a delay
56
    tcg_gen_mov_i32(cpu_pc, cpu_delayed_pc);
57
tcg_gen_discard_i32(cpu_delayed_pc);
58
- if (ctx->base.singlestep_enabled) {
59
- gen_helper_debug(cpu_env);
60
- } else if (use_exit_tb(ctx)) {
61
+ if (use_exit_tb(ctx)) {
62
tcg_gen_exit_tb(NULL, 0);
63
} else {
64
tcg_gen_lookup_and_goto_ptr();
65
@@ -XXX,XX +XXX,XX @@ static void sh4_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
66
switch (ctx->base.is_jmp) {
67
case DISAS_STOP:
68
gen_save_cpu_state(ctx, true);
69
- if (ctx->base.singlestep_enabled) {
70
- gen_helper_debug(cpu_env);
71
- } else {
72
- tcg_gen_exit_tb(NULL, 0);
73
- }
74
+ tcg_gen_exit_tb(NULL, 0);
75
break;
76
case DISAS_NEXT:
77
case DISAS_TOO_MANY:
78
--
102
--
79
2.25.1
103
2.34.1
80
81
diff view generated by jsdifflib
1
GDB single-stepping is now handled generically.
1
The helpers for reset_rf, cli, sti, clac, stac are
2
completely trivial; implement them inline.
2
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>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
9
---
5
target/i386/helper.h | 1 -
10
target/i386/helper.h | 5 -----
6
target/i386/tcg/misc_helper.c | 8 --------
11
target/i386/tcg/cc_helper.c | 41 -------------------------------------
7
target/i386/tcg/translate.c | 4 +---
12
target/i386/tcg/translate.c | 30 ++++++++++++++++++++++-----
8
3 files changed, 1 insertion(+), 12 deletions(-)
13
3 files changed, 25 insertions(+), 51 deletions(-)
9
14
10
diff --git a/target/i386/helper.h b/target/i386/helper.h
15
diff --git a/target/i386/helper.h b/target/i386/helper.h
11
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
12
--- a/target/i386/helper.h
17
--- a/target/i386/helper.h
13
+++ b/target/i386/helper.h
18
+++ b/target/i386/helper.h
14
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(syscall, void, env, int)
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(syscall, void, env, int)
15
DEF_HELPER_2(sysret, void, env, int)
20
DEF_HELPER_2(sysret, void, env, int)
16
#endif
21
#endif
17
DEF_HELPER_FLAGS_2(pause, TCG_CALL_NO_WG, noreturn, env, int)
22
DEF_HELPER_FLAGS_2(pause, TCG_CALL_NO_WG, noreturn, env, int)
18
-DEF_HELPER_FLAGS_1(debug, TCG_CALL_NO_WG, noreturn, env)
23
-DEF_HELPER_1(reset_rf, void, env)
19
DEF_HELPER_1(reset_rf, void, env)
20
DEF_HELPER_FLAGS_3(raise_interrupt, TCG_CALL_NO_WG, noreturn, env, int, int)
24
DEF_HELPER_FLAGS_3(raise_interrupt, TCG_CALL_NO_WG, noreturn, env, int, int)
21
DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_WG, noreturn, env, int)
25
DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_WG, noreturn, env, int)
22
diff --git a/target/i386/tcg/misc_helper.c b/target/i386/tcg/misc_helper.c
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
23
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
24
--- a/target/i386/tcg/misc_helper.c
35
--- a/target/i386/tcg/cc_helper.c
25
+++ b/target/i386/tcg/misc_helper.c
36
+++ b/target/i386/tcg/cc_helper.c
26
@@ -XXX,XX +XXX,XX @@ void QEMU_NORETURN helper_pause(CPUX86State *env, int next_eip_addend)
37
@@ -XXX,XX +XXX,XX @@ void helper_clts(CPUX86State *env)
27
do_pause(env);
38
env->cr[0] &= ~CR0_TS_MASK;
39
env->hflags &= ~HF_TS_MASK;
28
}
40
}
29
41
-
30
-void QEMU_NORETURN helper_debug(CPUX86State *env)
42
-void helper_reset_rf(CPUX86State *env)
31
-{
43
-{
32
- CPUState *cs = env_cpu(env);
44
- env->eflags &= ~RF_MASK;
33
-
34
- cs->exception_index = EXCP_DEBUG;
35
- cpu_loop_exit(cs);
36
-}
45
-}
37
-
46
-
38
uint64_t helper_rdpkru(CPUX86State *env, uint32_t ecx)
47
-void helper_cli(CPUX86State *env)
39
{
48
-{
40
if ((env->cr[4] & CR4_PKE_MASK) == 0) {
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
41
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
82
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
42
index XXXXXXX..XXXXXXX 100644
83
index XXXXXXX..XXXXXXX 100644
43
--- a/target/i386/tcg/translate.c
84
--- a/target/i386/tcg/translate.c
44
+++ b/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
{
45
@@ -XXX,XX +XXX,XX @@ do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr)
113
@@ -XXX,XX +XXX,XX @@ do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr)
114
}
115
46
if (s->base.tb->flags & HF_RF_MASK) {
116
if (s->base.tb->flags & HF_RF_MASK) {
47
gen_helper_reset_rf(cpu_env);
117
- gen_helper_reset_rf(cpu_env);
118
+ gen_reset_eflags(s, RF_MASK);
48
}
119
}
49
- if (s->base.singlestep_enabled) {
120
if (recheck_tf) {
50
- gen_helper_debug(cpu_env);
51
- } else if (recheck_tf) {
52
+ if (recheck_tf) {
53
gen_helper_rechecking_single_step(cpu_env);
121
gen_helper_rechecking_single_step(cpu_env);
54
tcg_gen_exit_tb(NULL, 0);
122
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
55
} else if (s->flags & HF_TF_MASK) {
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
56
--
155
--
57
2.25.1
156
2.34.1
58
157
59
158
diff view generated by jsdifflib
Deleted patch
1
We were using singlestep_enabled as a proxy for whether
2
translator_use_goto_tb would always return false.
3
1
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
target/microblaze/translate.c | 4 ++--
7
1 file changed, 2 insertions(+), 2 deletions(-)
8
9
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/target/microblaze/translate.c
12
+++ b/target/microblaze/translate.c
13
@@ -XXX,XX +XXX,XX @@ static void mb_tr_tb_stop(DisasContextBase *dcb, CPUState *cs)
14
break;
15
16
case DISAS_JUMP:
17
- if (dc->jmp_dest != -1 && !cs->singlestep_enabled) {
18
+ if (dc->jmp_dest != -1 && !(tb_cflags(dc->base.tb) & CF_NO_GOTO_TB)) {
19
/* Direct jump. */
20
tcg_gen_discard_i32(cpu_btarget);
21
22
@@ -XXX,XX +XXX,XX @@ static void mb_tr_tb_stop(DisasContextBase *dcb, CPUState *cs)
23
return;
24
}
25
26
- /* Indirect jump (or direct jump w/ singlestep) */
27
+ /* Indirect jump (or direct jump w/ goto_tb disabled) */
28
tcg_gen_mov_i32(cpu_pc, cpu_btarget);
29
tcg_gen_discard_i32(cpu_btarget);
30
31
--
32
2.25.1
33
34
diff view generated by jsdifflib
Deleted patch
1
GDB single-stepping is now handled generically.
2
1
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
5
target/microblaze/translate.c | 14 ++------------
6
1 file changed, 2 insertions(+), 12 deletions(-)
7
8
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
9
index XXXXXXX..XXXXXXX 100644
10
--- a/target/microblaze/translate.c
11
+++ b/target/microblaze/translate.c
12
@@ -XXX,XX +XXX,XX @@ static void gen_raise_hw_excp(DisasContext *dc, uint32_t esr_ec)
13
14
static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
15
{
16
- if (dc->base.singlestep_enabled) {
17
- TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
18
- tcg_gen_movi_i32(cpu_pc, dest);
19
- gen_helper_raise_exception(cpu_env, tmp);
20
- tcg_temp_free_i32(tmp);
21
- } else if (translator_use_goto_tb(&dc->base, dest)) {
22
+ if (translator_use_goto_tb(&dc->base, dest)) {
23
tcg_gen_goto_tb(n);
24
tcg_gen_movi_i32(cpu_pc, dest);
25
tcg_gen_exit_tb(dc->base.tb, n);
26
@@ -XXX,XX +XXX,XX @@ static void mb_tr_tb_stop(DisasContextBase *dcb, CPUState *cs)
27
/* Indirect jump (or direct jump w/ goto_tb disabled) */
28
tcg_gen_mov_i32(cpu_pc, cpu_btarget);
29
tcg_gen_discard_i32(cpu_btarget);
30
-
31
- if (unlikely(cs->singlestep_enabled)) {
32
- gen_raise_exception(dc, EXCP_DEBUG);
33
- } else {
34
- tcg_gen_lookup_and_goto_ptr();
35
- }
36
+ tcg_gen_lookup_and_goto_ptr();
37
return;
38
39
default:
40
--
41
2.25.1
42
43
diff view generated by jsdifflib
Deleted patch
1
As per an ancient comment in mips_tr_translate_insn about the
2
expectations of gdb, when restarting the insn in a delay slot
3
we also re-execute the branch. Which means that we are
4
expected to execute two insns in this case.
5
1
6
This has been broken since 8b86d6d2580, where we forced max_insns
7
to 1 while single-stepping. This resulted in an exit from the
8
translator loop after the branch but before the delay slot is
9
translated.
10
11
Increase the max_insns to 2 for this case. In addition, bypass
12
the end-of-page check, for when the branch itself ends the page.
13
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
---
17
target/mips/tcg/translate.c | 25 ++++++++++++++++---------
18
1 file changed, 16 insertions(+), 9 deletions(-)
19
20
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/mips/tcg/translate.c
23
+++ b/target/mips/tcg/translate.c
24
@@ -XXX,XX +XXX,XX @@ static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
25
ctx->default_tcg_memop_mask = (ctx->insn_flags & (ISA_MIPS_R6 |
26
INSN_LOONGSON3A)) ? MO_UNALN : MO_ALIGN;
27
28
+ /*
29
+ * Execute a branch and its delay slot as a single instruction.
30
+ * This is what GDB expects and is consistent with what the
31
+ * hardware does (e.g. if a delay slot instruction faults, the
32
+ * reported PC is the PC of the branch).
33
+ */
34
+ if (ctx->base.singlestep_enabled && (ctx->hflags & MIPS_HFLAG_BMASK)) {
35
+ ctx->base.max_insns = 2;
36
+ }
37
+
38
LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
39
ctx->hflags);
40
}
41
@@ -XXX,XX +XXX,XX @@ static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
42
if (ctx->base.is_jmp != DISAS_NEXT) {
43
return;
44
}
45
+
46
/*
47
- * Execute a branch and its delay slot as a single instruction.
48
- * This is what GDB expects and is consistent with what the
49
- * hardware does (e.g. if a delay slot instruction faults, the
50
- * reported PC is the PC of the branch).
51
+ * End the TB on (most) page crossings.
52
+ * See mips_tr_init_disas_context about single-stepping a branch
53
+ * together with its delay slot.
54
*/
55
- if (ctx->base.singlestep_enabled &&
56
- (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
57
- ctx->base.is_jmp = DISAS_TOO_MANY;
58
- }
59
- if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
60
+ if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE
61
+ && !ctx->base.singlestep_enabled) {
62
ctx->base.is_jmp = DISAS_TOO_MANY;
63
}
64
}
65
--
66
2.25.1
67
68
diff view generated by jsdifflib
Deleted patch
1
GDB single-stepping is now handled generically.
2
Reuse gen_debug_exception to handle architectural debug exceptions.
3
1
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
target/ppc/translate.c | 38 ++++++++------------------------------
7
1 file changed, 8 insertions(+), 30 deletions(-)
8
9
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/target/ppc/translate.c
12
+++ b/target/ppc/translate.c
13
@@ -XXX,XX +XXX,XX @@
14
15
#define CPU_SINGLE_STEP 0x1
16
#define CPU_BRANCH_STEP 0x2
17
-#define GDBSTUB_SINGLE_STEP 0x4
18
19
/* Include definitions for instructions classes and implementations flags */
20
/* #define PPC_DEBUG_DISAS */
21
@@ -XXX,XX +XXX,XX @@ static uint32_t gen_prep_dbgex(DisasContext *ctx)
22
23
static void gen_debug_exception(DisasContext *ctx)
24
{
25
- gen_helper_raise_exception(cpu_env, tcg_constant_i32(EXCP_DEBUG));
26
+ gen_helper_raise_exception(cpu_env, tcg_constant_i32(gen_prep_dbgex(ctx)));
27
ctx->base.is_jmp = DISAS_NORETURN;
28
}
29
30
@@ -XXX,XX +XXX,XX @@ static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
31
32
static void gen_lookup_and_goto_ptr(DisasContext *ctx)
33
{
34
- int sse = ctx->singlestep_enabled;
35
- if (unlikely(sse)) {
36
- if (sse & GDBSTUB_SINGLE_STEP) {
37
- gen_debug_exception(ctx);
38
- } else if (sse & (CPU_SINGLE_STEP | CPU_BRANCH_STEP)) {
39
- gen_helper_raise_exception(cpu_env, tcg_constant_i32(gen_prep_dbgex(ctx)));
40
- } else {
41
- tcg_gen_exit_tb(NULL, 0);
42
- }
43
+ if (unlikely(ctx->singlestep_enabled)) {
44
+ gen_debug_exception(ctx);
45
} else {
46
tcg_gen_lookup_and_goto_ptr();
47
}
48
@@ -XXX,XX +XXX,XX @@ static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
49
ctx->singlestep_enabled = 0;
50
if ((hflags >> HFLAGS_SE) & 1) {
51
ctx->singlestep_enabled |= CPU_SINGLE_STEP;
52
+ ctx->base.max_insns = 1;
53
}
54
if ((hflags >> HFLAGS_BE) & 1) {
55
ctx->singlestep_enabled |= CPU_BRANCH_STEP;
56
}
57
- if (unlikely(ctx->base.singlestep_enabled)) {
58
- ctx->singlestep_enabled |= GDBSTUB_SINGLE_STEP;
59
- }
60
-
61
- if (ctx->singlestep_enabled & (CPU_SINGLE_STEP | GDBSTUB_SINGLE_STEP)) {
62
- ctx->base.max_insns = 1;
63
- }
64
}
65
66
static void ppc_tr_tb_start(DisasContextBase *db, CPUState *cs)
67
@@ -XXX,XX +XXX,XX @@ static void ppc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
68
DisasContext *ctx = container_of(dcbase, DisasContext, base);
69
DisasJumpType is_jmp = ctx->base.is_jmp;
70
target_ulong nip = ctx->base.pc_next;
71
- int sse;
72
73
if (is_jmp == DISAS_NORETURN) {
74
/* We have already exited the TB. */
75
@@ -XXX,XX +XXX,XX @@ static void ppc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
76
}
77
78
/* Honor single stepping. */
79
- sse = ctx->singlestep_enabled & (CPU_SINGLE_STEP | GDBSTUB_SINGLE_STEP);
80
- if (unlikely(sse)) {
81
+ if (unlikely(ctx->singlestep_enabled & CPU_SINGLE_STEP)
82
+ && (nip <= 0x100 || nip > 0xf00)) {
83
switch (is_jmp) {
84
case DISAS_TOO_MANY:
85
case DISAS_EXIT_UPDATE:
86
@@ -XXX,XX +XXX,XX @@ static void ppc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
87
g_assert_not_reached();
88
}
89
90
- if (sse & GDBSTUB_SINGLE_STEP) {
91
- gen_debug_exception(ctx);
92
- return;
93
- }
94
- /* else CPU_SINGLE_STEP... */
95
- if (nip <= 0x100 || nip > 0xf00) {
96
- gen_helper_raise_exception(cpu_env, tcg_constant_i32(gen_prep_dbgex(ctx)));
97
- return;
98
- }
99
+ gen_debug_exception(ctx);
100
+ return;
101
}
102
103
switch (is_jmp) {
104
--
105
2.25.1
106
107
diff view generated by jsdifflib
Deleted patch
1
GDB single-stepping is now handled generically.
2
1
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
target/rx/helper.h | 1 -
7
target/rx/op_helper.c | 8 --------
8
target/rx/translate.c | 12 ++----------
9
3 files changed, 2 insertions(+), 19 deletions(-)
10
11
diff --git a/target/rx/helper.h b/target/rx/helper.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/rx/helper.h
14
+++ b/target/rx/helper.h
15
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(raise_illegal_instruction, noreturn, env)
16
DEF_HELPER_1(raise_access_fault, noreturn, env)
17
DEF_HELPER_1(raise_privilege_violation, noreturn, env)
18
DEF_HELPER_1(wait, noreturn, env)
19
-DEF_HELPER_1(debug, noreturn, env)
20
DEF_HELPER_2(rxint, noreturn, env, i32)
21
DEF_HELPER_1(rxbrk, noreturn, env)
22
DEF_HELPER_FLAGS_3(fadd, TCG_CALL_NO_WG, f32, env, f32, f32)
23
diff --git a/target/rx/op_helper.c b/target/rx/op_helper.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/rx/op_helper.c
26
+++ b/target/rx/op_helper.c
27
@@ -XXX,XX +XXX,XX @@ void QEMU_NORETURN helper_wait(CPURXState *env)
28
raise_exception(env, EXCP_HLT, 0);
29
}
30
31
-void QEMU_NORETURN helper_debug(CPURXState *env)
32
-{
33
- CPUState *cs = env_cpu(env);
34
-
35
- cs->exception_index = EXCP_DEBUG;
36
- cpu_loop_exit(cs);
37
-}
38
-
39
void QEMU_NORETURN helper_rxint(CPURXState *env, uint32_t vec)
40
{
41
raise_exception(env, 0x100 + vec, 0);
42
diff --git a/target/rx/translate.c b/target/rx/translate.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/rx/translate.c
45
+++ b/target/rx/translate.c
46
@@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
47
tcg_gen_exit_tb(dc->base.tb, n);
48
} else {
49
tcg_gen_movi_i32(cpu_pc, dest);
50
- if (dc->base.singlestep_enabled) {
51
- gen_helper_debug(cpu_env);
52
- } else {
53
- tcg_gen_lookup_and_goto_ptr();
54
- }
55
+ tcg_gen_lookup_and_goto_ptr();
56
}
57
dc->base.is_jmp = DISAS_NORETURN;
58
}
59
@@ -XXX,XX +XXX,XX @@ static void rx_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
60
gen_goto_tb(ctx, 0, dcbase->pc_next);
61
break;
62
case DISAS_JUMP:
63
- if (ctx->base.singlestep_enabled) {
64
- gen_helper_debug(cpu_env);
65
- } else {
66
- tcg_gen_lookup_and_goto_ptr();
67
- }
68
+ tcg_gen_lookup_and_goto_ptr();
69
break;
70
case DISAS_UPDATE:
71
tcg_gen_movi_i32(cpu_pc, ctx->base.pc_next);
72
--
73
2.25.1
74
75
diff view generated by jsdifflib