1
The following changes since commit 7a1dc45af581d2b643cdbf33c01fd96271616fbd:
1
The following changes since commit aa3a285b5bc56a4208b3b57d4a55291e9c260107:
2
2
3
Merge tag 'pull-target-arm-20240126' of https://git.linaro.org/people/pmaydell/qemu-arm into staging (2024-01-26 18:16:35 +0000)
3
Merge tag 'mem-2024-12-21' of https://github.com/davidhildenbrand/qemu into staging (2024-12-22 14:33:27 -0500)
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-20240130
7
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20241224
8
8
9
for you to fetch changes up to ec1d32af123e7f13d98754a72bcaa7aa8c8e9d27:
9
for you to fetch changes up to e4a8e093dc74be049f4829831dce76e5edab0003:
10
10
11
target/i386: Extract x86_cpu_exec_halt() from accel/tcg/ (2024-01-29 21:04:10 +1000)
11
accel/tcg: Move gen_intermediate_code to TCGCPUOps.translate_core (2024-12-24 08:32:15 -0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
linux-user: Allow gdbstub to ignore page protection
14
tcg/optimize: Remove in-flight mask data from OptContext
15
cpu-exec: simplify jump cache management
15
fpu: Add float*_muladd_scalbn
16
include/exec: Cleanups toward building accel/tcg once
16
fpu: Remove float_muladd_halve_result
17
fpu: Add float_round_nearest_even_max
18
fpu: Add float_muladd_suppress_add_product_zero
19
target/hexagon: Use float32_muladd
20
accel/tcg: Move gen_intermediate_code to TCGCPUOps.translate_core
17
21
18
----------------------------------------------------------------
22
----------------------------------------------------------------
19
Anton Johansson (9):
23
Ilya Leoshkevich (1):
20
include/exec: Move vaddr defines to separate file
24
tests/tcg: Do not use inttypes.h in multiarch/system/memory.c
21
hw/core: Include vaddr.h from cpu.h
22
target: Use vaddr in gen_intermediate_code
23
include/exec: Use vaddr in DisasContextBase for virtual addresses
24
include/exec: typedef abi_ptr to vaddr
25
include/exec: Move PAGE_* macros to common header
26
include/exec: Move cpu_*()/cpu_env() to common header
27
include/hw/core: Move do_interrupt in TCGCPUOps
28
include/hw/core: Remove i386 conditional on fake_user_interrupt
29
25
30
Ilya Leoshkevich (8):
26
Pierrick Bouvier (1):
31
linux-user: Allow gdbstub to ignore page protection
27
plugins: optimize cpu_index code generation
32
tests/tcg: Factor out gdbstub test functions
33
tests/tcg: Add the PROT_NONE gdbstub test
34
target: Make qemu_target_page_mask() available for *-user
35
accel/tcg: Make use of qemu_target_page_mask() in perf.c
36
tcg: Make tb_cflags() usable from target-agnostic code
37
accel/tcg: Remove #ifdef TARGET_I386 from perf.c
38
accel/tcg: Move perf and debuginfo support to tcg/
39
28
40
Paolo Bonzini (1):
29
Richard Henderson (70):
41
cpu-exec: simplify jump cache management
30
tcg/optimize: Split out finish_bb, finish_ebb
31
tcg/optimize: Split out fold_affected_mask
32
tcg/optimize: Copy mask writeback to fold_masks
33
tcg/optimize: Split out fold_masks_zs
34
tcg/optimize: Augment s_mask from z_mask in fold_masks_zs
35
tcg/optimize: Change representation of s_mask
36
tcg/optimize: Use finish_folding in fold_add, fold_add_vec, fold_addsub2
37
tcg/optimize: Introduce const value accessors for TempOptInfo
38
tcg/optimize: Use fold_masks_zs in fold_and
39
tcg/optimize: Use fold_masks_zs in fold_andc
40
tcg/optimize: Use fold_masks_zs in fold_bswap
41
tcg/optimize: Use fold_masks_zs in fold_count_zeros
42
tcg/optimize: Use fold_masks_z in fold_ctpop
43
tcg/optimize: Use fold_and and fold_masks_z in fold_deposit
44
tcg/optimize: Compute sign mask in fold_deposit
45
tcg/optimize: Use finish_folding in fold_divide
46
tcg/optimize: Use finish_folding in fold_dup, fold_dup2
47
tcg/optimize: Use fold_masks_s in fold_eqv
48
tcg/optimize: Use fold_masks_z in fold_extract
49
tcg/optimize: Use finish_folding in fold_extract2
50
tcg/optimize: Use fold_masks_zs in fold_exts
51
tcg/optimize: Use fold_masks_z in fold_extu
52
tcg/optimize: Use fold_masks_zs in fold_movcond
53
tcg/optimize: Use finish_folding in fold_mul*
54
tcg/optimize: Use fold_masks_s in fold_nand
55
tcg/optimize: Use fold_masks_z in fold_neg_no_const
56
tcg/optimize: Use fold_masks_s in fold_nor
57
tcg/optimize: Use fold_masks_s in fold_not
58
tcg/optimize: Use fold_masks_zs in fold_or
59
tcg/optimize: Use fold_masks_zs in fold_orc
60
tcg/optimize: Use fold_masks_zs in fold_qemu_ld
61
tcg/optimize: Return true from fold_qemu_st, fold_tcg_st
62
tcg/optimize: Use finish_folding in fold_remainder
63
tcg/optimize: Distinguish simplification in fold_setcond_zmask
64
tcg/optimize: Use fold_masks_z in fold_setcond
65
tcg/optimize: Use fold_masks_s in fold_negsetcond
66
tcg/optimize: Use fold_masks_z in fold_setcond2
67
tcg/optimize: Use finish_folding in fold_cmp_vec
68
tcg/optimize: Use finish_folding in fold_cmpsel_vec
69
tcg/optimize: Use fold_masks_zs in fold_sextract
70
tcg/optimize: Use fold_masks_zs, fold_masks_s in fold_shift
71
tcg/optimize: Simplify sign bit test in fold_shift
72
tcg/optimize: Use finish_folding in fold_sub, fold_sub_vec
73
tcg/optimize: Use fold_masks_zs in fold_tcg_ld
74
tcg/optimize: Use finish_folding in fold_tcg_ld_memcopy
75
tcg/optimize: Use fold_masks_zs in fold_xor
76
tcg/optimize: Use finish_folding in fold_bitsel_vec
77
tcg/optimize: Use finish_folding as default in tcg_optimize
78
tcg/optimize: Remove z_mask, s_mask from OptContext
79
tcg/optimize: Re-enable sign-mask optimizations
80
tcg/optimize: Move fold_bitsel_vec into alphabetic sort
81
tcg/optimize: Move fold_cmp_vec, fold_cmpsel_vec into alphabetic sort
82
softfloat: Add float{16,32,64}_muladd_scalbn
83
target/arm: Use float*_muladd_scalbn
84
target/sparc: Use float*_muladd_scalbn
85
softfloat: Remove float_muladd_halve_result
86
softfloat: Add float_round_nearest_even_max
87
softfloat: Add float_muladd_suppress_add_product_zero
88
target/hexagon: Use float32_mul in helper_sfmpy
89
target/hexagon: Use float32_muladd for helper_sffma
90
target/hexagon: Use float32_muladd for helper_sffms
91
target/hexagon: Use float32_muladd_scalbn for helper_sffma_sc
92
target/hexagon: Use float32_muladd for helper_sffm[as]_lib
93
target/hexagon: Remove internal_fmafx
94
target/hexagon: Expand GEN_XF_ROUND
95
target/hexagon: Remove Float
96
target/hexagon: Remove Double
97
target/hexagon: Use mulu64 for int128_mul_6464
98
target/hexagon: Simplify internal_mpyhh setup
99
accel/tcg: Move gen_intermediate_code to TCGCPUOps.translate_core
42
100
43
Philippe Mathieu-Daudé (9):
101
include/exec/translator.h | 14 -
44
accel/tcg/cpu-exec: Use RCU_READ_LOCK_GUARD
102
include/fpu/softfloat-types.h | 2 +
45
accel/tcg: Rename tcg_ss[] -> tcg_specific_ss[] in meson
103
include/fpu/softfloat.h | 14 +-
46
accel/tcg: Rename tcg_cpus_destroy() -> tcg_cpu_destroy()
104
include/hw/core/tcg-cpu-ops.h | 13 +
47
accel/tcg: Rename tcg_cpus_exec() -> tcg_cpu_exec()
105
target/alpha/cpu.h | 2 +
48
accel/tcg: Un-inline icount_exit_request() for clarity
106
target/arm/internals.h | 2 +
49
accel/tcg: Introduce TCGCPUOps::need_replay_interrupt() handler
107
target/avr/cpu.h | 2 +
50
target/i386: Extract x86_need_replay_interrupt() from accel/tcg/
108
target/hexagon/cpu.h | 2 +
51
accel/tcg: Introduce TCGCPUOps::cpu_exec_halt() handler
109
target/hexagon/fma_emu.h | 3 -
52
target/i386: Extract x86_cpu_exec_halt() from accel/tcg/
110
target/hppa/cpu.h | 2 +
53
111
target/i386/tcg/helper-tcg.h | 2 +
54
Richard Henderson (4):
112
target/loongarch/internals.h | 2 +
55
include/qemu: Add TCGCPUOps typedef to typedefs.h
113
target/m68k/cpu.h | 2 +
56
target/loongarch: Constify loongarch_tcg_ops
114
target/microblaze/cpu.h | 2 +
57
accel/tcg: Use CPUState.cc instead of CPU_GET_CLASS in cpu-exec.c
115
target/mips/tcg/tcg-internal.h | 2 +
58
accel/tcg: Inline need_replay_interrupt
116
target/openrisc/cpu.h | 2 +
59
117
target/ppc/cpu.h | 2 +
60
accel/tcg/tb-jmp-cache.h | 8 +-
118
target/riscv/cpu.h | 3 +
61
accel/tcg/tcg-accel-ops.h | 4 +-
119
target/rx/cpu.h | 2 +
62
include/exec/cpu-all.h | 49 -----
120
target/s390x/s390x-internal.h | 2 +
63
include/exec/cpu-common.h | 69 +++++--
121
target/sh4/cpu.h | 2 +
64
include/exec/cpu_ldst.h | 4 +-
122
target/sparc/cpu.h | 2 +
65
include/exec/exec-all.h | 6 -
123
target/sparc/helper.h | 4 +-
66
include/exec/translation-block.h | 6 +
124
target/tricore/cpu.h | 2 +
67
include/exec/translator.h | 8 +-
125
target/xtensa/cpu.h | 2 +
68
include/exec/vaddr.h | 18 ++
126
accel/tcg/cpu-exec.c | 8 +-
69
include/hw/core/cpu.h | 7 +-
127
accel/tcg/plugin-gen.c | 9 +
70
include/hw/core/tcg-cpu-ops.h | 19 +-
128
accel/tcg/translate-all.c | 8 +-
71
include/qemu/typedefs.h | 1 +
129
fpu/softfloat.c | 63 +--
72
{accel => include}/tcg/debuginfo.h | 4 +-
130
target/alpha/cpu.c | 1 +
73
{accel => include}/tcg/perf.h | 4 +-
131
target/alpha/translate.c | 4 +-
74
target/i386/tcg/helper-tcg.h | 2 +
132
target/arm/cpu.c | 1 +
75
target/mips/tcg/translate.h | 3 +-
133
target/arm/tcg/cpu-v7m.c | 1 +
76
accel/tcg/cpu-exec.c | 223 +++++++++------------
134
target/arm/tcg/helper-a64.c | 6 +-
77
accel/tcg/tcg-accel-ops-mttcg.c | 4 +-
135
target/arm/tcg/translate.c | 5 +-
78
accel/tcg/tcg-accel-ops-rr.c | 4 +-
136
target/avr/cpu.c | 1 +
79
accel/tcg/tcg-accel-ops.c | 4 +-
137
target/avr/translate.c | 6 +-
80
accel/tcg/translate-all.c | 2 +-
138
target/hexagon/cpu.c | 1 +
81
bsd-user/signal.c | 4 +-
139
target/hexagon/fma_emu.c | 496 ++++++---------------
82
cpu-target.c | 78 +++++--
140
target/hexagon/op_helper.c | 125 ++----
83
hw/core/loader.c | 2 +-
141
target/hexagon/translate.c | 4 +-
84
linux-user/elfload.c | 2 +-
142
target/hppa/cpu.c | 1 +
85
linux-user/exit.c | 2 +-
143
target/hppa/translate.c | 4 +-
86
linux-user/main.c | 2 +-
144
target/i386/tcg/tcg-cpu.c | 1 +
87
linux-user/signal.c | 4 +-
145
target/i386/tcg/translate.c | 5 +-
88
system/physmem.c | 5 -
146
target/loongarch/cpu.c | 1 +
89
system/vl.c | 2 +-
147
target/loongarch/tcg/translate.c | 4 +-
90
target/alpha/cpu.c | 2 +-
148
target/m68k/cpu.c | 1 +
91
target/alpha/translate.c | 2 +-
149
target/m68k/translate.c | 4 +-
92
target/arm/cpu.c | 2 +-
150
target/microblaze/cpu.c | 1 +
93
target/arm/tcg/cpu32.c | 2 +-
151
target/microblaze/translate.c | 4 +-
94
target/arm/tcg/translate.c | 2 +-
152
target/mips/cpu.c | 1 +
95
target/avr/cpu.c | 2 +-
153
target/mips/tcg/translate.c | 4 +-
96
target/avr/translate.c | 2 +-
154
target/openrisc/cpu.c | 1 +
97
target/cris/cpu.c | 4 +-
155
target/openrisc/translate.c | 4 +-
98
target/cris/translate.c | 2 +-
156
target/ppc/cpu_init.c | 1 +
99
target/hexagon/cpu.c | 2 +-
157
target/ppc/translate.c | 4 +-
100
target/hexagon/translate.c | 5 +-
158
target/riscv/tcg/tcg-cpu.c | 1 +
101
target/hppa/cpu.c | 2 +-
159
target/riscv/translate.c | 4 +-
102
target/hppa/translate.c | 2 +-
160
target/rx/cpu.c | 1 +
103
target/i386/tcg/sysemu/seg_helper.c | 23 +++
161
target/rx/translate.c | 4 +-
104
target/i386/tcg/tcg-cpu.c | 4 +-
162
target/s390x/cpu.c | 1 +
105
target/i386/tcg/translate.c | 2 +-
163
target/s390x/tcg/translate.c | 4 +-
106
target/loongarch/cpu.c | 2 +-
164
target/sh4/cpu.c | 1 +
107
target/loongarch/tcg/translate.c | 2 +-
165
target/sh4/translate.c | 4 +-
108
target/m68k/cpu.c | 2 +-
166
target/sparc/cpu.c | 1 +
109
target/m68k/translate.c | 4 +-
167
target/sparc/fop_helper.c | 8 +-
110
target/microblaze/cpu.c | 2 +-
168
target/sparc/translate.c | 84 ++--
111
target/microblaze/translate.c | 2 +-
169
target/tricore/cpu.c | 1 +
112
target/mips/cpu.c | 2 +-
170
target/tricore/translate.c | 5 +-
113
target/mips/tcg/translate.c | 14 +-
171
target/xtensa/cpu.c | 1 +
114
target/nios2/cpu.c | 2 +-
172
target/xtensa/translate.c | 4 +-
115
target/nios2/translate.c | 2 +-
173
tcg/optimize.c | 857 +++++++++++++++++++-----------------
116
target/openrisc/cpu.c | 2 +-
174
tests/tcg/multiarch/system/memory.c | 9 +-
117
target/openrisc/translate.c | 2 +-
175
fpu/softfloat-parts.c.inc | 16 +-
118
target/ppc/cpu_init.c | 2 +-
176
75 files changed, 866 insertions(+), 1009 deletions(-)
119
target/ppc/translate.c | 2 +-
120
target/riscv/tcg/tcg-cpu.c | 2 +-
121
target/riscv/translate.c | 2 +-
122
target/rx/cpu.c | 2 +-
123
target/rx/translate.c | 2 +-
124
target/s390x/cpu.c | 2 +-
125
target/s390x/tcg/translate.c | 2 +-
126
target/sh4/cpu.c | 2 +-
127
target/sh4/translate.c | 2 +-
128
target/sparc/cpu.c | 2 +-
129
target/sparc/translate.c | 2 +-
130
target/target-common.c | 10 +
131
target/tricore/cpu.c | 2 +-
132
target/tricore/translate.c | 2 +-
133
target/xtensa/cpu.c | 2 +-
134
target/xtensa/translate.c | 2 +-
135
{accel/tcg => tcg}/debuginfo.c | 3 +-
136
{accel/tcg => tcg}/perf.c | 14 +-
137
tcg/tcg.c | 2 +-
138
tests/tcg/multiarch/prot-none.c | 40 ++++
139
accel/tcg/meson.build | 16 +-
140
target/meson.build | 2 +
141
tcg/meson.build | 5 +
142
tests/guest-debug/run-test.py | 7 +-
143
tests/guest-debug/test_gdbstub.py | 60 ++++++
144
tests/tcg/aarch64/gdbstub/test-sve-ioctl.py | 34 +---
145
tests/tcg/aarch64/gdbstub/test-sve.py | 33 +--
146
tests/tcg/multiarch/Makefile.target | 9 +-
147
tests/tcg/multiarch/gdbstub/interrupt.py | 47 +----
148
tests/tcg/multiarch/gdbstub/memory.py | 39 +---
149
tests/tcg/multiarch/gdbstub/prot-none.py | 36 ++++
150
tests/tcg/multiarch/gdbstub/registers.py | 41 +---
151
tests/tcg/multiarch/gdbstub/sha1.py | 38 +---
152
tests/tcg/multiarch/gdbstub/test-proc-mappings.py | 39 +---
153
.../tcg/multiarch/gdbstub/test-qxfer-auxv-read.py | 37 +---
154
.../multiarch/gdbstub/test-thread-breakpoint.py | 37 +---
155
tests/tcg/s390x/gdbstub/test-signals-s390x.py | 42 +---
156
tests/tcg/s390x/gdbstub/test-svc.py | 39 +---
157
97 files changed, 580 insertions(+), 730 deletions(-)
158
create mode 100644 include/exec/vaddr.h
159
rename {accel => include}/tcg/debuginfo.h (96%)
160
rename {accel => include}/tcg/perf.h (95%)
161
create mode 100644 target/target-common.c
162
rename {accel/tcg => tcg}/debuginfo.c (98%)
163
rename {accel/tcg => tcg}/perf.c (97%)
164
create mode 100644 tests/tcg/multiarch/prot-none.c
165
create mode 100644 tests/guest-debug/test_gdbstub.py
166
create mode 100644 tests/tcg/multiarch/gdbstub/prot-none.py
167
diff view generated by jsdifflib
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
2
2
3
Stop using TARGET_PAGE_MASK in order to make perf.c more
3
make check-tcg fails on Fedora with the following error message:
4
target-agnostic.
5
4
5
alpha-linux-gnu-gcc [...] qemu/tests/tcg/multiarch/system/memory.c -o memory [...]
6
qemu/tests/tcg/multiarch/system/memory.c:17:10: fatal error: inttypes.h: No such file or directory
7
17 | #include <inttypes.h>
8
| ^~~~~~~~~~~~
9
compilation terminated.
10
11
The reason is that Fedora has cross-compilers, but no cross-glibc
12
headers. Fix by hardcoding the format specifiers and dropping the
13
include.
14
15
An alternative fix would be to introduce a configure check for
16
inttypes.h. But this would make it impossible to use Fedora
17
cross-compilers for softmmu tests, which used to work so far.
18
19
Fixes: ecbcc9ead2f8 ("tests/tcg: add a system test to check memory instrumentation")
6
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
20
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
21
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
22
Message-ID: <20241010085906.226249-1-iii@linux.ibm.com>
9
Message-ID: <20231212003837.64090-2-iii@linux.ibm.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-Id: <20240125054631.78867-2-philmd@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
23
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
---
24
---
14
accel/tcg/perf.c | 3 ++-
25
tests/tcg/multiarch/system/memory.c | 9 ++++-----
15
1 file changed, 2 insertions(+), 1 deletion(-)
26
1 file changed, 4 insertions(+), 5 deletions(-)
16
27
17
diff --git a/accel/tcg/perf.c b/accel/tcg/perf.c
28
diff --git a/tests/tcg/multiarch/system/memory.c b/tests/tcg/multiarch/system/memory.c
18
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
19
--- a/accel/tcg/perf.c
30
--- a/tests/tcg/multiarch/system/memory.c
20
+++ b/accel/tcg/perf.c
31
+++ b/tests/tcg/multiarch/system/memory.c
21
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@
22
33
23
#include "qemu/osdep.h"
34
#include <stdint.h>
24
#include "elf.h"
35
#include <stdbool.h>
25
+#include "exec/target_page.h"
36
-#include <inttypes.h>
26
#include "exec/exec-all.h"
37
#include <minilib.h>
27
#include "qemu/timer.h"
38
28
#include "tcg/tcg.h"
39
#ifndef CHECK_UNALIGNED
29
@@ -XXX,XX +XXX,XX @@ void perf_report_code(uint64_t guest_pc, TranslationBlock *tb,
40
@@ -XXX,XX +XXX,XX @@ int main(void)
30
/* FIXME: This replicates the restore_state_to_opc() logic. */
41
int i;
31
q[insn].address = gen_insn_data[insn * start_words + 0];
42
bool ok = true;
32
if (tb_cflags(tb) & CF_PCREL) {
43
33
- q[insn].address |= (guest_pc & TARGET_PAGE_MASK);
44
- ml_printf("Test data start: 0x%"PRIxPTR"\n", &test_data[0]);
34
+ q[insn].address |= (guest_pc & qemu_target_page_mask());
45
- ml_printf("Test data end: 0x%"PRIxPTR"\n", &test_data[TEST_SIZE]);
35
} else {
46
+ ml_printf("Test data start: 0x%lx\n", (unsigned long)&test_data[0]);
36
#if defined(TARGET_I386)
47
+ ml_printf("Test data end: 0x%lx\n", (unsigned long)&test_data[TEST_SIZE]);
37
q[insn].address -= tb->cs_base;
48
49
/* Run through the unsigned tests first */
50
for (i = 0; i < ARRAY_SIZE(init_ufns) && ok; i++) {
51
@@ -XXX,XX +XXX,XX @@ int main(void)
52
ok = do_signed_reads(true);
53
}
54
55
- ml_printf("Test data read: %"PRId32"\n", test_read_count);
56
- ml_printf("Test data write: %"PRId32"\n", test_write_count);
57
+ ml_printf("Test data read: %lu\n", (unsigned long)test_read_count);
58
+ ml_printf("Test data write: %lu\n", (unsigned long)test_write_count);
59
ml_printf("Test complete: %s\n", ok ? "PASSED" : "FAILED");
60
return ok ? 0 : -1;
61
}
38
--
62
--
39
2.34.1
63
2.43.0
40
41
diff view generated by jsdifflib
New patch
1
From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
1
2
3
When running with a single vcpu, we can return a constant instead of a
4
load when accessing cpu_index.
5
A side effect is that all tcg operations using it are optimized, most
6
notably scoreboard access.
7
When running a simple loop in user-mode, the speedup is around 20%.
8
9
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-ID: <20241128213843.1023080-1-pierrick.bouvier@linaro.org>
13
---
14
accel/tcg/plugin-gen.c | 9 +++++++++
15
1 file changed, 9 insertions(+)
16
17
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/accel/tcg/plugin-gen.c
20
+++ b/accel/tcg/plugin-gen.c
21
@@ -XXX,XX +XXX,XX @@ static void gen_disable_mem_helper(void)
22
23
static TCGv_i32 gen_cpu_index(void)
24
{
25
+ /*
26
+ * Optimize when we run with a single vcpu. All values using cpu_index,
27
+ * including scoreboard index, will be optimized out.
28
+ * User-mode calls tb_flush when setting this flag. In system-mode, all
29
+ * vcpus are created before generating code.
30
+ */
31
+ if (!tcg_cflags_has(current_cpu, CF_PARALLEL)) {
32
+ return tcg_constant_i32(current_cpu->cpu_index);
33
+ }
34
TCGv_i32 cpu_index = tcg_temp_ebb_new_i32();
35
tcg_gen_ld_i32(cpu_index, tcg_env,
36
-offsetof(ArchCPU, env) + offsetof(CPUState, cpu_index));
37
--
38
2.43.0
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
Call them directly from the opcode switch statement in tcg_optimize,
2
rather than in finish_folding based on opcode flags. Adjust folding
3
of conditional branches to match.
2
4
3
Move this x86-specific code out of the generic accel/tcg/.
5
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
5
Reviewed-by: Anton Johansson <anjo@rev.ng>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-Id: <20240124101639.30056-8-philmd@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
7
---
12
target/i386/tcg/helper-tcg.h | 1 +
8
tcg/optimize.c | 47 +++++++++++++++++++++++++++++++----------------
13
accel/tcg/cpu-exec.c | 4 ----
9
1 file changed, 31 insertions(+), 16 deletions(-)
14
target/i386/tcg/sysemu/seg_helper.c | 10 ++++++++++
15
target/i386/tcg/tcg-cpu.c | 1 +
16
4 files changed, 12 insertions(+), 4 deletions(-)
17
10
18
diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h
11
diff --git a/tcg/optimize.c b/tcg/optimize.c
19
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
20
--- a/target/i386/tcg/helper-tcg.h
13
--- a/tcg/optimize.c
21
+++ b/target/i386/tcg/helper-tcg.h
14
+++ b/tcg/optimize.c
22
@@ -XXX,XX +XXX,XX @@ QEMU_BUILD_BUG_ON(TCG_PHYS_ADDR_BITS > TARGET_PHYS_ADDR_SPACE_BITS);
15
@@ -XXX,XX +XXX,XX @@ static void copy_propagate(OptContext *ctx, TCGOp *op,
23
*/
24
void x86_cpu_do_interrupt(CPUState *cpu);
25
#ifndef CONFIG_USER_ONLY
26
+bool x86_need_replay_interrupt(int interrupt_request);
27
bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
28
#endif
29
30
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/accel/tcg/cpu-exec.c
33
+++ b/accel/tcg/cpu-exec.c
34
@@ -XXX,XX +XXX,XX @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
35
*/
36
static inline bool need_replay_interrupt(CPUState *cpu, int interrupt_request)
37
{
38
-#if defined(TARGET_I386)
39
- return !(interrupt_request & CPU_INTERRUPT_POLL);
40
-#else
41
const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
42
return !tcg_ops->need_replay_interrupt
43
|| tcg_ops->need_replay_interrupt(interrupt_request);
44
-#endif
45
}
46
#endif /* !CONFIG_USER_ONLY */
47
48
diff --git a/target/i386/tcg/sysemu/seg_helper.c b/target/i386/tcg/sysemu/seg_helper.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/i386/tcg/sysemu/seg_helper.c
51
+++ b/target/i386/tcg/sysemu/seg_helper.c
52
@@ -XXX,XX +XXX,XX @@ void x86_cpu_do_interrupt(CPUState *cs)
53
}
16
}
54
}
17
}
55
18
56
+bool x86_need_replay_interrupt(int interrupt_request)
19
+static void finish_bb(OptContext *ctx)
57
+{
20
+{
58
+ /*
21
+ /* We only optimize memory barriers across basic blocks. */
59
+ * CPU_INTERRUPT_POLL is a virtual event which gets converted into a
22
+ ctx->prev_mb = NULL;
60
+ * "real" interrupt event later. It does not need to be recorded for
61
+ * replay purposes.
62
+ */
63
+ return !(interrupt_request & CPU_INTERRUPT_POLL);
64
+}
23
+}
65
+
24
+
66
bool x86_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
25
+static void finish_ebb(OptContext *ctx)
26
+{
27
+ finish_bb(ctx);
28
+ /* We only optimize across extended basic blocks. */
29
+ memset(&ctx->temps_used, 0, sizeof(ctx->temps_used));
30
+ remove_mem_copy_all(ctx);
31
+}
32
+
33
static void finish_folding(OptContext *ctx, TCGOp *op)
67
{
34
{
68
X86CPU *cpu = X86_CPU(cs);
35
const TCGOpDef *def = &tcg_op_defs[op->opc];
69
diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c
36
int i, nb_oargs;
70
index XXXXXXX..XXXXXXX 100644
37
71
--- a/target/i386/tcg/tcg-cpu.c
38
- /*
72
+++ b/target/i386/tcg/tcg-cpu.c
39
- * We only optimize extended basic blocks. If the opcode ends a BB
73
@@ -XXX,XX +XXX,XX @@ static const TCGCPUOps x86_tcg_ops = {
40
- * and is not a conditional branch, reset all temp data.
74
.do_unaligned_access = x86_cpu_do_unaligned_access,
41
- */
75
.debug_excp_handler = breakpoint_handler,
42
- if (def->flags & TCG_OPF_BB_END) {
76
.debug_check_breakpoint = x86_debug_check_breakpoint,
43
- ctx->prev_mb = NULL;
77
+ .need_replay_interrupt = x86_need_replay_interrupt,
44
- if (!(def->flags & TCG_OPF_COND_BRANCH)) {
78
#endif /* !CONFIG_USER_ONLY */
45
- memset(&ctx->temps_used, 0, sizeof(ctx->temps_used));
79
};
46
- remove_mem_copy_all(ctx);
80
47
- }
48
- return;
49
- }
50
-
51
nb_oargs = def->nb_oargs;
52
for (i = 0; i < nb_oargs; i++) {
53
TCGTemp *ts = arg_temp(op->args[i]);
54
@@ -XXX,XX +XXX,XX @@ static bool fold_brcond(OptContext *ctx, TCGOp *op)
55
if (i > 0) {
56
op->opc = INDEX_op_br;
57
op->args[0] = op->args[3];
58
+ finish_ebb(ctx);
59
+ } else {
60
+ finish_bb(ctx);
61
}
62
- return false;
63
+ return true;
64
}
65
66
static bool fold_brcond2(OptContext *ctx, TCGOp *op)
67
@@ -XXX,XX +XXX,XX @@ static bool fold_brcond2(OptContext *ctx, TCGOp *op)
68
}
69
op->opc = INDEX_op_br;
70
op->args[0] = label;
71
- break;
72
+ finish_ebb(ctx);
73
+ return true;
74
}
75
- return false;
76
+
77
+ finish_bb(ctx);
78
+ return true;
79
}
80
81
static bool fold_bswap(OptContext *ctx, TCGOp *op)
82
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s)
83
CASE_OP_32_64_VEC(xor):
84
done = fold_xor(&ctx, op);
85
break;
86
+ case INDEX_op_set_label:
87
+ case INDEX_op_br:
88
+ case INDEX_op_exit_tb:
89
+ case INDEX_op_goto_tb:
90
+ case INDEX_op_goto_ptr:
91
+ finish_ebb(&ctx);
92
+ done = true;
93
+ break;
94
default:
95
break;
96
}
81
--
97
--
82
2.34.1
98
2.43.0
83
84
diff view generated by jsdifflib
New patch
1
There are only a few logical operations which can compute
2
an "affected" mask. Split out handling of this optimization
3
to a separate function, only to be called when applicable.
1
4
5
Remove the a_mask field from OptContext, as the mask is
6
no longer stored anywhere.
7
8
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
11
tcg/optimize.c | 42 +++++++++++++++++++++++++++---------------
12
1 file changed, 27 insertions(+), 15 deletions(-)
13
14
diff --git a/tcg/optimize.c b/tcg/optimize.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tcg/optimize.c
17
+++ b/tcg/optimize.c
18
@@ -XXX,XX +XXX,XX @@ typedef struct OptContext {
19
QSIMPLEQ_HEAD(, MemCopyInfo) mem_free;
20
21
/* In flight values from optimization. */
22
- uint64_t a_mask; /* mask bit is 0 iff value identical to first input */
23
uint64_t z_mask; /* mask bit is 0 iff value bit is 0 */
24
uint64_t s_mask; /* mask of clrsb(value) bits */
25
TCGType type;
26
@@ -XXX,XX +XXX,XX @@ static bool fold_const2_commutative(OptContext *ctx, TCGOp *op)
27
28
static bool fold_masks(OptContext *ctx, TCGOp *op)
29
{
30
- uint64_t a_mask = ctx->a_mask;
31
uint64_t z_mask = ctx->z_mask;
32
uint64_t s_mask = ctx->s_mask;
33
34
@@ -XXX,XX +XXX,XX @@ static bool fold_masks(OptContext *ctx, TCGOp *op)
35
* type changing opcodes.
36
*/
37
if (ctx->type == TCG_TYPE_I32) {
38
- a_mask = (int32_t)a_mask;
39
z_mask = (int32_t)z_mask;
40
s_mask |= MAKE_64BIT_MASK(32, 32);
41
ctx->z_mask = z_mask;
42
@@ -XXX,XX +XXX,XX @@ static bool fold_masks(OptContext *ctx, TCGOp *op)
43
if (z_mask == 0) {
44
return tcg_opt_gen_movi(ctx, op, op->args[0], 0);
45
}
46
+ return false;
47
+}
48
+
49
+/*
50
+ * An "affected" mask bit is 0 if and only if the result is identical
51
+ * to the first input. Thus if the entire mask is 0, the operation
52
+ * is equivalent to a copy.
53
+ */
54
+static bool fold_affected_mask(OptContext *ctx, TCGOp *op, uint64_t a_mask)
55
+{
56
+ if (ctx->type == TCG_TYPE_I32) {
57
+ a_mask = (uint32_t)a_mask;
58
+ }
59
if (a_mask == 0) {
60
return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[1]);
61
}
62
@@ -XXX,XX +XXX,XX @@ static bool fold_and(OptContext *ctx, TCGOp *op)
63
* Known-zeros does not imply known-ones. Therefore unless
64
* arg2 is constant, we can't infer affected bits from it.
65
*/
66
- if (arg_is_const(op->args[2])) {
67
- ctx->a_mask = z1 & ~z2;
68
+ if (arg_is_const(op->args[2]) &&
69
+ fold_affected_mask(ctx, op, z1 & ~z2)) {
70
+ return true;
71
}
72
73
return fold_masks(ctx, op);
74
@@ -XXX,XX +XXX,XX @@ static bool fold_andc(OptContext *ctx, TCGOp *op)
75
*/
76
if (arg_is_const(op->args[2])) {
77
uint64_t z2 = ~arg_info(op->args[2])->z_mask;
78
- ctx->a_mask = z1 & ~z2;
79
+ if (fold_affected_mask(ctx, op, z1 & ~z2)) {
80
+ return true;
81
+ }
82
z1 &= z2;
83
}
84
ctx->z_mask = z1;
85
@@ -XXX,XX +XXX,XX @@ static bool fold_extract(OptContext *ctx, TCGOp *op)
86
87
z_mask_old = arg_info(op->args[1])->z_mask;
88
z_mask = extract64(z_mask_old, pos, len);
89
- if (pos == 0) {
90
- ctx->a_mask = z_mask_old ^ z_mask;
91
+ if (pos == 0 && fold_affected_mask(ctx, op, z_mask_old ^ z_mask)) {
92
+ return true;
93
}
94
ctx->z_mask = z_mask;
95
ctx->s_mask = smask_from_zmask(z_mask);
96
@@ -XXX,XX +XXX,XX @@ static bool fold_exts(OptContext *ctx, TCGOp *op)
97
98
ctx->z_mask = z_mask;
99
ctx->s_mask = s_mask;
100
- if (!type_change) {
101
- ctx->a_mask = s_mask & ~s_mask_old;
102
+ if (!type_change && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
103
+ return true;
104
}
105
106
return fold_masks(ctx, op);
107
@@ -XXX,XX +XXX,XX @@ static bool fold_extu(OptContext *ctx, TCGOp *op)
108
109
ctx->z_mask = z_mask;
110
ctx->s_mask = smask_from_zmask(z_mask);
111
- if (!type_change) {
112
- ctx->a_mask = z_mask_old ^ z_mask;
113
+ if (!type_change && fold_affected_mask(ctx, op, z_mask_old ^ z_mask)) {
114
+ return true;
115
}
116
return fold_masks(ctx, op);
117
}
118
@@ -XXX,XX +XXX,XX @@ static bool fold_sextract(OptContext *ctx, TCGOp *op)
119
s_mask |= MAKE_64BIT_MASK(len, 64 - len);
120
ctx->s_mask = s_mask;
121
122
- if (pos == 0) {
123
- ctx->a_mask = s_mask & ~s_mask_old;
124
+ if (pos == 0 && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
125
+ return true;
126
}
127
128
return fold_masks(ctx, op);
129
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s)
130
}
131
132
/* Assume all bits affected, no bits known zero, no sign reps. */
133
- ctx.a_mask = -1;
134
ctx.z_mask = -1;
135
ctx.s_mask = 0;
136
137
--
138
2.43.0
diff view generated by jsdifflib
New patch
1
Use of fold_masks should be restricted to those opcodes that
2
can reliably make use of it -- those with a single output,
3
and from higher-level folders that set up the masks.
4
Prepare for conversion of each folder in turn.
1
5
6
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
9
tcg/optimize.c | 17 ++++++++++++++---
10
1 file changed, 14 insertions(+), 3 deletions(-)
11
12
diff --git a/tcg/optimize.c b/tcg/optimize.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/tcg/optimize.c
15
+++ b/tcg/optimize.c
16
@@ -XXX,XX +XXX,XX @@ static bool fold_masks(OptContext *ctx, TCGOp *op)
17
{
18
uint64_t z_mask = ctx->z_mask;
19
uint64_t s_mask = ctx->s_mask;
20
+ const TCGOpDef *def = &tcg_op_defs[op->opc];
21
+ TCGTemp *ts;
22
+ TempOptInfo *ti;
23
+
24
+ /* Only single-output opcodes are supported here. */
25
+ tcg_debug_assert(def->nb_oargs == 1);
26
27
/*
28
* 32-bit ops generate 32-bit results, which for the purpose of
29
@@ -XXX,XX +XXX,XX @@ static bool fold_masks(OptContext *ctx, TCGOp *op)
30
if (ctx->type == TCG_TYPE_I32) {
31
z_mask = (int32_t)z_mask;
32
s_mask |= MAKE_64BIT_MASK(32, 32);
33
- ctx->z_mask = z_mask;
34
- ctx->s_mask = s_mask;
35
}
36
37
if (z_mask == 0) {
38
return tcg_opt_gen_movi(ctx, op, op->args[0], 0);
39
}
40
- return false;
41
+
42
+ ts = arg_temp(op->args[0]);
43
+ reset_ts(ctx, ts);
44
+
45
+ ti = ts_info(ts);
46
+ ti->z_mask = z_mask;
47
+ ti->s_mask = s_mask;
48
+ return true;
49
}
50
51
/*
52
--
53
2.43.0
diff view generated by jsdifflib
New patch
1
Add a routine to which masks can be passed directly, rather than
2
storing them into OptContext. To be used in upcoming patches.
1
3
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
tcg/optimize.c | 15 ++++++++++++---
8
1 file changed, 12 insertions(+), 3 deletions(-)
9
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/optimize.c
13
+++ b/tcg/optimize.c
14
@@ -XXX,XX +XXX,XX @@ static bool fold_const2_commutative(OptContext *ctx, TCGOp *op)
15
return fold_const2(ctx, op);
16
}
17
18
-static bool fold_masks(OptContext *ctx, TCGOp *op)
19
+/*
20
+ * Record "zero" and "sign" masks for the single output of @op.
21
+ * See TempOptInfo definition of z_mask and s_mask.
22
+ * If z_mask allows, fold the output to constant zero.
23
+ */
24
+static bool fold_masks_zs(OptContext *ctx, TCGOp *op,
25
+ uint64_t z_mask, uint64_t s_mask)
26
{
27
- uint64_t z_mask = ctx->z_mask;
28
- uint64_t s_mask = ctx->s_mask;
29
const TCGOpDef *def = &tcg_op_defs[op->opc];
30
TCGTemp *ts;
31
TempOptInfo *ti;
32
@@ -XXX,XX +XXX,XX @@ static bool fold_masks(OptContext *ctx, TCGOp *op)
33
return true;
34
}
35
36
+static bool fold_masks(OptContext *ctx, TCGOp *op)
37
+{
38
+ return fold_masks_zs(ctx, op, ctx->z_mask, ctx->s_mask);
39
+}
40
+
41
/*
42
* An "affected" mask bit is 0 if and only if the result is identical
43
* to the first input. Thus if the entire mask is 0, the operation
44
--
45
2.43.0
diff view generated by jsdifflib
1
CPU_GET_CLASS does runtime type checking; use the cached
1
Consider the passed s_mask to be a minimum deduced from
2
copy of the class instead.
2
either existing s_mask or from a sign-extension operation.
3
We may be able to deduce more from the set of known zeros.
4
Remove identical logic from several opcode folders.
3
5
6
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@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
accel/tcg/cpu-exec.c | 109 ++++++++++++++++++++++---------------------
9
tcg/optimize.c | 21 ++++++---------------
7
1 file changed, 56 insertions(+), 53 deletions(-)
10
1 file changed, 6 insertions(+), 15 deletions(-)
8
11
9
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
12
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
11
--- a/accel/tcg/cpu-exec.c
14
--- a/tcg/optimize.c
12
+++ b/accel/tcg/cpu-exec.c
15
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool check_for_breakpoints_slow(CPUState *cpu, vaddr pc,
16
@@ -XXX,XX +XXX,XX @@ static bool fold_const2_commutative(OptContext *ctx, TCGOp *op)
14
#ifdef CONFIG_USER_ONLY
17
* Record "zero" and "sign" masks for the single output of @op.
15
g_assert_not_reached();
18
* See TempOptInfo definition of z_mask and s_mask.
16
#else
19
* If z_mask allows, fold the output to constant zero.
17
- CPUClass *cc = CPU_GET_CLASS(cpu);
20
+ * The passed s_mask may be augmented by z_mask.
18
- assert(cc->tcg_ops->debug_check_breakpoint);
21
*/
19
- match_bp = cc->tcg_ops->debug_check_breakpoint(cpu);
22
static bool fold_masks_zs(OptContext *ctx, TCGOp *op,
20
+ const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
23
uint64_t z_mask, uint64_t s_mask)
21
+ assert(tcg_ops->debug_check_breakpoint);
24
@@ -XXX,XX +XXX,XX @@ static bool fold_masks_zs(OptContext *ctx, TCGOp *op,
22
+ match_bp = tcg_ops->debug_check_breakpoint(cpu);
25
23
#endif
26
ti = ts_info(ts);
24
}
27
ti->z_mask = z_mask;
25
28
- ti->s_mask = s_mask;
26
@@ -XXX,XX +XXX,XX @@ cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit)
29
+ ti->s_mask = s_mask | smask_from_zmask(z_mask);
27
* counter hit zero); we must restore the guest PC to the address
30
return true;
28
* of the start of the TB.
31
}
29
*/
32
30
- CPUClass *cc = CPU_GET_CLASS(cpu);
33
@@ -XXX,XX +XXX,XX @@ static bool fold_bswap(OptContext *ctx, TCGOp *op)
31
+ CPUClass *cc = cpu->cc;
34
default:
32
+ const TCGCPUOps *tcg_ops = cc->tcg_ops;
35
g_assert_not_reached();
33
34
- if (cc->tcg_ops->synchronize_from_tb) {
35
- cc->tcg_ops->synchronize_from_tb(cpu, last_tb);
36
+ if (tcg_ops->synchronize_from_tb) {
37
+ tcg_ops->synchronize_from_tb(cpu, last_tb);
38
} else {
39
tcg_debug_assert(!(tb_cflags(last_tb) & CF_PCREL));
40
assert(cc->set_pc);
41
@@ -XXX,XX +XXX,XX @@ cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit)
42
43
static void cpu_exec_enter(CPUState *cpu)
44
{
45
- CPUClass *cc = CPU_GET_CLASS(cpu);
46
+ const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
47
48
- if (cc->tcg_ops->cpu_exec_enter) {
49
- cc->tcg_ops->cpu_exec_enter(cpu);
50
+ if (tcg_ops->cpu_exec_enter) {
51
+ tcg_ops->cpu_exec_enter(cpu);
52
}
36
}
37
- s_mask = smask_from_zmask(z_mask);
38
39
+ s_mask = 0;
40
switch (op->args[2] & (TCG_BSWAP_OZ | TCG_BSWAP_OS)) {
41
case TCG_BSWAP_OZ:
42
break;
43
@@ -XXX,XX +XXX,XX @@ static bool fold_bswap(OptContext *ctx, TCGOp *op)
44
default:
45
/* The high bits are undefined: force all bits above the sign to 1. */
46
z_mask |= sign << 1;
47
- s_mask = 0;
48
break;
49
}
50
ctx->z_mask = z_mask;
51
@@ -XXX,XX +XXX,XX @@ static bool fold_count_zeros(OptContext *ctx, TCGOp *op)
52
g_assert_not_reached();
53
}
54
ctx->z_mask = arg_info(op->args[2])->z_mask | z_mask;
55
- ctx->s_mask = smask_from_zmask(ctx->z_mask);
56
return false;
53
}
57
}
54
58
55
static void cpu_exec_exit(CPUState *cpu)
59
@@ -XXX,XX +XXX,XX @@ static bool fold_ctpop(OptContext *ctx, TCGOp *op)
56
{
60
default:
57
- CPUClass *cc = CPU_GET_CLASS(cpu);
61
g_assert_not_reached();
58
+ const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
59
60
- if (cc->tcg_ops->cpu_exec_exit) {
61
- cc->tcg_ops->cpu_exec_exit(cpu);
62
+ if (tcg_ops->cpu_exec_exit) {
63
+ tcg_ops->cpu_exec_exit(cpu);
64
}
62
}
63
- ctx->s_mask = smask_from_zmask(ctx->z_mask);
64
return false;
65
}
65
}
66
66
67
@@ -XXX,XX +XXX,XX @@ static inline bool cpu_handle_halt(CPUState *cpu)
67
@@ -XXX,XX +XXX,XX @@ static bool fold_extract(OptContext *ctx, TCGOp *op)
68
68
return true;
69
static inline void cpu_handle_debug_exception(CPUState *cpu)
69
}
70
{
70
ctx->z_mask = z_mask;
71
- CPUClass *cc = CPU_GET_CLASS(cpu);
71
- ctx->s_mask = smask_from_zmask(z_mask);
72
+ const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
72
73
CPUWatchpoint *wp;
73
return fold_masks(ctx, op);
74
74
}
75
if (!cpu->watchpoint_hit) {
75
@@ -XXX,XX +XXX,XX @@ static bool fold_extu(OptContext *ctx, TCGOp *op)
76
@@ -XXX,XX +XXX,XX @@ static inline void cpu_handle_debug_exception(CPUState *cpu)
76
}
77
78
ctx->z_mask = z_mask;
79
- ctx->s_mask = smask_from_zmask(z_mask);
80
if (!type_change && fold_affected_mask(ctx, op, z_mask_old ^ z_mask)) {
81
return true;
82
}
83
@@ -XXX,XX +XXX,XX @@ static bool fold_qemu_ld(OptContext *ctx, TCGOp *op)
84
int width = 8 * memop_size(mop);
85
86
if (width < 64) {
87
- ctx->s_mask = MAKE_64BIT_MASK(width, 64 - width);
88
- if (!(mop & MO_SIGN)) {
89
+ if (mop & MO_SIGN) {
90
+ ctx->s_mask = MAKE_64BIT_MASK(width, 64 - width);
91
+ } else {
92
ctx->z_mask = MAKE_64BIT_MASK(0, width);
93
- ctx->s_mask <<= 1;
77
}
94
}
78
}
95
}
79
96
80
- if (cc->tcg_ops->debug_excp_handler) {
97
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond(OptContext *ctx, TCGOp *op)
81
- cc->tcg_ops->debug_excp_handler(cpu);
98
fold_setcond_tst_pow2(ctx, op, false);
82
+ if (tcg_ops->debug_excp_handler) {
99
83
+ tcg_ops->debug_excp_handler(cpu);
100
ctx->z_mask = 1;
84
}
101
- ctx->s_mask = smask_from_zmask(1);
85
}
86
87
@@ -XXX,XX +XXX,XX @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
88
#endif
89
return false;
90
}
91
+
92
if (cpu->exception_index >= EXCP_INTERRUPT) {
93
/* exit request from the cpu execution loop */
94
*ret = cpu->exception_index;
95
@@ -XXX,XX +XXX,XX @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
96
}
97
cpu->exception_index = -1;
98
return true;
99
- } else {
100
-#if defined(CONFIG_USER_ONLY)
101
- /* if user mode only, we simulate a fake exception
102
- which will be handled outside the cpu execution
103
- loop */
104
-#if defined(TARGET_I386)
105
- CPUClass *cc = CPU_GET_CLASS(cpu);
106
- cc->tcg_ops->fake_user_interrupt(cpu);
107
-#endif /* TARGET_I386 */
108
- *ret = cpu->exception_index;
109
- cpu->exception_index = -1;
110
- return true;
111
-#else
112
- if (replay_exception()) {
113
- CPUClass *cc = CPU_GET_CLASS(cpu);
114
- bql_lock();
115
- cc->tcg_ops->do_interrupt(cpu);
116
- bql_unlock();
117
- cpu->exception_index = -1;
118
+ }
119
120
- if (unlikely(cpu->singlestep_enabled)) {
121
- /*
122
- * After processing the exception, ensure an EXCP_DEBUG is
123
- * raised when single-stepping so that GDB doesn't miss the
124
- * next instruction.
125
- */
126
- *ret = EXCP_DEBUG;
127
- cpu_handle_debug_exception(cpu);
128
- return true;
129
- }
130
- } else if (!replay_has_interrupt()) {
131
- /* give a chance to iothread in replay mode */
132
- *ret = EXCP_INTERRUPT;
133
+#if defined(CONFIG_USER_ONLY)
134
+ /*
135
+ * If user mode only, we simulate a fake exception which will be
136
+ * handled outside the cpu execution loop.
137
+ */
138
+#if defined(TARGET_I386)
139
+ const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
140
+ tcg_ops->fake_user_interrupt(cpu);
141
+#endif /* TARGET_I386 */
142
+ *ret = cpu->exception_index;
143
+ cpu->exception_index = -1;
144
+ return true;
145
+#else
146
+ if (replay_exception()) {
147
+ const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
148
+
149
+ bql_lock();
150
+ tcg_ops->do_interrupt(cpu);
151
+ bql_unlock();
152
+ cpu->exception_index = -1;
153
+
154
+ if (unlikely(cpu->singlestep_enabled)) {
155
+ /*
156
+ * After processing the exception, ensure an EXCP_DEBUG is
157
+ * raised when single-stepping so that GDB doesn't miss the
158
+ * next instruction.
159
+ */
160
+ *ret = EXCP_DEBUG;
161
+ cpu_handle_debug_exception(cpu);
162
return true;
163
}
164
-#endif
165
+ } else if (!replay_has_interrupt()) {
166
+ /* give a chance to iothread in replay mode */
167
+ *ret = EXCP_INTERRUPT;
168
+ return true;
169
}
170
+#endif
171
172
return false;
102
return false;
173
}
103
}
174
@@ -XXX,XX +XXX,XX @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
104
175
True when it is, and we should restart on a new TB,
105
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond2(OptContext *ctx, TCGOp *op)
176
and via longjmp via cpu_loop_exit. */
177
else {
178
- CPUClass *cc = CPU_GET_CLASS(cpu);
179
+ const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
180
181
- if (cc->tcg_ops->cpu_exec_interrupt &&
182
- cc->tcg_ops->cpu_exec_interrupt(cpu, interrupt_request)) {
183
+ if (tcg_ops->cpu_exec_interrupt &&
184
+ tcg_ops->cpu_exec_interrupt(cpu, interrupt_request)) {
185
if (need_replay_interrupt(interrupt_request)) {
186
replay_interrupt();
187
}
188
@@ -XXX,XX +XXX,XX @@ int cpu_exec(CPUState *cpu)
189
bool tcg_exec_realizefn(CPUState *cpu, Error **errp)
190
{
191
static bool tcg_target_initialized;
192
- CPUClass *cc = CPU_GET_CLASS(cpu);
193
194
if (!tcg_target_initialized) {
195
- cc->tcg_ops->initialize();
196
+ cpu->cc->tcg_ops->initialize();
197
tcg_target_initialized = true;
198
}
106
}
199
107
108
ctx->z_mask = 1;
109
- ctx->s_mask = smask_from_zmask(1);
110
return false;
111
112
do_setcond_const:
113
@@ -XXX,XX +XXX,XX @@ static bool fold_tcg_ld(OptContext *ctx, TCGOp *op)
114
break;
115
CASE_OP_32_64(ld8u):
116
ctx->z_mask = MAKE_64BIT_MASK(0, 8);
117
- ctx->s_mask = MAKE_64BIT_MASK(9, 55);
118
break;
119
CASE_OP_32_64(ld16s):
120
ctx->s_mask = MAKE_64BIT_MASK(16, 48);
121
break;
122
CASE_OP_32_64(ld16u):
123
ctx->z_mask = MAKE_64BIT_MASK(0, 16);
124
- ctx->s_mask = MAKE_64BIT_MASK(17, 47);
125
break;
126
case INDEX_op_ld32s_i64:
127
ctx->s_mask = MAKE_64BIT_MASK(32, 32);
128
break;
129
case INDEX_op_ld32u_i64:
130
ctx->z_mask = MAKE_64BIT_MASK(0, 32);
131
- ctx->s_mask = MAKE_64BIT_MASK(33, 31);
132
break;
133
default:
134
g_assert_not_reached();
200
--
135
--
201
2.34.1
136
2.43.0
diff view generated by jsdifflib
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
1
Change the representation from sign bit repetitions to all bits equal
2
to the sign bit, including the sign bit itself.
2
3
3
Preparation for moving perf.c to tcg/.
4
The previous format has a problem in that it is difficult to recreate
5
a valid sign mask after a shift operation: the "repetitions" part of
6
the previous format meant that applying the same shift as for the value
7
lead to an off-by-one value.
4
8
5
This affects only profiling guest code, which has code in a non-0 based
9
The new format, including the sign bit itself, means that the sign mask
6
segment, e.g., 16-bit code, which is not particularly important.
10
can be manipulated in exactly the same way as the value, canonicalization
11
is easier.
7
12
8
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
13
Canonicalize the s_mask in fold_masks_zs, rather than requiring callers
9
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
14
to do so. Treat 0 as a non-canonical but typeless input for no sign
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
information, which will be reset as appropriate for the data type.
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
We can easily fold in the data from z_mask while canonicalizing.
12
Message-ID: <20231212003837.64090-4-iii@linux.ibm.com>
17
13
Message-Id: <20240125054631.78867-4-philmd@linaro.org>
18
Temporarily disable optimizations using s_mask while each operation is
19
converted to use fold_masks_zs and to the new form.
20
21
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
22
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
---
23
---
16
accel/tcg/perf.c | 4 ----
24
tcg/optimize.c | 64 ++++++++++++--------------------------------------
17
1 file changed, 4 deletions(-)
25
1 file changed, 15 insertions(+), 49 deletions(-)
18
26
19
diff --git a/accel/tcg/perf.c b/accel/tcg/perf.c
27
diff --git a/tcg/optimize.c b/tcg/optimize.c
20
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
21
--- a/accel/tcg/perf.c
29
--- a/tcg/optimize.c
22
+++ b/accel/tcg/perf.c
30
+++ b/tcg/optimize.c
23
@@ -XXX,XX +XXX,XX @@ void perf_report_code(uint64_t guest_pc, TranslationBlock *tb,
31
@@ -XXX,XX +XXX,XX @@ typedef struct TempOptInfo {
24
q[insn].address = gen_insn_data[insn * start_words + 0];
32
QSIMPLEQ_HEAD(, MemCopyInfo) mem_copy;
25
if (tb_cflags(tb) & CF_PCREL) {
33
uint64_t val;
26
q[insn].address |= (guest_pc & qemu_target_page_mask());
34
uint64_t z_mask; /* mask bit is 0 if and only if value bit is 0 */
27
- } else {
35
- uint64_t s_mask; /* a left-aligned mask of clrsb(value) bits. */
28
-#if defined(TARGET_I386)
36
+ uint64_t s_mask; /* mask bit is 1 if value bit matches msb */
29
- q[insn].address -= tb->cs_base;
37
} TempOptInfo;
30
-#endif
38
39
typedef struct OptContext {
40
@@ -XXX,XX +XXX,XX @@ typedef struct OptContext {
41
42
/* In flight values from optimization. */
43
uint64_t z_mask; /* mask bit is 0 iff value bit is 0 */
44
- uint64_t s_mask; /* mask of clrsb(value) bits */
45
+ uint64_t s_mask; /* mask bit is 1 if value bit matches msb */
46
TCGType type;
47
} OptContext;
48
49
-/* Calculate the smask for a specific value. */
50
-static uint64_t smask_from_value(uint64_t value)
51
-{
52
- int rep = clrsb64(value);
53
- return ~(~0ull >> rep);
54
-}
55
-
56
-/*
57
- * Calculate the smask for a given set of known-zeros.
58
- * If there are lots of zeros on the left, we can consider the remainder
59
- * an unsigned field, and thus the corresponding signed field is one bit
60
- * larger.
61
- */
62
-static uint64_t smask_from_zmask(uint64_t zmask)
63
-{
64
- /*
65
- * Only the 0 bits are significant for zmask, thus the msb itself
66
- * must be zero, else we have no sign information.
67
- */
68
- int rep = clz64(zmask);
69
- if (rep == 0) {
70
- return 0;
71
- }
72
- rep -= 1;
73
- return ~(~0ull >> rep);
74
-}
75
-
76
-/*
77
- * Recreate a properly left-aligned smask after manipulation.
78
- * Some bit-shuffling, particularly shifts and rotates, may
79
- * retain sign bits on the left, but may scatter disconnected
80
- * sign bits on the right. Retain only what remains to the left.
81
- */
82
-static uint64_t smask_from_smask(int64_t smask)
83
-{
84
- /* Only the 1 bits are significant for smask */
85
- return smask_from_zmask(~smask);
86
-}
87
-
88
static inline TempOptInfo *ts_info(TCGTemp *ts)
89
{
90
return ts->state_ptr;
91
@@ -XXX,XX +XXX,XX @@ static void init_ts_info(OptContext *ctx, TCGTemp *ts)
92
ti->is_const = true;
93
ti->val = ts->val;
94
ti->z_mask = ts->val;
95
- ti->s_mask = smask_from_value(ts->val);
96
+ ti->s_mask = INT64_MIN >> clrsb64(ts->val);
97
} else {
98
ti->is_const = false;
99
ti->z_mask = -1;
100
@@ -XXX,XX +XXX,XX @@ static void finish_folding(OptContext *ctx, TCGOp *op)
101
*/
102
if (i == 0) {
103
ts_info(ts)->z_mask = ctx->z_mask;
104
- ts_info(ts)->s_mask = ctx->s_mask;
31
}
105
}
32
q[insn].flags = DEBUGINFO_SYMBOL | (jitdump ? DEBUGINFO_LINE : 0);
106
}
107
}
108
@@ -XXX,XX +XXX,XX @@ static bool fold_const2_commutative(OptContext *ctx, TCGOp *op)
109
* The passed s_mask may be augmented by z_mask.
110
*/
111
static bool fold_masks_zs(OptContext *ctx, TCGOp *op,
112
- uint64_t z_mask, uint64_t s_mask)
113
+ uint64_t z_mask, int64_t s_mask)
114
{
115
const TCGOpDef *def = &tcg_op_defs[op->opc];
116
TCGTemp *ts;
117
TempOptInfo *ti;
118
+ int rep;
119
120
/* Only single-output opcodes are supported here. */
121
tcg_debug_assert(def->nb_oargs == 1);
122
@@ -XXX,XX +XXX,XX @@ static bool fold_masks_zs(OptContext *ctx, TCGOp *op,
123
*/
124
if (ctx->type == TCG_TYPE_I32) {
125
z_mask = (int32_t)z_mask;
126
- s_mask |= MAKE_64BIT_MASK(32, 32);
127
+ s_mask |= INT32_MIN;
128
}
129
130
if (z_mask == 0) {
131
@@ -XXX,XX +XXX,XX @@ static bool fold_masks_zs(OptContext *ctx, TCGOp *op,
132
133
ti = ts_info(ts);
134
ti->z_mask = z_mask;
135
- ti->s_mask = s_mask | smask_from_zmask(z_mask);
136
+
137
+ /* Canonicalize s_mask and incorporate data from z_mask. */
138
+ rep = clz64(~s_mask);
139
+ rep = MAX(rep, clz64(z_mask));
140
+ rep = MAX(rep - 1, 0);
141
+ ti->s_mask = INT64_MIN >> rep;
142
+
143
return true;
144
}
145
146
@@ -XXX,XX +XXX,XX @@ static bool fold_exts(OptContext *ctx, TCGOp *op)
147
148
ctx->z_mask = z_mask;
149
ctx->s_mask = s_mask;
150
- if (!type_change && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
151
+ if (0 && !type_change && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
152
return true;
153
}
154
155
@@ -XXX,XX +XXX,XX @@ static bool fold_sextract(OptContext *ctx, TCGOp *op)
156
s_mask |= MAKE_64BIT_MASK(len, 64 - len);
157
ctx->s_mask = s_mask;
158
159
- if (pos == 0 && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
160
+ if (0 && pos == 0 && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
161
return true;
162
}
163
164
@@ -XXX,XX +XXX,XX @@ static bool fold_shift(OptContext *ctx, TCGOp *op)
165
ctx->z_mask = do_constant_folding(op->opc, ctx->type, z_mask, sh);
166
167
s_mask = do_constant_folding(op->opc, ctx->type, s_mask, sh);
168
- ctx->s_mask = smask_from_smask(s_mask);
169
170
return fold_masks(ctx, op);
33
}
171
}
34
--
172
--
35
2.34.1
173
2.43.0
36
37
diff view generated by jsdifflib
New patch
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
tcg/optimize.c | 9 +++++----
5
1 file changed, 5 insertions(+), 4 deletions(-)
1
6
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/optimize.c
10
+++ b/tcg/optimize.c
11
@@ -XXX,XX +XXX,XX @@ static void finish_ebb(OptContext *ctx)
12
remove_mem_copy_all(ctx);
13
}
14
15
-static void finish_folding(OptContext *ctx, TCGOp *op)
16
+static bool finish_folding(OptContext *ctx, TCGOp *op)
17
{
18
const TCGOpDef *def = &tcg_op_defs[op->opc];
19
int i, nb_oargs;
20
@@ -XXX,XX +XXX,XX @@ static void finish_folding(OptContext *ctx, TCGOp *op)
21
ts_info(ts)->z_mask = ctx->z_mask;
22
}
23
}
24
+ return true;
25
}
26
27
/*
28
@@ -XXX,XX +XXX,XX @@ static bool fold_add(OptContext *ctx, TCGOp *op)
29
fold_xi_to_x(ctx, op, 0)) {
30
return true;
31
}
32
- return false;
33
+ return finish_folding(ctx, op);
34
}
35
36
/* We cannot as yet do_constant_folding with vectors. */
37
@@ -XXX,XX +XXX,XX @@ static bool fold_add_vec(OptContext *ctx, TCGOp *op)
38
fold_xi_to_x(ctx, op, 0)) {
39
return true;
40
}
41
- return false;
42
+ return finish_folding(ctx, op);
43
}
44
45
static bool fold_addsub2(OptContext *ctx, TCGOp *op, bool add)
46
@@ -XXX,XX +XXX,XX @@ static bool fold_addsub2(OptContext *ctx, TCGOp *op, bool add)
47
op->args[4] = arg_new_constant(ctx, bl);
48
op->args[5] = arg_new_constant(ctx, bh);
49
}
50
- return false;
51
+ return finish_folding(ctx, op);
52
}
53
54
static bool fold_add2(OptContext *ctx, TCGOp *op)
55
--
56
2.43.0
diff view generated by jsdifflib
1
The function is now trivial, and with inlining we can
1
Introduce ti_is_const, ti_const_val, ti_is_const_val.
2
re-use the calling function's tcg_ops variable.
3
2
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
4
---
6
accel/tcg/cpu-exec.c | 17 ++---------------
5
tcg/optimize.c | 20 +++++++++++++++++---
7
1 file changed, 2 insertions(+), 15 deletions(-)
6
1 file changed, 17 insertions(+), 3 deletions(-)
8
7
9
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
8
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
9
index XXXXXXX..XXXXXXX 100644
11
--- a/accel/tcg/cpu-exec.c
10
--- a/tcg/optimize.c
12
+++ b/accel/tcg/cpu-exec.c
11
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
12
@@ -XXX,XX +XXX,XX @@ static inline TempOptInfo *arg_info(TCGArg arg)
14
return false;
13
return ts_info(arg_temp(arg));
15
}
14
}
16
15
17
-#ifndef CONFIG_USER_ONLY
16
+static inline bool ti_is_const(TempOptInfo *ti)
18
-/*
17
+{
19
- * CPU_INTERRUPT_POLL is a virtual event which gets converted into a
18
+ return ti->is_const;
20
- * "real" interrupt event later. It does not need to be recorded for
19
+}
21
- * replay purposes.
20
+
22
- */
21
+static inline uint64_t ti_const_val(TempOptInfo *ti)
23
-static inline bool need_replay_interrupt(CPUState *cpu, int interrupt_request)
22
+{
24
-{
23
+ return ti->val;
25
- const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
24
+}
26
- return !tcg_ops->need_replay_interrupt
25
+
27
- || tcg_ops->need_replay_interrupt(interrupt_request);
26
+static inline bool ti_is_const_val(TempOptInfo *ti, uint64_t val)
28
-}
27
+{
29
-#endif /* !CONFIG_USER_ONLY */
28
+ return ti_is_const(ti) && ti_const_val(ti) == val;
30
-
29
+}
31
static inline bool icount_exit_request(CPUState *cpu)
30
+
31
static inline bool ts_is_const(TCGTemp *ts)
32
{
32
{
33
if (!icount_enabled()) {
33
- return ts_info(ts)->is_const;
34
@@ -XXX,XX +XXX,XX @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
34
+ return ti_is_const(ts_info(ts));
35
35
}
36
if (tcg_ops->cpu_exec_interrupt &&
36
37
tcg_ops->cpu_exec_interrupt(cpu, interrupt_request)) {
37
static inline bool ts_is_const_val(TCGTemp *ts, uint64_t val)
38
- if (need_replay_interrupt(cpu, interrupt_request)) {
38
{
39
+ if (!tcg_ops->need_replay_interrupt ||
39
- TempOptInfo *ti = ts_info(ts);
40
+ tcg_ops->need_replay_interrupt(interrupt_request)) {
40
- return ti->is_const && ti->val == val;
41
replay_interrupt();
41
+ return ti_is_const_val(ts_info(ts), val);
42
}
42
}
43
/*
43
44
static inline bool arg_is_const(TCGArg arg)
44
--
45
--
45
2.34.1
46
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
2
Sink mask computation below fold_affected_mask early exit.
1
3
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
tcg/optimize.c | 30 ++++++++++++++++--------------
8
1 file changed, 16 insertions(+), 14 deletions(-)
9
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/optimize.c
13
+++ b/tcg/optimize.c
14
@@ -XXX,XX +XXX,XX @@ static bool fold_add2(OptContext *ctx, TCGOp *op)
15
16
static bool fold_and(OptContext *ctx, TCGOp *op)
17
{
18
- uint64_t z1, z2;
19
+ uint64_t z1, z2, z_mask, s_mask;
20
+ TempOptInfo *t1, *t2;
21
22
if (fold_const2_commutative(ctx, op) ||
23
fold_xi_to_i(ctx, op, 0) ||
24
@@ -XXX,XX +XXX,XX @@ static bool fold_and(OptContext *ctx, TCGOp *op)
25
return true;
26
}
27
28
- z1 = arg_info(op->args[1])->z_mask;
29
- z2 = arg_info(op->args[2])->z_mask;
30
- ctx->z_mask = z1 & z2;
31
-
32
- /*
33
- * Sign repetitions are perforce all identical, whether they are 1 or 0.
34
- * Bitwise operations preserve the relative quantity of the repetitions.
35
- */
36
- ctx->s_mask = arg_info(op->args[1])->s_mask
37
- & arg_info(op->args[2])->s_mask;
38
+ t1 = arg_info(op->args[1]);
39
+ t2 = arg_info(op->args[2]);
40
+ z1 = t1->z_mask;
41
+ z2 = t2->z_mask;
42
43
/*
44
* Known-zeros does not imply known-ones. Therefore unless
45
* arg2 is constant, we can't infer affected bits from it.
46
*/
47
- if (arg_is_const(op->args[2]) &&
48
- fold_affected_mask(ctx, op, z1 & ~z2)) {
49
+ if (ti_is_const(t2) && fold_affected_mask(ctx, op, z1 & ~z2)) {
50
return true;
51
}
52
53
- return fold_masks(ctx, op);
54
+ z_mask = z1 & z2;
55
+
56
+ /*
57
+ * Sign repetitions are perforce all identical, whether they are 1 or 0.
58
+ * Bitwise operations preserve the relative quantity of the repetitions.
59
+ */
60
+ s_mask = t1->s_mask & t2->s_mask;
61
+
62
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
63
}
64
65
static bool fold_andc(OptContext *ctx, TCGOp *op)
66
--
67
2.43.0
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
2
Avoid double inversion of the value of second const operand.
2
3
3
In order to make accel/tcg/ target agnostic,
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
introduce the cpu_exec_halt() handler.
5
6
Reviewed-by: Anton Johansson <anjo@rev.ng>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-Id: <20240124101639.30056-9-philmd@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
6
---
12
include/hw/core/tcg-cpu-ops.h | 2 ++
7
tcg/optimize.c | 21 +++++++++++----------
13
accel/tcg/cpu-exec.c | 5 +++++
8
1 file changed, 11 insertions(+), 10 deletions(-)
14
2 files changed, 7 insertions(+)
15
9
16
diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
17
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/core/tcg-cpu-ops.h
12
--- a/tcg/optimize.c
19
+++ b/include/hw/core/tcg-cpu-ops.h
13
+++ b/tcg/optimize.c
20
@@ -XXX,XX +XXX,XX @@ struct TCGCPUOps {
14
@@ -XXX,XX +XXX,XX @@ static bool fold_and(OptContext *ctx, TCGOp *op)
21
void (*do_interrupt)(CPUState *cpu);
15
22
/** @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec */
16
static bool fold_andc(OptContext *ctx, TCGOp *op)
23
bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request);
24
+ /** @cpu_exec_halt: Callback for handling halt in cpu_exec */
25
+ void (*cpu_exec_halt)(CPUState *cpu);
26
/**
27
* @tlb_fill: Handle a softmmu tlb miss
28
*
29
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/accel/tcg/cpu-exec.c
32
+++ b/accel/tcg/cpu-exec.c
33
@@ -XXX,XX +XXX,XX @@ static inline bool cpu_handle_halt(CPUState *cpu)
34
{
17
{
35
#ifndef CONFIG_USER_ONLY
18
- uint64_t z1;
36
if (cpu->halted) {
19
+ uint64_t z_mask, s_mask;
37
+ const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
20
+ TempOptInfo *t1, *t2;
38
+
21
39
#if defined(TARGET_I386)
22
if (fold_const2(ctx, op) ||
40
if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
23
fold_xx_to_i(ctx, op, 0) ||
41
X86CPU *x86_cpu = X86_CPU(cpu);
24
@@ -XXX,XX +XXX,XX @@ static bool fold_andc(OptContext *ctx, TCGOp *op)
42
@@ -XXX,XX +XXX,XX @@ static inline bool cpu_handle_halt(CPUState *cpu)
25
return true;
43
bql_unlock();
26
}
44
}
27
45
#endif /* TARGET_I386 */
28
- z1 = arg_info(op->args[1])->z_mask;
46
+ if (tcg_ops->cpu_exec_halt) {
29
+ t1 = arg_info(op->args[1]);
47
+ tcg_ops->cpu_exec_halt(cpu);
30
+ t2 = arg_info(op->args[2]);
48
+ }
31
+ z_mask = t1->z_mask;
49
if (!cpu_has_work(cpu)) {
32
33
/*
34
* Known-zeros does not imply known-ones. Therefore unless
35
* arg2 is constant, we can't infer anything from it.
36
*/
37
- if (arg_is_const(op->args[2])) {
38
- uint64_t z2 = ~arg_info(op->args[2])->z_mask;
39
- if (fold_affected_mask(ctx, op, z1 & ~z2)) {
40
+ if (ti_is_const(t2)) {
41
+ uint64_t v2 = ti_const_val(t2);
42
+ if (fold_affected_mask(ctx, op, z_mask & v2)) {
50
return true;
43
return true;
51
}
44
}
45
- z1 &= z2;
46
+ z_mask &= ~v2;
47
}
48
- ctx->z_mask = z1;
49
50
- ctx->s_mask = arg_info(op->args[1])->s_mask
51
- & arg_info(op->args[2])->s_mask;
52
- return fold_masks(ctx, op);
53
+ s_mask = t1->s_mask & t2->s_mask;
54
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
55
}
56
57
static bool fold_brcond(OptContext *ctx, TCGOp *op)
52
--
58
--
53
2.34.1
59
2.43.0
54
55
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
2
Always set s_mask along the BSWAP_OS path, since the result is
3
being explicitly sign-extended.
1
4
5
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
tcg/optimize.c | 21 ++++++++++-----------
9
1 file changed, 10 insertions(+), 11 deletions(-)
10
11
diff --git a/tcg/optimize.c b/tcg/optimize.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/tcg/optimize.c
14
+++ b/tcg/optimize.c
15
@@ -XXX,XX +XXX,XX @@ static bool fold_brcond2(OptContext *ctx, TCGOp *op)
16
static bool fold_bswap(OptContext *ctx, TCGOp *op)
17
{
18
uint64_t z_mask, s_mask, sign;
19
+ TempOptInfo *t1 = arg_info(op->args[1]);
20
21
- if (arg_is_const(op->args[1])) {
22
- uint64_t t = arg_info(op->args[1])->val;
23
-
24
- t = do_constant_folding(op->opc, ctx->type, t, op->args[2]);
25
- return tcg_opt_gen_movi(ctx, op, op->args[0], t);
26
+ if (ti_is_const(t1)) {
27
+ return tcg_opt_gen_movi(ctx, op, op->args[0],
28
+ do_constant_folding(op->opc, ctx->type,
29
+ ti_const_val(t1),
30
+ op->args[2]));
31
}
32
33
- z_mask = arg_info(op->args[1])->z_mask;
34
-
35
+ z_mask = t1->z_mask;
36
switch (op->opc) {
37
case INDEX_op_bswap16_i32:
38
case INDEX_op_bswap16_i64:
39
@@ -XXX,XX +XXX,XX @@ static bool fold_bswap(OptContext *ctx, TCGOp *op)
40
/* If the sign bit may be 1, force all the bits above to 1. */
41
if (z_mask & sign) {
42
z_mask |= sign;
43
- s_mask = sign << 1;
44
}
45
+ /* The value and therefore s_mask is explicitly sign-extended. */
46
+ s_mask = sign;
47
break;
48
default:
49
/* The high bits are undefined: force all bits above the sign to 1. */
50
z_mask |= sign << 1;
51
break;
52
}
53
- ctx->z_mask = z_mask;
54
- ctx->s_mask = s_mask;
55
56
- return fold_masks(ctx, op);
57
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
58
}
59
60
static bool fold_call(OptContext *ctx, TCGOp *op)
61
--
62
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
2
Compute s_mask from the union of the maximum count and the
3
op2 fallback for op1 being zero.
1
4
5
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
tcg/optimize.c | 15 ++++++++++-----
9
1 file changed, 10 insertions(+), 5 deletions(-)
10
11
diff --git a/tcg/optimize.c b/tcg/optimize.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/tcg/optimize.c
14
+++ b/tcg/optimize.c
15
@@ -XXX,XX +XXX,XX @@ static bool fold_call(OptContext *ctx, TCGOp *op)
16
17
static bool fold_count_zeros(OptContext *ctx, TCGOp *op)
18
{
19
- uint64_t z_mask;
20
+ uint64_t z_mask, s_mask;
21
+ TempOptInfo *t1 = arg_info(op->args[1]);
22
+ TempOptInfo *t2 = arg_info(op->args[2]);
23
24
- if (arg_is_const(op->args[1])) {
25
- uint64_t t = arg_info(op->args[1])->val;
26
+ if (ti_is_const(t1)) {
27
+ uint64_t t = ti_const_val(t1);
28
29
if (t != 0) {
30
t = do_constant_folding(op->opc, ctx->type, t, 0);
31
@@ -XXX,XX +XXX,XX @@ static bool fold_count_zeros(OptContext *ctx, TCGOp *op)
32
default:
33
g_assert_not_reached();
34
}
35
- ctx->z_mask = arg_info(op->args[2])->z_mask | z_mask;
36
- return false;
37
+ s_mask = ~z_mask;
38
+ z_mask |= t2->z_mask;
39
+ s_mask &= t2->s_mask;
40
+
41
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
42
}
43
44
static bool fold_ctpop(OptContext *ctx, TCGOp *op)
45
--
46
2.43.0
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
Add fold_masks_z as a trivial wrapper around fold_masks_zs.
2
Avoid the use of the OptContext slots.
2
3
3
Move this x86-specific code out of the generic accel/tcg/.
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
5
Reported-by: Anton Johansson <anjo@rev.ng>
6
Reviewed-by: Anton Johansson <anjo@rev.ng>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-Id: <20240124101639.30056-10-philmd@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
6
---
12
target/i386/tcg/helper-tcg.h | 1 +
7
tcg/optimize.c | 13 ++++++++++---
13
accel/tcg/cpu-exec.c | 12 ------------
8
1 file changed, 10 insertions(+), 3 deletions(-)
14
target/i386/tcg/sysemu/seg_helper.c | 13 +++++++++++++
15
target/i386/tcg/tcg-cpu.c | 1 +
16
4 files changed, 15 insertions(+), 12 deletions(-)
17
9
18
diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
19
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
20
--- a/target/i386/tcg/helper-tcg.h
12
--- a/tcg/optimize.c
21
+++ b/target/i386/tcg/helper-tcg.h
13
+++ b/tcg/optimize.c
22
@@ -XXX,XX +XXX,XX @@ QEMU_BUILD_BUG_ON(TCG_PHYS_ADDR_BITS > TARGET_PHYS_ADDR_SPACE_BITS);
14
@@ -XXX,XX +XXX,XX @@ static bool fold_masks_zs(OptContext *ctx, TCGOp *op,
23
*/
15
return true;
24
void x86_cpu_do_interrupt(CPUState *cpu);
25
#ifndef CONFIG_USER_ONLY
26
+void x86_cpu_exec_halt(CPUState *cpu);
27
bool x86_need_replay_interrupt(int interrupt_request);
28
bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
29
#endif
30
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/accel/tcg/cpu-exec.c
33
+++ b/accel/tcg/cpu-exec.c
34
@@ -XXX,XX +XXX,XX @@
35
#include "qemu/rcu.h"
36
#include "exec/log.h"
37
#include "qemu/main-loop.h"
38
-#if defined(TARGET_I386) && !defined(CONFIG_USER_ONLY)
39
-#include "hw/i386/apic.h"
40
-#endif
41
#include "sysemu/cpus.h"
42
#include "exec/cpu-all.h"
43
#include "sysemu/cpu-timers.h"
44
@@ -XXX,XX +XXX,XX @@ static inline bool cpu_handle_halt(CPUState *cpu)
45
if (cpu->halted) {
46
const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
47
48
-#if defined(TARGET_I386)
49
- if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
50
- X86CPU *x86_cpu = X86_CPU(cpu);
51
- bql_lock();
52
- apic_poll_irq(x86_cpu->apic_state);
53
- cpu_reset_interrupt(cpu, CPU_INTERRUPT_POLL);
54
- bql_unlock();
55
- }
56
-#endif /* TARGET_I386 */
57
if (tcg_ops->cpu_exec_halt) {
58
tcg_ops->cpu_exec_halt(cpu);
59
}
60
diff --git a/target/i386/tcg/sysemu/seg_helper.c b/target/i386/tcg/sysemu/seg_helper.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/i386/tcg/sysemu/seg_helper.c
63
+++ b/target/i386/tcg/sysemu/seg_helper.c
64
@@ -XXX,XX +XXX,XX @@
65
66
#include "qemu/osdep.h"
67
#include "qemu/log.h"
68
+#include "qemu/main-loop.h"
69
#include "cpu.h"
70
#include "exec/helper-proto.h"
71
#include "exec/cpu_ldst.h"
72
@@ -XXX,XX +XXX,XX @@ void x86_cpu_do_interrupt(CPUState *cs)
73
}
74
}
16
}
75
17
76
+void x86_cpu_exec_halt(CPUState *cpu)
18
+static bool fold_masks_z(OptContext *ctx, TCGOp *op, uint64_t z_mask)
77
+{
19
+{
78
+ if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
20
+ return fold_masks_zs(ctx, op, z_mask, 0);
79
+ X86CPU *x86_cpu = X86_CPU(cpu);
80
+
81
+ bql_lock();
82
+ apic_poll_irq(x86_cpu->apic_state);
83
+ cpu_reset_interrupt(cpu, CPU_INTERRUPT_POLL);
84
+ bql_unlock();
85
+ }
86
+}
21
+}
87
+
22
+
88
bool x86_need_replay_interrupt(int interrupt_request)
23
static bool fold_masks(OptContext *ctx, TCGOp *op)
89
{
24
{
90
/*
25
return fold_masks_zs(ctx, op, ctx->z_mask, ctx->s_mask);
91
diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c
26
@@ -XXX,XX +XXX,XX @@ static bool fold_count_zeros(OptContext *ctx, TCGOp *op)
92
index XXXXXXX..XXXXXXX 100644
27
93
--- a/target/i386/tcg/tcg-cpu.c
28
static bool fold_ctpop(OptContext *ctx, TCGOp *op)
94
+++ b/target/i386/tcg/tcg-cpu.c
29
{
95
@@ -XXX,XX +XXX,XX @@ static const TCGCPUOps x86_tcg_ops = {
30
+ uint64_t z_mask;
96
#else
31
+
97
.tlb_fill = x86_cpu_tlb_fill,
32
if (fold_const1(ctx, op)) {
98
.do_interrupt = x86_cpu_do_interrupt,
33
return true;
99
+ .cpu_exec_halt = x86_cpu_exec_halt,
34
}
100
.cpu_exec_interrupt = x86_cpu_exec_interrupt,
35
101
.do_unaligned_access = x86_cpu_do_unaligned_access,
36
switch (ctx->type) {
102
.debug_excp_handler = breakpoint_handler,
37
case TCG_TYPE_I32:
38
- ctx->z_mask = 32 | 31;
39
+ z_mask = 32 | 31;
40
break;
41
case TCG_TYPE_I64:
42
- ctx->z_mask = 64 | 63;
43
+ z_mask = 64 | 63;
44
break;
45
default:
46
g_assert_not_reached();
47
}
48
- return false;
49
+ return fold_masks_z(ctx, op, z_mask);
50
}
51
52
static bool fold_deposit(OptContext *ctx, TCGOp *op)
103
--
53
--
104
2.34.1
54
2.43.0
105
106
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
2
When we fold to and, use fold_and.
1
3
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
tcg/optimize.c | 35 +++++++++++++++++------------------
8
1 file changed, 17 insertions(+), 18 deletions(-)
9
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/optimize.c
13
+++ b/tcg/optimize.c
14
@@ -XXX,XX +XXX,XX @@ static bool fold_ctpop(OptContext *ctx, TCGOp *op)
15
16
static bool fold_deposit(OptContext *ctx, TCGOp *op)
17
{
18
+ TempOptInfo *t1 = arg_info(op->args[1]);
19
+ TempOptInfo *t2 = arg_info(op->args[2]);
20
+ int ofs = op->args[3];
21
+ int len = op->args[4];
22
TCGOpcode and_opc;
23
+ uint64_t z_mask;
24
25
- if (arg_is_const(op->args[1]) && arg_is_const(op->args[2])) {
26
- uint64_t t1 = arg_info(op->args[1])->val;
27
- uint64_t t2 = arg_info(op->args[2])->val;
28
-
29
- t1 = deposit64(t1, op->args[3], op->args[4], t2);
30
- return tcg_opt_gen_movi(ctx, op, op->args[0], t1);
31
+ if (ti_is_const(t1) && ti_is_const(t2)) {
32
+ return tcg_opt_gen_movi(ctx, op, op->args[0],
33
+ deposit64(ti_const_val(t1), ofs, len,
34
+ ti_const_val(t2)));
35
}
36
37
switch (ctx->type) {
38
@@ -XXX,XX +XXX,XX @@ static bool fold_deposit(OptContext *ctx, TCGOp *op)
39
}
40
41
/* Inserting a value into zero at offset 0. */
42
- if (arg_is_const_val(op->args[1], 0) && op->args[3] == 0) {
43
- uint64_t mask = MAKE_64BIT_MASK(0, op->args[4]);
44
+ if (ti_is_const_val(t1, 0) && ofs == 0) {
45
+ uint64_t mask = MAKE_64BIT_MASK(0, len);
46
47
op->opc = and_opc;
48
op->args[1] = op->args[2];
49
op->args[2] = arg_new_constant(ctx, mask);
50
- ctx->z_mask = mask & arg_info(op->args[1])->z_mask;
51
- return false;
52
+ return fold_and(ctx, op);
53
}
54
55
/* Inserting zero into a value. */
56
- if (arg_is_const_val(op->args[2], 0)) {
57
- uint64_t mask = deposit64(-1, op->args[3], op->args[4], 0);
58
+ if (ti_is_const_val(t2, 0)) {
59
+ uint64_t mask = deposit64(-1, ofs, len, 0);
60
61
op->opc = and_opc;
62
op->args[2] = arg_new_constant(ctx, mask);
63
- ctx->z_mask = mask & arg_info(op->args[1])->z_mask;
64
- return false;
65
+ return fold_and(ctx, op);
66
}
67
68
- ctx->z_mask = deposit64(arg_info(op->args[1])->z_mask,
69
- op->args[3], op->args[4],
70
- arg_info(op->args[2])->z_mask);
71
- return false;
72
+ z_mask = deposit64(t1->z_mask, ofs, len, t2->z_mask);
73
+ return fold_masks_z(ctx, op, z_mask);
74
}
75
76
static bool fold_divide(OptContext *ctx, TCGOp *op)
77
--
78
2.43.0
diff view generated by jsdifflib
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
The input which overlaps the sign bit of the output can
2
have its input s_mask propagated to the output s_mask.
2
3
3
Unless I'm missing something egregious, the jmp cache is only every
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
populated with a valid entry by the same thread that reads the cache.
5
Therefore, the contents of any valid entry are always consistent and
6
there is no need for any acquire/release magic.
7
8
Indeed ->tb has to be accessed with atomics, because concurrent
9
invalidations would otherwise cause data races. But ->pc is only ever
10
accessed by one thread, and accesses to ->tb and ->pc within tb_lookup
11
can never race with another tb_lookup. While the TranslationBlock
12
(especially the flags) could be modified by a concurrent invalidation,
13
store-release and load-acquire operations on the cache entry would
14
not add any additional ordering beyond what you get from performing
15
the accesses within a single thread.
16
17
Because of this, there is really nothing to win in splitting the CF_PCREL
18
and !CF_PCREL paths. It is easier to just always use the ->pc field in
19
the jump cache.
20
21
I noticed this while working on splitting commit 8ed558ec0cb
22
("accel/tcg: Introduce TARGET_TB_PCREL", 2022-10-04) into multiple
23
pieces, for the sake of finding a more fine-grained bisection
24
result for https://gitlab.com/qemu-project/qemu/-/issues/2092.
25
It does not (and does not intend to) fix that issue; therefore
26
it may make sense to not commit it until the root cause
27
of issue #2092 is found.
28
29
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
30
Tested-by: Alex Bennée <alex.bennee@linaro.org>
31
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
32
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
33
Message-Id: <20240122153409.351959-1-pbonzini@redhat.com>
34
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
35
---
6
---
36
accel/tcg/tb-jmp-cache.h | 8 +++--
7
tcg/optimize.c | 14 ++++++++++++--
37
accel/tcg/cpu-exec.c | 66 ++++++++++++++--------------------------
8
1 file changed, 12 insertions(+), 2 deletions(-)
38
2 files changed, 28 insertions(+), 46 deletions(-)
39
9
40
diff --git a/accel/tcg/tb-jmp-cache.h b/accel/tcg/tb-jmp-cache.h
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
41
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
42
--- a/accel/tcg/tb-jmp-cache.h
12
--- a/tcg/optimize.c
43
+++ b/accel/tcg/tb-jmp-cache.h
13
+++ b/tcg/optimize.c
44
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static bool fold_deposit(OptContext *ctx, TCGOp *op)
45
#define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
15
TempOptInfo *t2 = arg_info(op->args[2]);
46
16
int ofs = op->args[3];
47
/*
17
int len = op->args[4];
48
- * Accessed in parallel; all accesses to 'tb' must be atomic.
18
+ int width;
49
- * For CF_PCREL, accesses to 'pc' must be protected by a
19
TCGOpcode and_opc;
50
- * load_acquire/store_release to 'tb'.
20
- uint64_t z_mask;
51
+ * Invalidated in parallel; all accesses to 'tb' must be atomic.
21
+ uint64_t z_mask, s_mask;
52
+ * A valid entry is read/written by a single CPU, therefore there is
22
53
+ * no need for qatomic_rcu_read() and pc is always consistent with a
23
if (ti_is_const(t1) && ti_is_const(t2)) {
54
+ * non-NULL value of 'tb'. Strictly speaking pc is only needed for
24
return tcg_opt_gen_movi(ctx, op, op->args[0],
55
+ * CF_PCREL, but it's used always for simplicity.
25
@@ -XXX,XX +XXX,XX @@ static bool fold_deposit(OptContext *ctx, TCGOp *op)
56
*/
26
switch (ctx->type) {
57
struct CPUJumpCache {
27
case TCG_TYPE_I32:
58
struct rcu_head rcu;
28
and_opc = INDEX_op_and_i32;
59
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
29
+ width = 32;
60
index XXXXXXX..XXXXXXX 100644
30
break;
61
--- a/accel/tcg/cpu-exec.c
31
case TCG_TYPE_I64:
62
+++ b/accel/tcg/cpu-exec.c
32
and_opc = INDEX_op_and_i64;
63
@@ -XXX,XX +XXX,XX @@ static inline TranslationBlock *tb_lookup(CPUState *cpu, vaddr pc,
33
+ width = 64;
64
hash = tb_jmp_cache_hash_func(pc);
34
break;
65
jc = cpu->tb_jmp_cache;
35
default:
66
36
g_assert_not_reached();
67
- if (cflags & CF_PCREL) {
37
@@ -XXX,XX +XXX,XX @@ static bool fold_deposit(OptContext *ctx, TCGOp *op)
68
- /* Use acquire to ensure current load of pc from jc. */
38
return fold_and(ctx, op);
69
- tb = qatomic_load_acquire(&jc->array[hash].tb);
70
-
71
- if (likely(tb &&
72
- jc->array[hash].pc == pc &&
73
- tb->cs_base == cs_base &&
74
- tb->flags == flags &&
75
- tb_cflags(tb) == cflags)) {
76
- return tb;
77
- }
78
- tb = tb_htable_lookup(cpu, pc, cs_base, flags, cflags);
79
- if (tb == NULL) {
80
- return NULL;
81
- }
82
- jc->array[hash].pc = pc;
83
- /* Ensure pc is written first. */
84
- qatomic_store_release(&jc->array[hash].tb, tb);
85
- } else {
86
- /* Use rcu_read to ensure current load of pc from *tb. */
87
- tb = qatomic_rcu_read(&jc->array[hash].tb);
88
-
89
- if (likely(tb &&
90
- tb->pc == pc &&
91
- tb->cs_base == cs_base &&
92
- tb->flags == flags &&
93
- tb_cflags(tb) == cflags)) {
94
- return tb;
95
- }
96
- tb = tb_htable_lookup(cpu, pc, cs_base, flags, cflags);
97
- if (tb == NULL) {
98
- return NULL;
99
- }
100
- /* Use the pc value already stored in tb->pc. */
101
- qatomic_set(&jc->array[hash].tb, tb);
102
+ tb = qatomic_read(&jc->array[hash].tb);
103
+ if (likely(tb &&
104
+ jc->array[hash].pc == pc &&
105
+ tb->cs_base == cs_base &&
106
+ tb->flags == flags &&
107
+ tb_cflags(tb) == cflags)) {
108
+ goto hit;
109
}
39
}
110
40
111
+ tb = tb_htable_lookup(cpu, pc, cs_base, flags, cflags);
41
+ /* The s_mask from the top portion of the deposit is still valid. */
112
+ if (tb == NULL) {
42
+ if (ofs + len == width) {
113
+ return NULL;
43
+ s_mask = t2->s_mask << ofs;
44
+ } else {
45
+ s_mask = t1->s_mask & ~MAKE_64BIT_MASK(0, ofs + len);
114
+ }
46
+ }
115
+
47
+
116
+ jc->array[hash].pc = pc;
48
z_mask = deposit64(t1->z_mask, ofs, len, t2->z_mask);
117
+ qatomic_set(&jc->array[hash].tb, tb);
49
- return fold_masks_z(ctx, op, z_mask);
118
+
50
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
119
+hit:
120
+ /*
121
+ * As long as tb is not NULL, the contents are consistent. Therefore,
122
+ * the virtual PC has to match for non-CF_PCREL translations.
123
+ */
124
+ assert((tb_cflags(tb) & CF_PCREL) || tb->pc == pc);
125
return tb;
126
}
51
}
127
52
128
@@ -XXX,XX +XXX,XX @@ cpu_exec_loop(CPUState *cpu, SyncClocks *sc)
53
static bool fold_divide(OptContext *ctx, TCGOp *op)
129
*/
130
h = tb_jmp_cache_hash_func(pc);
131
jc = cpu->tb_jmp_cache;
132
- if (cflags & CF_PCREL) {
133
- jc->array[h].pc = pc;
134
- /* Ensure pc is written first. */
135
- qatomic_store_release(&jc->array[h].tb, tb);
136
- } else {
137
- /* Use the pc value already stored in tb->pc. */
138
- qatomic_set(&jc->array[h].tb, tb);
139
- }
140
+ jc->array[h].pc = pc;
141
+ qatomic_set(&jc->array[h].tb, tb);
142
}
143
144
#ifndef CONFIG_USER_ONLY
145
--
54
--
146
2.34.1
55
2.43.0
147
148
diff view generated by jsdifflib
New patch
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
tcg/optimize.c | 2 +-
5
1 file changed, 1 insertion(+), 1 deletion(-)
1
6
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/optimize.c
10
+++ b/tcg/optimize.c
11
@@ -XXX,XX +XXX,XX @@ static bool fold_divide(OptContext *ctx, TCGOp *op)
12
fold_xi_to_x(ctx, op, 1)) {
13
return true;
14
}
15
- return false;
16
+ return finish_folding(ctx, op);
17
}
18
19
static bool fold_dup(OptContext *ctx, TCGOp *op)
20
--
21
2.43.0
diff view generated by jsdifflib
New patch
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
tcg/optimize.c | 4 ++--
5
1 file changed, 2 insertions(+), 2 deletions(-)
1
6
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/optimize.c
10
+++ b/tcg/optimize.c
11
@@ -XXX,XX +XXX,XX @@ static bool fold_dup(OptContext *ctx, TCGOp *op)
12
t = dup_const(TCGOP_VECE(op), t);
13
return tcg_opt_gen_movi(ctx, op, op->args[0], t);
14
}
15
- return false;
16
+ return finish_folding(ctx, op);
17
}
18
19
static bool fold_dup2(OptContext *ctx, TCGOp *op)
20
@@ -XXX,XX +XXX,XX @@ static bool fold_dup2(OptContext *ctx, TCGOp *op)
21
op->opc = INDEX_op_dup_vec;
22
TCGOP_VECE(op) = MO_32;
23
}
24
- return false;
25
+ return finish_folding(ctx, op);
26
}
27
28
static bool fold_eqv(OptContext *ctx, TCGOp *op)
29
--
30
2.43.0
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
Add fold_masks_s as a trivial wrapper around fold_masks_zs.
2
Avoid the use of the OptContext slots.
2
3
3
Convert packed logic to dumb icount_exit_request() helper.
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
No functional change intended.
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Anton Johansson <anjo@rev.ng>
9
Message-Id: <20240124101639.30056-5-philmd@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
6
---
12
accel/tcg/cpu-exec.c | 16 ++++++++++++----
7
tcg/optimize.c | 13 ++++++++++---
13
1 file changed, 12 insertions(+), 4 deletions(-)
8
1 file changed, 10 insertions(+), 3 deletions(-)
14
9
15
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
16
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
17
--- a/accel/tcg/cpu-exec.c
12
--- a/tcg/optimize.c
18
+++ b/accel/tcg/cpu-exec.c
13
+++ b/tcg/optimize.c
19
@@ -XXX,XX +XXX,XX @@ static inline bool need_replay_interrupt(int interrupt_request)
14
@@ -XXX,XX +XXX,XX @@ static bool fold_masks_z(OptContext *ctx, TCGOp *op, uint64_t z_mask)
15
return fold_masks_zs(ctx, op, z_mask, 0);
20
}
16
}
21
#endif /* !CONFIG_USER_ONLY */
17
22
18
+static bool fold_masks_s(OptContext *ctx, TCGOp *op, uint64_t s_mask)
23
+static inline bool icount_exit_request(CPUState *cpu)
24
+{
19
+{
25
+ if (!icount_enabled()) {
20
+ return fold_masks_zs(ctx, op, -1, s_mask);
26
+ return false;
27
+ }
28
+ if (cpu->cflags_next_tb != -1 && !(cpu->cflags_next_tb & CF_USE_ICOUNT)) {
29
+ return false;
30
+ }
31
+ return cpu->neg.icount_decr.u16.low + cpu->icount_extra == 0;
32
+}
21
+}
33
+
22
+
34
static inline bool cpu_handle_interrupt(CPUState *cpu,
23
static bool fold_masks(OptContext *ctx, TCGOp *op)
35
TranslationBlock **last_tb)
36
{
24
{
37
@@ -XXX,XX +XXX,XX @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
25
return fold_masks_zs(ctx, op, ctx->z_mask, ctx->s_mask);
26
@@ -XXX,XX +XXX,XX @@ static bool fold_dup2(OptContext *ctx, TCGOp *op)
27
28
static bool fold_eqv(OptContext *ctx, TCGOp *op)
29
{
30
+ uint64_t s_mask;
31
+
32
if (fold_const2_commutative(ctx, op) ||
33
fold_xi_to_x(ctx, op, -1) ||
34
fold_xi_to_not(ctx, op, 0)) {
35
return true;
38
}
36
}
39
37
40
/* Finally, check if we need to exit to the main loop. */
38
- ctx->s_mask = arg_info(op->args[1])->s_mask
41
- if (unlikely(qatomic_read(&cpu->exit_request))
39
- & arg_info(op->args[2])->s_mask;
42
- || (icount_enabled()
40
- return false;
43
- && (cpu->cflags_next_tb == -1 || cpu->cflags_next_tb & CF_USE_ICOUNT)
41
+ s_mask = arg_info(op->args[1])->s_mask
44
- && cpu->neg.icount_decr.u16.low + cpu->icount_extra == 0)) {
42
+ & arg_info(op->args[2])->s_mask;
45
+ if (unlikely(qatomic_read(&cpu->exit_request)) || icount_exit_request(cpu)) {
43
+ return fold_masks_s(ctx, op, s_mask);
46
qatomic_set(&cpu->exit_request, 0);
44
}
47
if (cpu->exception_index == -1) {
45
48
cpu->exception_index = EXCP_INTERRUPT;
46
static bool fold_extract(OptContext *ctx, TCGOp *op)
49
--
47
--
50
2.34.1
48
2.43.0
51
52
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 15 ++++++---------
7
1 file changed, 6 insertions(+), 9 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_eqv(OptContext *ctx, TCGOp *op)
14
static bool fold_extract(OptContext *ctx, TCGOp *op)
15
{
16
uint64_t z_mask_old, z_mask;
17
+ TempOptInfo *t1 = arg_info(op->args[1]);
18
int pos = op->args[2];
19
int len = op->args[3];
20
21
- if (arg_is_const(op->args[1])) {
22
- uint64_t t;
23
-
24
- t = arg_info(op->args[1])->val;
25
- t = extract64(t, pos, len);
26
- return tcg_opt_gen_movi(ctx, op, op->args[0], t);
27
+ if (ti_is_const(t1)) {
28
+ return tcg_opt_gen_movi(ctx, op, op->args[0],
29
+ extract64(ti_const_val(t1), pos, len));
30
}
31
32
- z_mask_old = arg_info(op->args[1])->z_mask;
33
+ z_mask_old = t1->z_mask;
34
z_mask = extract64(z_mask_old, pos, len);
35
if (pos == 0 && fold_affected_mask(ctx, op, z_mask_old ^ z_mask)) {
36
return true;
37
}
38
- ctx->z_mask = z_mask;
39
40
- return fold_masks(ctx, op);
41
+ return fold_masks_z(ctx, op, z_mask);
42
}
43
44
static bool fold_extract2(OptContext *ctx, TCGOp *op)
45
--
46
2.43.0
diff view generated by jsdifflib
New patch
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
tcg/optimize.c | 2 +-
5
1 file changed, 1 insertion(+), 1 deletion(-)
1
6
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/optimize.c
10
+++ b/tcg/optimize.c
11
@@ -XXX,XX +XXX,XX @@ static bool fold_extract2(OptContext *ctx, TCGOp *op)
12
}
13
return tcg_opt_gen_movi(ctx, op, op->args[0], v1 | v2);
14
}
15
- return false;
16
+ return finish_folding(ctx, op);
17
}
18
19
static bool fold_exts(OptContext *ctx, TCGOp *op)
20
--
21
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
2
Explicitly sign-extend z_mask instead of doing that manually.
1
3
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
tcg/optimize.c | 29 ++++++++++++-----------------
8
1 file changed, 12 insertions(+), 17 deletions(-)
9
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/optimize.c
13
+++ b/tcg/optimize.c
14
@@ -XXX,XX +XXX,XX @@ static bool fold_extract2(OptContext *ctx, TCGOp *op)
15
16
static bool fold_exts(OptContext *ctx, TCGOp *op)
17
{
18
- uint64_t s_mask_old, s_mask, z_mask, sign;
19
+ uint64_t s_mask_old, s_mask, z_mask;
20
bool type_change = false;
21
+ TempOptInfo *t1;
22
23
if (fold_const1(ctx, op)) {
24
return true;
25
}
26
27
- z_mask = arg_info(op->args[1])->z_mask;
28
- s_mask = arg_info(op->args[1])->s_mask;
29
+ t1 = arg_info(op->args[1]);
30
+ z_mask = t1->z_mask;
31
+ s_mask = t1->s_mask;
32
s_mask_old = s_mask;
33
34
switch (op->opc) {
35
CASE_OP_32_64(ext8s):
36
- sign = INT8_MIN;
37
- z_mask = (uint8_t)z_mask;
38
+ s_mask |= INT8_MIN;
39
+ z_mask = (int8_t)z_mask;
40
break;
41
CASE_OP_32_64(ext16s):
42
- sign = INT16_MIN;
43
- z_mask = (uint16_t)z_mask;
44
+ s_mask |= INT16_MIN;
45
+ z_mask = (int16_t)z_mask;
46
break;
47
case INDEX_op_ext_i32_i64:
48
type_change = true;
49
QEMU_FALLTHROUGH;
50
case INDEX_op_ext32s_i64:
51
- sign = INT32_MIN;
52
- z_mask = (uint32_t)z_mask;
53
+ s_mask |= INT32_MIN;
54
+ z_mask = (int32_t)z_mask;
55
break;
56
default:
57
g_assert_not_reached();
58
}
59
60
- if (z_mask & sign) {
61
- z_mask |= sign;
62
- }
63
- s_mask |= sign << 1;
64
-
65
- ctx->z_mask = z_mask;
66
- ctx->s_mask = s_mask;
67
if (0 && !type_change && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
68
return true;
69
}
70
71
- return fold_masks(ctx, op);
72
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
73
}
74
75
static bool fold_extu(OptContext *ctx, TCGOp *op)
76
--
77
2.43.0
diff view generated by jsdifflib
1
From: Anton Johansson <anjo@rev.ng>
1
Avoid the use of the OptContext slots.
2
2
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Message-Id: <20240119144024.14289-11-anjo@rev.ng>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
5
---
8
include/exec/cpu_ldst.h | 4 ++--
6
tcg/optimize.c | 4 ++--
9
1 file changed, 2 insertions(+), 2 deletions(-)
7
1 file changed, 2 insertions(+), 2 deletions(-)
10
8
11
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
12
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
13
--- a/include/exec/cpu_ldst.h
11
--- a/tcg/optimize.c
14
+++ b/include/exec/cpu_ldst.h
12
+++ b/tcg/optimize.c
15
@@ -XXX,XX +XXX,XX @@ static inline bool guest_range_valid_untagged(abi_ulong start, abi_ulong len)
13
@@ -XXX,XX +XXX,XX @@ static bool fold_extu(OptContext *ctx, TCGOp *op)
16
h2g_nocheck(x); \
14
g_assert_not_reached();
17
})
15
}
18
#else
16
19
-typedef target_ulong abi_ptr;
17
- ctx->z_mask = z_mask;
20
-#define TARGET_ABI_FMT_ptr TARGET_FMT_lx
18
if (!type_change && fold_affected_mask(ctx, op, z_mask_old ^ z_mask)) {
21
+typedef vaddr abi_ptr;
19
return true;
22
+#define TARGET_ABI_FMT_ptr VADDR_PRIx
20
}
23
#endif
21
- return fold_masks(ctx, op);
24
22
+
25
uint32_t cpu_ldub_data(CPUArchState *env, abi_ptr ptr);
23
+ return fold_masks_z(ctx, op, z_mask);
24
}
25
26
static bool fold_mb(OptContext *ctx, TCGOp *op)
26
--
27
--
27
2.34.1
28
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 19 +++++++++++--------
7
1 file changed, 11 insertions(+), 8 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_mov(OptContext *ctx, TCGOp *op)
14
15
static bool fold_movcond(OptContext *ctx, TCGOp *op)
16
{
17
+ uint64_t z_mask, s_mask;
18
+ TempOptInfo *tt, *ft;
19
int i;
20
21
/* If true and false values are the same, eliminate the cmp. */
22
@@ -XXX,XX +XXX,XX @@ static bool fold_movcond(OptContext *ctx, TCGOp *op)
23
return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[4 - i]);
24
}
25
26
- ctx->z_mask = arg_info(op->args[3])->z_mask
27
- | arg_info(op->args[4])->z_mask;
28
- ctx->s_mask = arg_info(op->args[3])->s_mask
29
- & arg_info(op->args[4])->s_mask;
30
+ tt = arg_info(op->args[3]);
31
+ ft = arg_info(op->args[4]);
32
+ z_mask = tt->z_mask | ft->z_mask;
33
+ s_mask = tt->s_mask & ft->s_mask;
34
35
- if (arg_is_const(op->args[3]) && arg_is_const(op->args[4])) {
36
- uint64_t tv = arg_info(op->args[3])->val;
37
- uint64_t fv = arg_info(op->args[4])->val;
38
+ if (ti_is_const(tt) && ti_is_const(ft)) {
39
+ uint64_t tv = ti_const_val(tt);
40
+ uint64_t fv = ti_const_val(ft);
41
TCGOpcode opc, negopc = 0;
42
TCGCond cond = op->args[5];
43
44
@@ -XXX,XX +XXX,XX @@ static bool fold_movcond(OptContext *ctx, TCGOp *op)
45
}
46
}
47
}
48
- return false;
49
+
50
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
51
}
52
53
static bool fold_mul(OptContext *ctx, TCGOp *op)
54
--
55
2.43.0
diff view generated by jsdifflib
New patch
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
tcg/optimize.c | 6 +++---
5
1 file changed, 3 insertions(+), 3 deletions(-)
1
6
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/optimize.c
10
+++ b/tcg/optimize.c
11
@@ -XXX,XX +XXX,XX @@ static bool fold_mul(OptContext *ctx, TCGOp *op)
12
fold_xi_to_x(ctx, op, 1)) {
13
return true;
14
}
15
- return false;
16
+ return finish_folding(ctx, op);
17
}
18
19
static bool fold_mul_highpart(OptContext *ctx, TCGOp *op)
20
@@ -XXX,XX +XXX,XX @@ static bool fold_mul_highpart(OptContext *ctx, TCGOp *op)
21
fold_xi_to_i(ctx, op, 0)) {
22
return true;
23
}
24
- return false;
25
+ return finish_folding(ctx, op);
26
}
27
28
static bool fold_multiply2(OptContext *ctx, TCGOp *op)
29
@@ -XXX,XX +XXX,XX @@ static bool fold_multiply2(OptContext *ctx, TCGOp *op)
30
tcg_opt_gen_movi(ctx, op2, rh, h);
31
return true;
32
}
33
- return false;
34
+ return finish_folding(ctx, op);
35
}
36
37
static bool fold_nand(OptContext *ctx, TCGOp *op)
38
--
39
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 8 +++++---
7
1 file changed, 5 insertions(+), 3 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_multiply2(OptContext *ctx, TCGOp *op)
14
15
static bool fold_nand(OptContext *ctx, TCGOp *op)
16
{
17
+ uint64_t s_mask;
18
+
19
if (fold_const2_commutative(ctx, op) ||
20
fold_xi_to_not(ctx, op, -1)) {
21
return true;
22
}
23
24
- ctx->s_mask = arg_info(op->args[1])->s_mask
25
- & arg_info(op->args[2])->s_mask;
26
- return false;
27
+ s_mask = arg_info(op->args[1])->s_mask
28
+ & arg_info(op->args[2])->s_mask;
29
+ return fold_masks_s(ctx, op, s_mask);
30
}
31
32
static bool fold_neg_no_const(OptContext *ctx, TCGOp *op)
33
--
34
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 9 ++-------
7
1 file changed, 2 insertions(+), 7 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_neg_no_const(OptContext *ctx, TCGOp *op)
14
{
15
/* Set to 1 all bits to the left of the rightmost. */
16
uint64_t z_mask = arg_info(op->args[1])->z_mask;
17
- ctx->z_mask = -(z_mask & -z_mask);
18
+ z_mask = -(z_mask & -z_mask);
19
20
- /*
21
- * Because of fold_sub_to_neg, we want to always return true,
22
- * via finish_folding.
23
- */
24
- finish_folding(ctx, op);
25
- return true;
26
+ return fold_masks_z(ctx, op, z_mask);
27
}
28
29
static bool fold_neg(OptContext *ctx, TCGOp *op)
30
--
31
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 8 +++++---
7
1 file changed, 5 insertions(+), 3 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_neg(OptContext *ctx, TCGOp *op)
14
15
static bool fold_nor(OptContext *ctx, TCGOp *op)
16
{
17
+ uint64_t s_mask;
18
+
19
if (fold_const2_commutative(ctx, op) ||
20
fold_xi_to_not(ctx, op, 0)) {
21
return true;
22
}
23
24
- ctx->s_mask = arg_info(op->args[1])->s_mask
25
- & arg_info(op->args[2])->s_mask;
26
- return false;
27
+ s_mask = arg_info(op->args[1])->s_mask
28
+ & arg_info(op->args[2])->s_mask;
29
+ return fold_masks_s(ctx, op, s_mask);
30
}
31
32
static bool fold_not(OptContext *ctx, TCGOp *op)
33
--
34
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 7 +------
7
1 file changed, 1 insertion(+), 6 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_not(OptContext *ctx, TCGOp *op)
14
if (fold_const1(ctx, op)) {
15
return true;
16
}
17
-
18
- ctx->s_mask = arg_info(op->args[1])->s_mask;
19
-
20
- /* Because of fold_to_not, we want to always return true, via finish. */
21
- finish_folding(ctx, op);
22
- return true;
23
+ return fold_masks_s(ctx, op, arg_info(op->args[1])->s_mask);
24
}
25
26
static bool fold_or(OptContext *ctx, TCGOp *op)
27
--
28
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 13 ++++++++-----
7
1 file changed, 8 insertions(+), 5 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_not(OptContext *ctx, TCGOp *op)
14
15
static bool fold_or(OptContext *ctx, TCGOp *op)
16
{
17
+ uint64_t z_mask, s_mask;
18
+ TempOptInfo *t1, *t2;
19
+
20
if (fold_const2_commutative(ctx, op) ||
21
fold_xi_to_x(ctx, op, 0) ||
22
fold_xx_to_x(ctx, op)) {
23
return true;
24
}
25
26
- ctx->z_mask = arg_info(op->args[1])->z_mask
27
- | arg_info(op->args[2])->z_mask;
28
- ctx->s_mask = arg_info(op->args[1])->s_mask
29
- & arg_info(op->args[2])->s_mask;
30
- return fold_masks(ctx, op);
31
+ t1 = arg_info(op->args[1]);
32
+ t2 = arg_info(op->args[2]);
33
+ z_mask = t1->z_mask | t2->z_mask;
34
+ s_mask = t1->s_mask & t2->s_mask;
35
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
36
}
37
38
static bool fold_orc(OptContext *ctx, TCGOp *op)
39
--
40
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 8 +++++---
7
1 file changed, 5 insertions(+), 3 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_or(OptContext *ctx, TCGOp *op)
14
15
static bool fold_orc(OptContext *ctx, TCGOp *op)
16
{
17
+ uint64_t s_mask;
18
+
19
if (fold_const2(ctx, op) ||
20
fold_xx_to_i(ctx, op, -1) ||
21
fold_xi_to_x(ctx, op, -1) ||
22
@@ -XXX,XX +XXX,XX @@ static bool fold_orc(OptContext *ctx, TCGOp *op)
23
return true;
24
}
25
26
- ctx->s_mask = arg_info(op->args[1])->s_mask
27
- & arg_info(op->args[2])->s_mask;
28
- return false;
29
+ s_mask = arg_info(op->args[1])->s_mask
30
+ & arg_info(op->args[2])->s_mask;
31
+ return fold_masks_s(ctx, op, s_mask);
32
}
33
34
static bool fold_qemu_ld(OptContext *ctx, TCGOp *op)
35
--
36
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots.
1
2
3
Be careful not to call fold_masks_zs when the memory operation
4
is wide enough to require multiple outputs, so split into two
5
functions: fold_qemu_ld_1reg and fold_qemu_ld_2reg.
6
7
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
10
tcg/optimize.c | 26 +++++++++++++++++++++-----
11
1 file changed, 21 insertions(+), 5 deletions(-)
12
13
diff --git a/tcg/optimize.c b/tcg/optimize.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tcg/optimize.c
16
+++ b/tcg/optimize.c
17
@@ -XXX,XX +XXX,XX @@ static bool fold_orc(OptContext *ctx, TCGOp *op)
18
return fold_masks_s(ctx, op, s_mask);
19
}
20
21
-static bool fold_qemu_ld(OptContext *ctx, TCGOp *op)
22
+static bool fold_qemu_ld_1reg(OptContext *ctx, TCGOp *op)
23
{
24
const TCGOpDef *def = &tcg_op_defs[op->opc];
25
MemOpIdx oi = op->args[def->nb_oargs + def->nb_iargs];
26
MemOp mop = get_memop(oi);
27
int width = 8 * memop_size(mop);
28
+ uint64_t z_mask = -1, s_mask = 0;
29
30
if (width < 64) {
31
if (mop & MO_SIGN) {
32
- ctx->s_mask = MAKE_64BIT_MASK(width, 64 - width);
33
+ s_mask = MAKE_64BIT_MASK(width - 1, 64 - (width - 1));
34
} else {
35
- ctx->z_mask = MAKE_64BIT_MASK(0, width);
36
+ z_mask = MAKE_64BIT_MASK(0, width);
37
}
38
}
39
40
/* Opcodes that touch guest memory stop the mb optimization. */
41
ctx->prev_mb = NULL;
42
- return false;
43
+
44
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
45
+}
46
+
47
+static bool fold_qemu_ld_2reg(OptContext *ctx, TCGOp *op)
48
+{
49
+ /* Opcodes that touch guest memory stop the mb optimization. */
50
+ ctx->prev_mb = NULL;
51
+ return finish_folding(ctx, op);
52
}
53
54
static bool fold_qemu_st(OptContext *ctx, TCGOp *op)
55
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s)
56
break;
57
case INDEX_op_qemu_ld_a32_i32:
58
case INDEX_op_qemu_ld_a64_i32:
59
+ done = fold_qemu_ld_1reg(&ctx, op);
60
+ break;
61
case INDEX_op_qemu_ld_a32_i64:
62
case INDEX_op_qemu_ld_a64_i64:
63
+ if (TCG_TARGET_REG_BITS == 64) {
64
+ done = fold_qemu_ld_1reg(&ctx, op);
65
+ break;
66
+ }
67
+ QEMU_FALLTHROUGH;
68
case INDEX_op_qemu_ld_a32_i128:
69
case INDEX_op_qemu_ld_a64_i128:
70
- done = fold_qemu_ld(&ctx, op);
71
+ done = fold_qemu_ld_2reg(&ctx, op);
72
break;
73
case INDEX_op_qemu_st8_a32_i32:
74
case INDEX_op_qemu_st8_a64_i32:
75
--
76
2.43.0
diff view generated by jsdifflib
New patch
1
Stores have no output operands, and so need no further work.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 11 +++++------
7
1 file changed, 5 insertions(+), 6 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_qemu_st(OptContext *ctx, TCGOp *op)
14
{
15
/* Opcodes that touch guest memory stop the mb optimization. */
16
ctx->prev_mb = NULL;
17
- return false;
18
+ return true;
19
}
20
21
static bool fold_remainder(OptContext *ctx, TCGOp *op)
22
@@ -XXX,XX +XXX,XX @@ static bool fold_tcg_st(OptContext *ctx, TCGOp *op)
23
24
if (op->args[1] != tcgv_ptr_arg(tcg_env)) {
25
remove_mem_copy_all(ctx);
26
- return false;
27
+ return true;
28
}
29
30
switch (op->opc) {
31
@@ -XXX,XX +XXX,XX @@ static bool fold_tcg_st(OptContext *ctx, TCGOp *op)
32
g_assert_not_reached();
33
}
34
remove_mem_copy_in(ctx, ofs, ofs + lm1);
35
- return false;
36
+ return true;
37
}
38
39
static bool fold_tcg_st_memcopy(OptContext *ctx, TCGOp *op)
40
@@ -XXX,XX +XXX,XX @@ static bool fold_tcg_st_memcopy(OptContext *ctx, TCGOp *op)
41
TCGType type;
42
43
if (op->args[1] != tcgv_ptr_arg(tcg_env)) {
44
- fold_tcg_st(ctx, op);
45
- return false;
46
+ return fold_tcg_st(ctx, op);
47
}
48
49
src = arg_temp(op->args[0]);
50
@@ -XXX,XX +XXX,XX @@ static bool fold_tcg_st_memcopy(OptContext *ctx, TCGOp *op)
51
last = ofs + tcg_type_size(type) - 1;
52
remove_mem_copy_in(ctx, ofs, last);
53
record_mem_copy(ctx, type, src, ofs, last);
54
- return false;
55
+ return true;
56
}
57
58
static bool fold_xor(OptContext *ctx, TCGOp *op)
59
--
60
2.43.0
diff view generated by jsdifflib
New patch
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
tcg/optimize.c | 2 +-
5
1 file changed, 1 insertion(+), 1 deletion(-)
1
6
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/optimize.c
10
+++ b/tcg/optimize.c
11
@@ -XXX,XX +XXX,XX @@ static bool fold_remainder(OptContext *ctx, TCGOp *op)
12
fold_xx_to_i(ctx, op, 0)) {
13
return true;
14
}
15
- return false;
16
+ return finish_folding(ctx, op);
17
}
18
19
static bool fold_setcond_zmask(OptContext *ctx, TCGOp *op, bool neg)
20
--
21
2.43.0
diff view generated by jsdifflib
New patch
1
Change return from bool to int; distinguish between
2
complete folding, simplification, and no change.
1
3
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
tcg/optimize.c | 22 ++++++++++++++--------
8
1 file changed, 14 insertions(+), 8 deletions(-)
9
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/optimize.c
13
+++ b/tcg/optimize.c
14
@@ -XXX,XX +XXX,XX @@ static bool fold_remainder(OptContext *ctx, TCGOp *op)
15
return finish_folding(ctx, op);
16
}
17
18
-static bool fold_setcond_zmask(OptContext *ctx, TCGOp *op, bool neg)
19
+/* Return 1 if finished, -1 if simplified, 0 if unchanged. */
20
+static int fold_setcond_zmask(OptContext *ctx, TCGOp *op, bool neg)
21
{
22
uint64_t a_zmask, b_val;
23
TCGCond cond;
24
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond_zmask(OptContext *ctx, TCGOp *op, bool neg)
25
op->opc = xor_opc;
26
op->args[2] = arg_new_constant(ctx, 1);
27
}
28
- return false;
29
+ return -1;
30
}
31
}
32
-
33
- return false;
34
+ return 0;
35
}
36
37
static void fold_setcond_tst_pow2(OptContext *ctx, TCGOp *op, bool neg)
38
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond(OptContext *ctx, TCGOp *op)
39
return tcg_opt_gen_movi(ctx, op, op->args[0], i);
40
}
41
42
- if (fold_setcond_zmask(ctx, op, false)) {
43
+ i = fold_setcond_zmask(ctx, op, false);
44
+ if (i > 0) {
45
return true;
46
}
47
- fold_setcond_tst_pow2(ctx, op, false);
48
+ if (i == 0) {
49
+ fold_setcond_tst_pow2(ctx, op, false);
50
+ }
51
52
ctx->z_mask = 1;
53
return false;
54
@@ -XXX,XX +XXX,XX @@ static bool fold_negsetcond(OptContext *ctx, TCGOp *op)
55
return tcg_opt_gen_movi(ctx, op, op->args[0], -i);
56
}
57
58
- if (fold_setcond_zmask(ctx, op, true)) {
59
+ i = fold_setcond_zmask(ctx, op, true);
60
+ if (i > 0) {
61
return true;
62
}
63
- fold_setcond_tst_pow2(ctx, op, true);
64
+ if (i == 0) {
65
+ fold_setcond_tst_pow2(ctx, op, true);
66
+ }
67
68
/* Value is {0,-1} so all bits are repetitions of the sign. */
69
ctx->s_mask = -1;
70
--
71
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 3 +--
7
1 file changed, 1 insertion(+), 2 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond(OptContext *ctx, TCGOp *op)
14
fold_setcond_tst_pow2(ctx, op, false);
15
}
16
17
- ctx->z_mask = 1;
18
- return false;
19
+ return fold_masks_z(ctx, op, 1);
20
}
21
22
static bool fold_negsetcond(OptContext *ctx, TCGOp *op)
23
--
24
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 3 +--
7
1 file changed, 1 insertion(+), 2 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_negsetcond(OptContext *ctx, TCGOp *op)
14
}
15
16
/* Value is {0,-1} so all bits are repetitions of the sign. */
17
- ctx->s_mask = -1;
18
- return false;
19
+ return fold_masks_s(ctx, op, -1);
20
}
21
22
static bool fold_setcond2(OptContext *ctx, TCGOp *op)
23
--
24
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 3 +--
7
1 file changed, 1 insertion(+), 2 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond2(OptContext *ctx, TCGOp *op)
14
return fold_setcond(ctx, op);
15
}
16
17
- ctx->z_mask = 1;
18
- return false;
19
+ return fold_masks_z(ctx, op, 1);
20
21
do_setcond_const:
22
return tcg_opt_gen_movi(ctx, op, op->args[0], i);
23
--
24
2.43.0
diff view generated by jsdifflib
New patch
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
tcg/optimize.c | 2 +-
5
1 file changed, 1 insertion(+), 1 deletion(-)
1
6
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/optimize.c
10
+++ b/tcg/optimize.c
11
@@ -XXX,XX +XXX,XX @@ static bool fold_cmp_vec(OptContext *ctx, TCGOp *op)
12
if (swap_commutative(NO_DEST, &op->args[1], &op->args[2])) {
13
op->args[3] = tcg_swap_cond(op->args[3]);
14
}
15
- return false;
16
+ return finish_folding(ctx, op);
17
}
18
19
static bool fold_cmpsel_vec(OptContext *ctx, TCGOp *op)
20
--
21
2.43.0
diff view generated by jsdifflib
New patch
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
tcg/optimize.c | 2 +-
5
1 file changed, 1 insertion(+), 1 deletion(-)
1
6
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/optimize.c
10
+++ b/tcg/optimize.c
11
@@ -XXX,XX +XXX,XX @@ static bool fold_cmpsel_vec(OptContext *ctx, TCGOp *op)
12
if (swap_commutative(op->args[0], &op->args[4], &op->args[3])) {
13
op->args[5] = tcg_invert_cond(op->args[5]);
14
}
15
- return false;
16
+ return finish_folding(ctx, op);
17
}
18
19
static bool fold_sextract(OptContext *ctx, TCGOp *op)
20
--
21
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 24 +++++++++---------------
7
1 file changed, 9 insertions(+), 15 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_cmpsel_vec(OptContext *ctx, TCGOp *op)
14
static bool fold_sextract(OptContext *ctx, TCGOp *op)
15
{
16
uint64_t z_mask, s_mask, s_mask_old;
17
+ TempOptInfo *t1 = arg_info(op->args[1]);
18
int pos = op->args[2];
19
int len = op->args[3];
20
21
- if (arg_is_const(op->args[1])) {
22
- uint64_t t;
23
-
24
- t = arg_info(op->args[1])->val;
25
- t = sextract64(t, pos, len);
26
- return tcg_opt_gen_movi(ctx, op, op->args[0], t);
27
+ if (ti_is_const(t1)) {
28
+ return tcg_opt_gen_movi(ctx, op, op->args[0],
29
+ sextract64(ti_const_val(t1), pos, len));
30
}
31
32
- z_mask = arg_info(op->args[1])->z_mask;
33
- z_mask = sextract64(z_mask, pos, len);
34
- ctx->z_mask = z_mask;
35
-
36
- s_mask_old = arg_info(op->args[1])->s_mask;
37
- s_mask = sextract64(s_mask_old, pos, len);
38
- s_mask |= MAKE_64BIT_MASK(len, 64 - len);
39
- ctx->s_mask = s_mask;
40
+ s_mask_old = t1->s_mask;
41
+ s_mask = s_mask_old >> pos;
42
+ s_mask |= -1ull << (len - 1);
43
44
if (0 && pos == 0 && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
45
return true;
46
}
47
48
- return fold_masks(ctx, op);
49
+ z_mask = sextract64(t1->z_mask, pos, len);
50
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
51
}
52
53
static bool fold_shift(OptContext *ctx, TCGOp *op)
54
--
55
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 27 ++++++++++++++-------------
7
1 file changed, 14 insertions(+), 13 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_sextract(OptContext *ctx, TCGOp *op)
14
static bool fold_shift(OptContext *ctx, TCGOp *op)
15
{
16
uint64_t s_mask, z_mask, sign;
17
+ TempOptInfo *t1, *t2;
18
19
if (fold_const2(ctx, op) ||
20
fold_ix_to_i(ctx, op, 0) ||
21
@@ -XXX,XX +XXX,XX @@ static bool fold_shift(OptContext *ctx, TCGOp *op)
22
return true;
23
}
24
25
- s_mask = arg_info(op->args[1])->s_mask;
26
- z_mask = arg_info(op->args[1])->z_mask;
27
+ t1 = arg_info(op->args[1]);
28
+ t2 = arg_info(op->args[2]);
29
+ s_mask = t1->s_mask;
30
+ z_mask = t1->z_mask;
31
32
- if (arg_is_const(op->args[2])) {
33
- int sh = arg_info(op->args[2])->val;
34
-
35
- ctx->z_mask = do_constant_folding(op->opc, ctx->type, z_mask, sh);
36
+ if (ti_is_const(t2)) {
37
+ int sh = ti_const_val(t2);
38
39
+ z_mask = do_constant_folding(op->opc, ctx->type, z_mask, sh);
40
s_mask = do_constant_folding(op->opc, ctx->type, s_mask, sh);
41
42
- return fold_masks(ctx, op);
43
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
44
}
45
46
switch (op->opc) {
47
@@ -XXX,XX +XXX,XX @@ static bool fold_shift(OptContext *ctx, TCGOp *op)
48
* Arithmetic right shift will not reduce the number of
49
* input sign repetitions.
50
*/
51
- ctx->s_mask = s_mask;
52
- break;
53
+ return fold_masks_s(ctx, op, s_mask);
54
CASE_OP_32_64(shr):
55
/*
56
* If the sign bit is known zero, then logical right shift
57
- * will not reduced the number of input sign repetitions.
58
+ * will not reduce the number of input sign repetitions.
59
*/
60
- sign = (s_mask & -s_mask) >> 1;
61
+ sign = -s_mask;
62
if (sign && !(z_mask & sign)) {
63
- ctx->s_mask = s_mask;
64
+ return fold_masks_s(ctx, op, s_mask);
65
}
66
break;
67
default:
68
break;
69
}
70
71
- return false;
72
+ return finish_folding(ctx, op);
73
}
74
75
static bool fold_sub_to_neg(OptContext *ctx, TCGOp *op)
76
--
77
2.43.0
diff view generated by jsdifflib
New patch
1
Merge the two conditions, sign != 0 && !(z_mask & sign),
2
by testing ~z_mask & sign. If sign == 0, the logical and
3
will produce false.
1
4
5
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
tcg/optimize.c | 5 ++---
9
1 file changed, 2 insertions(+), 3 deletions(-)
10
11
diff --git a/tcg/optimize.c b/tcg/optimize.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/tcg/optimize.c
14
+++ b/tcg/optimize.c
15
@@ -XXX,XX +XXX,XX @@ static bool fold_sextract(OptContext *ctx, TCGOp *op)
16
17
static bool fold_shift(OptContext *ctx, TCGOp *op)
18
{
19
- uint64_t s_mask, z_mask, sign;
20
+ uint64_t s_mask, z_mask;
21
TempOptInfo *t1, *t2;
22
23
if (fold_const2(ctx, op) ||
24
@@ -XXX,XX +XXX,XX @@ static bool fold_shift(OptContext *ctx, TCGOp *op)
25
* If the sign bit is known zero, then logical right shift
26
* will not reduce the number of input sign repetitions.
27
*/
28
- sign = -s_mask;
29
- if (sign && !(z_mask & sign)) {
30
+ if (~z_mask & -s_mask) {
31
return fold_masks_s(ctx, op, s_mask);
32
}
33
break;
34
--
35
2.43.0
diff view generated by jsdifflib
New patch
1
Duplicate fold_sub_vec into fold_sub instead of calling it,
2
now that fold_sub_vec always returns true.
1
3
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
tcg/optimize.c | 9 ++++++---
8
1 file changed, 6 insertions(+), 3 deletions(-)
9
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/optimize.c
13
+++ b/tcg/optimize.c
14
@@ -XXX,XX +XXX,XX @@ static bool fold_sub_vec(OptContext *ctx, TCGOp *op)
15
fold_sub_to_neg(ctx, op)) {
16
return true;
17
}
18
- return false;
19
+ return finish_folding(ctx, op);
20
}
21
22
static bool fold_sub(OptContext *ctx, TCGOp *op)
23
{
24
- if (fold_const2(ctx, op) || fold_sub_vec(ctx, op)) {
25
+ if (fold_const2(ctx, op) ||
26
+ fold_xx_to_i(ctx, op, 0) ||
27
+ fold_xi_to_x(ctx, op, 0) ||
28
+ fold_sub_to_neg(ctx, op)) {
29
return true;
30
}
31
32
@@ -XXX,XX +XXX,XX @@ static bool fold_sub(OptContext *ctx, TCGOp *op)
33
? INDEX_op_add_i32 : INDEX_op_add_i64);
34
op->args[2] = arg_new_constant(ctx, -val);
35
}
36
- return false;
37
+ return finish_folding(ctx, op);
38
}
39
40
static bool fold_sub2(OptContext *ctx, TCGOp *op)
41
--
42
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 16 +++++++++-------
7
1 file changed, 9 insertions(+), 7 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_sub2(OptContext *ctx, TCGOp *op)
14
15
static bool fold_tcg_ld(OptContext *ctx, TCGOp *op)
16
{
17
+ uint64_t z_mask = -1, s_mask = 0;
18
+
19
/* We can't do any folding with a load, but we can record bits. */
20
switch (op->opc) {
21
CASE_OP_32_64(ld8s):
22
- ctx->s_mask = MAKE_64BIT_MASK(8, 56);
23
+ s_mask = INT8_MIN;
24
break;
25
CASE_OP_32_64(ld8u):
26
- ctx->z_mask = MAKE_64BIT_MASK(0, 8);
27
+ z_mask = MAKE_64BIT_MASK(0, 8);
28
break;
29
CASE_OP_32_64(ld16s):
30
- ctx->s_mask = MAKE_64BIT_MASK(16, 48);
31
+ s_mask = INT16_MIN;
32
break;
33
CASE_OP_32_64(ld16u):
34
- ctx->z_mask = MAKE_64BIT_MASK(0, 16);
35
+ z_mask = MAKE_64BIT_MASK(0, 16);
36
break;
37
case INDEX_op_ld32s_i64:
38
- ctx->s_mask = MAKE_64BIT_MASK(32, 32);
39
+ s_mask = INT32_MIN;
40
break;
41
case INDEX_op_ld32u_i64:
42
- ctx->z_mask = MAKE_64BIT_MASK(0, 32);
43
+ z_mask = MAKE_64BIT_MASK(0, 32);
44
break;
45
default:
46
g_assert_not_reached();
47
}
48
- return false;
49
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
50
}
51
52
static bool fold_tcg_ld_memcopy(OptContext *ctx, TCGOp *op)
53
--
54
2.43.0
diff view generated by jsdifflib
1
From: Anton Johansson <anjo@rev.ng>
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
3
Updates target/ QEMU_LOG macros to use VADDR_PRIx for printing updated
4
DisasContextBase fields.
5
6
Signed-off-by: Anton Johansson <anjo@rev.ng>
7
Message-Id: <20240119144024.14289-10-anjo@rev.ng>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
3
---
11
include/exec/translator.h | 6 +++---
4
tcg/optimize.c | 2 +-
12
target/mips/tcg/translate.h | 3 ++-
5
1 file changed, 1 insertion(+), 1 deletion(-)
13
target/hexagon/translate.c | 3 ++-
14
target/m68k/translate.c | 2 +-
15
target/mips/tcg/translate.c | 12 ++++++------
16
5 files changed, 14 insertions(+), 12 deletions(-)
17
6
18
diff --git a/include/exec/translator.h b/include/exec/translator.h
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
19
index XXXXXXX..XXXXXXX 100644
8
index XXXXXXX..XXXXXXX 100644
20
--- a/include/exec/translator.h
9
--- a/tcg/optimize.c
21
+++ b/include/exec/translator.h
10
+++ b/tcg/optimize.c
22
@@ -XXX,XX +XXX,XX @@ typedef enum DisasJumpType {
11
@@ -XXX,XX +XXX,XX @@ static bool fold_tcg_ld_memcopy(OptContext *ctx, TCGOp *op)
23
*/
12
TCGType type;
24
typedef struct DisasContextBase {
13
25
TranslationBlock *tb;
14
if (op->args[1] != tcgv_ptr_arg(tcg_env)) {
26
- target_ulong pc_first;
15
- return false;
27
- target_ulong pc_next;
16
+ return finish_folding(ctx, op);
28
+ vaddr pc_first;
29
+ vaddr pc_next;
30
DisasJumpType is_jmp;
31
int num_insns;
32
int max_insns;
33
@@ -XXX,XX +XXX,XX @@ void translator_fake_ldb(uint8_t insn8, abi_ptr pc);
34
* Translators can use this to enforce the rule that only single-insn
35
* translation blocks are allowed to cross page boundaries.
36
*/
37
-static inline bool is_same_page(const DisasContextBase *db, target_ulong addr)
38
+static inline bool is_same_page(const DisasContextBase *db, vaddr addr)
39
{
40
return ((addr ^ db->pc_first) & TARGET_PAGE_MASK) == 0;
41
}
42
diff --git a/target/mips/tcg/translate.h b/target/mips/tcg/translate.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/mips/tcg/translate.h
45
+++ b/target/mips/tcg/translate.h
46
@@ -XXX,XX +XXX,XX @@ extern TCGv bcond;
47
do { \
48
if (MIPS_DEBUG_DISAS) { \
49
qemu_log_mask(CPU_LOG_TB_IN_ASM, \
50
- TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
51
+ "%016" VADDR_PRIx \
52
+ ": %08x Invalid %s %03x %03x %03x\n", \
53
ctx->base.pc_next, ctx->opcode, op, \
54
ctx->opcode >> 26, ctx->opcode & 0x3F, \
55
((ctx->opcode >> 16) & 0x1F)); \
56
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/hexagon/translate.c
59
+++ b/target/hexagon/translate.c
60
@@ -XXX,XX +XXX,XX @@ static int read_packet_words(CPUHexagonState *env, DisasContext *ctx,
61
g_assert(ctx->base.num_insns == 1);
62
}
17
}
63
18
64
- HEX_DEBUG_LOG("decode_packet: pc = 0x%x\n", ctx->base.pc_next);
19
type = ctx->type;
65
+ HEX_DEBUG_LOG("decode_packet: pc = 0x%" VADDR_PRIx "\n",
66
+ ctx->base.pc_next);
67
HEX_DEBUG_LOG(" words = { ");
68
for (int i = 0; i < nwords; i++) {
69
HEX_DEBUG_LOG("0x%x, ", words[i]);
70
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/m68k/translate.c
73
+++ b/target/m68k/translate.c
74
@@ -XXX,XX +XXX,XX @@ DISAS_INSN(undef)
75
* for the 680x0 series, as well as those that are implemented
76
* but actually illegal for CPU32 or pre-68020.
77
*/
78
- qemu_log_mask(LOG_UNIMP, "Illegal instruction: %04x @ %08x\n",
79
+ qemu_log_mask(LOG_UNIMP, "Illegal instruction: %04x @ %" VADDR_PRIx "\n",
80
insn, s->base.pc_next);
81
gen_exception(s, s->base.pc_next, EXCP_ILLEGAL);
82
}
83
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/target/mips/tcg/translate.c
86
+++ b/target/mips/tcg/translate.c
87
@@ -XXX,XX +XXX,XX @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
88
89
if (ctx->hflags & MIPS_HFLAG_BMASK) {
90
#ifdef MIPS_DEBUG_DISAS
91
- LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
92
- TARGET_FMT_lx "\n", ctx->base.pc_next);
93
+ LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016"
94
+ VADDR_PRIx "\n", ctx->base.pc_next);
95
#endif
96
gen_reserved_instruction(ctx);
97
goto out;
98
@@ -XXX,XX +XXX,XX @@ static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
99
100
if (ctx->hflags & MIPS_HFLAG_BMASK) {
101
#ifdef MIPS_DEBUG_DISAS
102
- LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
103
- "\n", ctx->base.pc_next);
104
+ LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016"
105
+ VADDR_PRIx "\n", ctx->base.pc_next);
106
#endif
107
gen_reserved_instruction(ctx);
108
return;
109
@@ -XXX,XX +XXX,XX @@ static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
110
111
if (ctx->hflags & MIPS_HFLAG_BMASK) {
112
#ifdef MIPS_DEBUG_DISAS
113
- LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
114
- "\n", ctx->base.pc_next);
115
+ LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016"
116
+ VADDR_PRIx "\n", ctx->base.pc_next);
117
#endif
118
gen_reserved_instruction(ctx);
119
return;
120
--
20
--
121
2.34.1
21
2.43.0
diff view generated by jsdifflib
1
From: Anton Johansson <anjo@rev.ng>
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
2
Remove fold_masks as the function becomes unused.
2
3
3
These don't vary across targets and are used in soon-to-be common code
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
(cputlb.c).
5
6
Signed-off-by: Anton Johansson <anjo@rev.ng>
7
Message-Id: <20240119144024.14289-15-anjo@rev.ng>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
6
---
11
include/exec/cpu-all.h | 24 ------------------------
7
tcg/optimize.c | 18 ++++++++----------
12
include/exec/cpu-common.h | 30 ++++++++++++++++++++++++++++++
8
1 file changed, 8 insertions(+), 10 deletions(-)
13
2 files changed, 30 insertions(+), 24 deletions(-)
14
9
15
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
16
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
17
--- a/include/exec/cpu-all.h
12
--- a/tcg/optimize.c
18
+++ b/include/exec/cpu-all.h
13
+++ b/tcg/optimize.c
19
@@ -XXX,XX +XXX,XX @@ extern const TargetPageBits target_page;
14
@@ -XXX,XX +XXX,XX @@ static bool fold_masks_s(OptContext *ctx, TCGOp *op, uint64_t s_mask)
20
15
return fold_masks_zs(ctx, op, -1, s_mask);
21
#define TARGET_PAGE_ALIGN(addr) ROUND_UP((addr), TARGET_PAGE_SIZE)
16
}
22
17
23
-/* same as PROT_xxx */
18
-static bool fold_masks(OptContext *ctx, TCGOp *op)
24
-#define PAGE_READ 0x0001
19
-{
25
-#define PAGE_WRITE 0x0002
20
- return fold_masks_zs(ctx, op, ctx->z_mask, ctx->s_mask);
26
-#define PAGE_EXEC 0x0004
21
-}
27
-#define PAGE_BITS (PAGE_READ | PAGE_WRITE | PAGE_EXEC)
28
-#define PAGE_VALID 0x0008
29
-/*
30
- * Original state of the write flag (used when tracking self-modifying code)
31
- */
32
-#define PAGE_WRITE_ORG 0x0010
33
-/*
34
- * Invalidate the TLB entry immediately, helpful for s390x
35
- * Low-Address-Protection. Used with PAGE_WRITE in tlb_set_page_with_attrs()
36
- */
37
-#define PAGE_WRITE_INV 0x0020
38
-/* For use with page_set_flags: page is being replaced; target_data cleared. */
39
-#define PAGE_RESET 0x0040
40
-/* For linux-user, indicates that the page is MAP_ANON. */
41
-#define PAGE_ANON 0x0080
42
-
43
#if defined(CONFIG_BSD) && defined(CONFIG_USER_ONLY)
44
/* FIXME: Code that sets/uses this is broken and needs to go away. */
45
#define PAGE_RESERVED 0x0100
46
#endif
47
-/* Target-specific bits that will be used via page_get_flags(). */
48
-#define PAGE_TARGET_1 0x0200
49
-#define PAGE_TARGET_2 0x0400
50
-
22
-
51
/*
23
/*
52
* For linux-user, indicates that the page is mapped with the same semantics
24
* An "affected" mask bit is 0 if and only if the result is identical
53
* in both guest and host.
25
* to the first input. Thus if the entire mask is 0, the operation
54
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
26
@@ -XXX,XX +XXX,XX @@ static bool fold_tcg_st_memcopy(OptContext *ctx, TCGOp *op)
55
index XXXXXXX..XXXXXXX 100644
27
56
--- a/include/exec/cpu-common.h
28
static bool fold_xor(OptContext *ctx, TCGOp *op)
57
+++ b/include/exec/cpu-common.h
29
{
58
@@ -XXX,XX +XXX,XX @@ G_NORETURN void cpu_loop_exit_atomic(CPUState *cpu, uintptr_t pc);
30
+ uint64_t z_mask, s_mask;
59
G_NORETURN void cpu_loop_exit(CPUState *cpu);
31
+ TempOptInfo *t1, *t2;
60
G_NORETURN void cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc);
61
62
+/* same as PROT_xxx */
63
+#define PAGE_READ 0x0001
64
+#define PAGE_WRITE 0x0002
65
+#define PAGE_EXEC 0x0004
66
+#define PAGE_BITS (PAGE_READ | PAGE_WRITE | PAGE_EXEC)
67
+#define PAGE_VALID 0x0008
68
+/*
69
+ * Original state of the write flag (used when tracking self-modifying code)
70
+ */
71
+#define PAGE_WRITE_ORG 0x0010
72
+/*
73
+ * Invalidate the TLB entry immediately, helpful for s390x
74
+ * Low-Address-Protection. Used with PAGE_WRITE in tlb_set_page_with_attrs()
75
+ */
76
+#define PAGE_WRITE_INV 0x0020
77
+/* For use with page_set_flags: page is being replaced; target_data cleared. */
78
+#define PAGE_RESET 0x0040
79
+/* For linux-user, indicates that the page is MAP_ANON. */
80
+#define PAGE_ANON 0x0080
81
+
32
+
82
+/* Target-specific bits that will be used via page_get_flags(). */
33
if (fold_const2_commutative(ctx, op) ||
83
+#define PAGE_TARGET_1 0x0200
34
fold_xx_to_i(ctx, op, 0) ||
84
+#define PAGE_TARGET_2 0x0400
35
fold_xi_to_x(ctx, op, 0) ||
85
+
36
@@ -XXX,XX +XXX,XX @@ static bool fold_xor(OptContext *ctx, TCGOp *op)
86
+/*
37
return true;
87
+ * For linux-user, indicates that the page is mapped with the same semantics
38
}
88
+ * in both guest and host.
39
89
+ */
40
- ctx->z_mask = arg_info(op->args[1])->z_mask
90
+#define PAGE_PASSTHROUGH 0x0800
41
- | arg_info(op->args[2])->z_mask;
91
+
42
- ctx->s_mask = arg_info(op->args[1])->s_mask
92
#endif /* CPU_COMMON_H */
43
- & arg_info(op->args[2])->s_mask;
44
- return fold_masks(ctx, op);
45
+ t1 = arg_info(op->args[1]);
46
+ t2 = arg_info(op->args[2]);
47
+ z_mask = t1->z_mask | t2->z_mask;
48
+ s_mask = t1->s_mask & t2->s_mask;
49
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
50
}
51
52
static bool fold_bitsel_vec(OptContext *ctx, TCGOp *op)
93
--
53
--
94
2.34.1
54
2.43.0
diff view generated by jsdifflib
New patch
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
tcg/optimize.c | 2 +-
5
1 file changed, 1 insertion(+), 1 deletion(-)
1
6
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/optimize.c
10
+++ b/tcg/optimize.c
11
@@ -XXX,XX +XXX,XX @@ static bool fold_bitsel_vec(OptContext *ctx, TCGOp *op)
12
return fold_orc(ctx, op);
13
}
14
}
15
- return false;
16
+ return finish_folding(ctx, op);
17
}
18
19
/* Propagate constants and copies, fold constant expressions. */
20
--
21
2.43.0
diff view generated by jsdifflib
New patch
1
All non-default cases now finish folding within each function.
2
Do the same with the default case and assert it is done after.
1
3
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
tcg/optimize.c | 6 ++----
8
1 file changed, 2 insertions(+), 4 deletions(-)
9
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/optimize.c
13
+++ b/tcg/optimize.c
14
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s)
15
done = true;
16
break;
17
default:
18
+ done = finish_folding(&ctx, op);
19
break;
20
}
21
-
22
- if (!done) {
23
- finish_folding(&ctx, op);
24
- }
25
+ tcg_debug_assert(done);
26
}
27
}
28
--
29
2.43.0
diff view generated by jsdifflib
New patch
1
All mask setting is now done with parameters via fold_masks_*.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 13 -------------
7
1 file changed, 13 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ typedef struct OptContext {
14
QSIMPLEQ_HEAD(, MemCopyInfo) mem_free;
15
16
/* In flight values from optimization. */
17
- uint64_t z_mask; /* mask bit is 0 iff value bit is 0 */
18
- uint64_t s_mask; /* mask bit is 1 if value bit matches msb */
19
TCGType type;
20
} OptContext;
21
22
@@ -XXX,XX +XXX,XX @@ static bool finish_folding(OptContext *ctx, TCGOp *op)
23
for (i = 0; i < nb_oargs; i++) {
24
TCGTemp *ts = arg_temp(op->args[i]);
25
reset_ts(ctx, ts);
26
- /*
27
- * Save the corresponding known-zero/sign bits mask for the
28
- * first output argument (only one supported so far).
29
- */
30
- if (i == 0) {
31
- ts_info(ts)->z_mask = ctx->z_mask;
32
- }
33
}
34
return true;
35
}
36
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s)
37
ctx.type = TCG_TYPE_I32;
38
}
39
40
- /* Assume all bits affected, no bits known zero, no sign reps. */
41
- ctx.z_mask = -1;
42
- ctx.s_mask = 0;
43
-
44
/*
45
* Process each opcode.
46
* Sorted alphabetically by opcode as much as possible.
47
--
48
2.43.0
diff view generated by jsdifflib
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
1
All instances of s_mask have been converted to the new
2
representation. We can now re-enable usage.
2
3
3
gdbserver ignores page protection by virtue of using /proc/$pid/mem.
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Teach qemu gdbstub to do this too. This will not work if /proc is not
5
mounted; accept this limitation.
6
7
One alternative is to temporarily grant the missing PROT_* bit, but
8
this is inherently racy. Another alternative is self-debugging with
9
ptrace(POKE), which will break if QEMU itself is being debugged - a
10
much more severe limitation.
11
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
14
Message-Id: <20240129093410.3151-2-iii@linux.ibm.com>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
---
6
---
17
cpu-target.c | 78 ++++++++++++++++++++++++++++++++++++++++++----------
7
tcg/optimize.c | 4 ++--
18
1 file changed, 63 insertions(+), 15 deletions(-)
8
1 file changed, 2 insertions(+), 2 deletions(-)
19
9
20
diff --git a/cpu-target.c b/cpu-target.c
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
21
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
22
--- a/cpu-target.c
12
--- a/tcg/optimize.c
23
+++ b/cpu-target.c
13
+++ b/tcg/optimize.c
24
@@ -XXX,XX +XXX,XX @@ int cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
14
@@ -XXX,XX +XXX,XX @@ static bool fold_exts(OptContext *ctx, TCGOp *op)
25
vaddr l, page;
15
g_assert_not_reached();
26
void * p;
27
uint8_t *buf = ptr;
28
+ ssize_t written;
29
+ int ret = -1;
30
+ int fd = -1;
31
32
while (len > 0) {
33
page = addr & TARGET_PAGE_MASK;
34
@@ -XXX,XX +XXX,XX @@ int cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
35
if (l > len)
36
l = len;
37
flags = page_get_flags(page);
38
- if (!(flags & PAGE_VALID))
39
- return -1;
40
+ if (!(flags & PAGE_VALID)) {
41
+ goto out_close;
42
+ }
43
if (is_write) {
44
- if (!(flags & PAGE_WRITE))
45
- return -1;
46
+ if (flags & PAGE_WRITE) {
47
+ /* XXX: this code should not depend on lock_user */
48
+ p = lock_user(VERIFY_WRITE, addr, l, 0);
49
+ if (!p) {
50
+ goto out_close;
51
+ }
52
+ memcpy(p, buf, l);
53
+ unlock_user(p, addr, l);
54
+ } else {
55
+ /* Bypass the host page protection using ptrace. */
56
+ if (fd == -1) {
57
+ fd = open("/proc/self/mem", O_WRONLY);
58
+ if (fd == -1) {
59
+ goto out;
60
+ }
61
+ }
62
+ /*
63
+ * If there is a TranslationBlock and we weren't bypassing the
64
+ * host page protection, the memcpy() above would SEGV,
65
+ * ultimately leading to page_unprotect(). So invalidate the
66
+ * translations manually. Both invalidation and pwrite() must
67
+ * be under mmap_lock() in order to prevent the creation of
68
+ * another TranslationBlock in between.
69
+ */
70
+ mmap_lock();
71
+ tb_invalidate_phys_range(addr, addr + l - 1);
72
+ written = pwrite(fd, buf, l,
73
+ (off_t)(uintptr_t)g2h_untagged(addr));
74
+ mmap_unlock();
75
+ if (written != l) {
76
+ goto out_close;
77
+ }
78
+ }
79
+ } else if (flags & PAGE_READ) {
80
/* XXX: this code should not depend on lock_user */
81
- if (!(p = lock_user(VERIFY_WRITE, addr, l, 0)))
82
- return -1;
83
- memcpy(p, buf, l);
84
- unlock_user(p, addr, l);
85
- } else {
86
- if (!(flags & PAGE_READ))
87
- return -1;
88
- /* XXX: this code should not depend on lock_user */
89
- if (!(p = lock_user(VERIFY_READ, addr, l, 1)))
90
- return -1;
91
+ p = lock_user(VERIFY_READ, addr, l, 1);
92
+ if (!p) {
93
+ goto out_close;
94
+ }
95
memcpy(buf, p, l);
96
unlock_user(p, addr, 0);
97
+ } else {
98
+ /* Bypass the host page protection using ptrace. */
99
+ if (fd == -1) {
100
+ fd = open("/proc/self/mem", O_RDONLY);
101
+ if (fd == -1) {
102
+ goto out;
103
+ }
104
+ }
105
+ if (pread(fd, buf, l,
106
+ (off_t)(uintptr_t)g2h_untagged(addr)) != l) {
107
+ goto out_close;
108
+ }
109
}
110
len -= l;
111
buf += l;
112
addr += l;
113
}
16
}
114
- return 0;
17
115
+ ret = 0;
18
- if (0 && !type_change && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
116
+out_close:
19
+ if (!type_change && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
117
+ if (fd != -1) {
20
return true;
118
+ close(fd);
21
}
119
+ }
22
120
+out:
23
@@ -XXX,XX +XXX,XX @@ static bool fold_sextract(OptContext *ctx, TCGOp *op)
121
+ return ret;
24
s_mask = s_mask_old >> pos;
122
}
25
s_mask |= -1ull << (len - 1);
123
#endif
26
27
- if (0 && pos == 0 && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
28
+ if (pos == 0 && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
29
return true;
30
}
124
31
125
--
32
--
126
2.34.1
33
2.43.0
diff view generated by jsdifflib
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
1
The big comment just above says functions should be sorted.
2
Add forward declarations as needed.
2
3
3
tcg/ should not depend on accel/tcg/, but perf and debuginfo
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
support provided by the latter are being used by tcg/tcg.c.
5
6
Since that's the only user, move both to tcg/.
7
8
Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-ID: <20231212003837.64090-5-iii@linux.ibm.com>
13
Message-Id: <20240125054631.78867-5-philmd@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
---
6
---
16
{accel => include}/tcg/debuginfo.h | 4 ++--
7
tcg/optimize.c | 114 +++++++++++++++++++++++++------------------------
17
{accel => include}/tcg/perf.h | 4 ++--
8
1 file changed, 59 insertions(+), 55 deletions(-)
18
accel/tcg/translate-all.c | 2 +-
19
hw/core/loader.c | 2 +-
20
linux-user/elfload.c | 2 +-
21
linux-user/exit.c | 2 +-
22
linux-user/main.c | 2 +-
23
system/vl.c | 2 +-
24
{accel/tcg => tcg}/debuginfo.c | 3 +--
25
{accel/tcg => tcg}/perf.c | 7 +++----
26
tcg/tcg.c | 2 +-
27
accel/tcg/meson.build | 4 ----
28
tcg/meson.build | 5 +++++
29
13 files changed, 20 insertions(+), 21 deletions(-)
30
rename {accel => include}/tcg/debuginfo.h (96%)
31
rename {accel => include}/tcg/perf.h (95%)
32
rename {accel/tcg => tcg}/debuginfo.c (98%)
33
rename {accel/tcg => tcg}/perf.c (99%)
34
9
35
diff --git a/accel/tcg/debuginfo.h b/include/tcg/debuginfo.h
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
36
similarity index 96%
37
rename from accel/tcg/debuginfo.h
38
rename to include/tcg/debuginfo.h
39
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
40
--- a/accel/tcg/debuginfo.h
12
--- a/tcg/optimize.c
41
+++ b/include/tcg/debuginfo.h
13
+++ b/tcg/optimize.c
42
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static bool fold_xx_to_x(OptContext *ctx, TCGOp *op)
43
* SPDX-License-Identifier: GPL-2.0-or-later
15
* 3) those that produce information about the result value.
44
*/
16
*/
45
17
46
-#ifndef ACCEL_TCG_DEBUGINFO_H
18
+static bool fold_or(OptContext *ctx, TCGOp *op);
47
-#define ACCEL_TCG_DEBUGINFO_H
19
+static bool fold_orc(OptContext *ctx, TCGOp *op);
48
+#ifndef TCG_DEBUGINFO_H
20
+static bool fold_xor(OptContext *ctx, TCGOp *op);
49
+#define TCG_DEBUGINFO_H
21
+
50
22
static bool fold_add(OptContext *ctx, TCGOp *op)
51
#include "qemu/bitops.h"
23
{
52
24
if (fold_const2_commutative(ctx, op) ||
53
diff --git a/accel/tcg/perf.h b/include/tcg/perf.h
25
@@ -XXX,XX +XXX,XX @@ static bool fold_andc(OptContext *ctx, TCGOp *op)
54
similarity index 95%
26
return fold_masks_zs(ctx, op, z_mask, s_mask);
55
rename from accel/tcg/perf.h
27
}
56
rename to include/tcg/perf.h
28
57
index XXXXXXX..XXXXXXX 100644
29
+static bool fold_bitsel_vec(OptContext *ctx, TCGOp *op)
58
--- a/accel/tcg/perf.h
30
+{
59
+++ b/include/tcg/perf.h
31
+ /* If true and false values are the same, eliminate the cmp. */
60
@@ -XXX,XX +XXX,XX @@
32
+ if (args_are_copies(op->args[2], op->args[3])) {
61
* SPDX-License-Identifier: GPL-2.0-or-later
33
+ return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[2]);
62
*/
34
+ }
63
35
+
64
-#ifndef ACCEL_TCG_PERF_H
36
+ if (arg_is_const(op->args[2]) && arg_is_const(op->args[3])) {
65
-#define ACCEL_TCG_PERF_H
37
+ uint64_t tv = arg_info(op->args[2])->val;
66
+#ifndef TCG_PERF_H
38
+ uint64_t fv = arg_info(op->args[3])->val;
67
+#define TCG_PERF_H
39
+
68
40
+ if (tv == -1 && fv == 0) {
69
#if defined(CONFIG_TCG) && defined(CONFIG_LINUX)
41
+ return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[1]);
70
/* Start writing perf-<pid>.map. */
42
+ }
71
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
43
+ if (tv == 0 && fv == -1) {
72
index XXXXXXX..XXXXXXX 100644
44
+ if (TCG_TARGET_HAS_not_vec) {
73
--- a/accel/tcg/translate-all.c
45
+ op->opc = INDEX_op_not_vec;
74
+++ b/accel/tcg/translate-all.c
46
+ return fold_not(ctx, op);
75
@@ -XXX,XX +XXX,XX @@
47
+ } else {
76
#include "tb-context.h"
48
+ op->opc = INDEX_op_xor_vec;
77
#include "internal-common.h"
49
+ op->args[2] = arg_new_constant(ctx, -1);
78
#include "internal-target.h"
50
+ return fold_xor(ctx, op);
79
-#include "perf.h"
51
+ }
80
+#include "tcg/perf.h"
52
+ }
81
#include "tcg/insn-start-words.h"
53
+ }
82
54
+ if (arg_is_const(op->args[2])) {
83
TBContext tb_ctx;
55
+ uint64_t tv = arg_info(op->args[2])->val;
84
diff --git a/hw/core/loader.c b/hw/core/loader.c
56
+ if (tv == -1) {
85
index XXXXXXX..XXXXXXX 100644
57
+ op->opc = INDEX_op_or_vec;
86
--- a/hw/core/loader.c
58
+ op->args[2] = op->args[3];
87
+++ b/hw/core/loader.c
59
+ return fold_or(ctx, op);
88
@@ -XXX,XX +XXX,XX @@
60
+ }
89
#include "hw/boards.h"
61
+ if (tv == 0 && TCG_TARGET_HAS_andc_vec) {
90
#include "qemu/cutils.h"
62
+ op->opc = INDEX_op_andc_vec;
91
#include "sysemu/runstate.h"
63
+ op->args[2] = op->args[1];
92
-#include "accel/tcg/debuginfo.h"
64
+ op->args[1] = op->args[3];
93
+#include "tcg/debuginfo.h"
65
+ return fold_andc(ctx, op);
94
66
+ }
95
#include <zlib.h>
67
+ }
96
68
+ if (arg_is_const(op->args[3])) {
97
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
69
+ uint64_t fv = arg_info(op->args[3])->val;
98
index XXXXXXX..XXXXXXX 100644
70
+ if (fv == 0) {
99
--- a/linux-user/elfload.c
71
+ op->opc = INDEX_op_and_vec;
100
+++ b/linux-user/elfload.c
72
+ return fold_and(ctx, op);
101
@@ -XXX,XX +XXX,XX @@
73
+ }
102
#include "qapi/error.h"
74
+ if (fv == -1 && TCG_TARGET_HAS_orc_vec) {
103
#include "qemu/error-report.h"
75
+ op->opc = INDEX_op_orc_vec;
104
#include "target_signal.h"
76
+ op->args[2] = op->args[1];
105
-#include "accel/tcg/debuginfo.h"
77
+ op->args[1] = op->args[3];
106
+#include "tcg/debuginfo.h"
78
+ return fold_orc(ctx, op);
107
79
+ }
108
#ifdef TARGET_ARM
80
+ }
109
#include "target/arm/cpu-features.h"
81
+ return finish_folding(ctx, op);
110
diff --git a/linux-user/exit.c b/linux-user/exit.c
82
+}
111
index XXXXXXX..XXXXXXX 100644
83
+
112
--- a/linux-user/exit.c
84
static bool fold_brcond(OptContext *ctx, TCGOp *op)
113
+++ b/linux-user/exit.c
85
{
114
@@ -XXX,XX +XXX,XX @@
86
int i = do_constant_folding_cond1(ctx, op, NO_DEST, &op->args[0],
115
* along with this program; if not, see <http://www.gnu.org/licenses/>.
87
@@ -XXX,XX +XXX,XX @@ static bool fold_xor(OptContext *ctx, TCGOp *op)
116
*/
88
return fold_masks_zs(ctx, op, z_mask, s_mask);
117
#include "qemu/osdep.h"
89
}
118
-#include "accel/tcg/perf.h"
90
119
+#include "tcg/perf.h"
91
-static bool fold_bitsel_vec(OptContext *ctx, TCGOp *op)
120
#include "gdbstub/syscalls.h"
92
-{
121
#include "qemu.h"
93
- /* If true and false values are the same, eliminate the cmp. */
122
#include "user-internals.h"
94
- if (args_are_copies(op->args[2], op->args[3])) {
123
diff --git a/linux-user/main.c b/linux-user/main.c
95
- return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[2]);
124
index XXXXXXX..XXXXXXX 100644
96
- }
125
--- a/linux-user/main.c
126
+++ b/linux-user/main.c
127
@@ -XXX,XX +XXX,XX @@
128
#include "signal-common.h"
129
#include "loader.h"
130
#include "user-mmap.h"
131
-#include "accel/tcg/perf.h"
132
+#include "tcg/perf.h"
133
134
#ifdef CONFIG_SEMIHOSTING
135
#include "semihosting/semihost.h"
136
diff --git a/system/vl.c b/system/vl.c
137
index XXXXXXX..XXXXXXX 100644
138
--- a/system/vl.c
139
+++ b/system/vl.c
140
@@ -XXX,XX +XXX,XX @@
141
#endif
142
#include "sysemu/qtest.h"
143
#ifdef CONFIG_TCG
144
-#include "accel/tcg/perf.h"
145
+#include "tcg/perf.h"
146
#endif
147
148
#include "disas/disas.h"
149
diff --git a/accel/tcg/debuginfo.c b/tcg/debuginfo.c
150
similarity index 98%
151
rename from accel/tcg/debuginfo.c
152
rename to tcg/debuginfo.c
153
index XXXXXXX..XXXXXXX 100644
154
--- a/accel/tcg/debuginfo.c
155
+++ b/tcg/debuginfo.c
156
@@ -XXX,XX +XXX,XX @@
157
158
#include "qemu/osdep.h"
159
#include "qemu/lockable.h"
160
+#include "tcg/debuginfo.h"
161
162
#include <elfutils/libdwfl.h>
163
164
-#include "debuginfo.h"
165
-
97
-
166
static QemuMutex lock;
98
- if (arg_is_const(op->args[2]) && arg_is_const(op->args[3])) {
167
static Dwfl *dwfl;
99
- uint64_t tv = arg_info(op->args[2])->val;
168
static const Dwfl_Callbacks dwfl_callbacks = {
100
- uint64_t fv = arg_info(op->args[3])->val;
169
diff --git a/accel/tcg/perf.c b/tcg/perf.c
170
similarity index 99%
171
rename from accel/tcg/perf.c
172
rename to tcg/perf.c
173
index XXXXXXX..XXXXXXX 100644
174
--- a/accel/tcg/perf.c
175
+++ b/tcg/perf.c
176
@@ -XXX,XX +XXX,XX @@
177
#include "qemu/osdep.h"
178
#include "elf.h"
179
#include "exec/target_page.h"
180
-#include "exec/exec-all.h"
181
+#include "exec/translation-block.h"
182
#include "qemu/timer.h"
183
+#include "tcg/debuginfo.h"
184
+#include "tcg/perf.h"
185
#include "tcg/tcg.h"
186
187
-#include "debuginfo.h"
188
-#include "perf.h"
189
-
101
-
190
static FILE *safe_fopen_w(const char *path)
102
- if (tv == -1 && fv == 0) {
103
- return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[1]);
104
- }
105
- if (tv == 0 && fv == -1) {
106
- if (TCG_TARGET_HAS_not_vec) {
107
- op->opc = INDEX_op_not_vec;
108
- return fold_not(ctx, op);
109
- } else {
110
- op->opc = INDEX_op_xor_vec;
111
- op->args[2] = arg_new_constant(ctx, -1);
112
- return fold_xor(ctx, op);
113
- }
114
- }
115
- }
116
- if (arg_is_const(op->args[2])) {
117
- uint64_t tv = arg_info(op->args[2])->val;
118
- if (tv == -1) {
119
- op->opc = INDEX_op_or_vec;
120
- op->args[2] = op->args[3];
121
- return fold_or(ctx, op);
122
- }
123
- if (tv == 0 && TCG_TARGET_HAS_andc_vec) {
124
- op->opc = INDEX_op_andc_vec;
125
- op->args[2] = op->args[1];
126
- op->args[1] = op->args[3];
127
- return fold_andc(ctx, op);
128
- }
129
- }
130
- if (arg_is_const(op->args[3])) {
131
- uint64_t fv = arg_info(op->args[3])->val;
132
- if (fv == 0) {
133
- op->opc = INDEX_op_and_vec;
134
- return fold_and(ctx, op);
135
- }
136
- if (fv == -1 && TCG_TARGET_HAS_orc_vec) {
137
- op->opc = INDEX_op_orc_vec;
138
- op->args[2] = op->args[1];
139
- op->args[1] = op->args[3];
140
- return fold_orc(ctx, op);
141
- }
142
- }
143
- return finish_folding(ctx, op);
144
-}
145
-
146
/* Propagate constants and copies, fold constant expressions. */
147
void tcg_optimize(TCGContext *s)
191
{
148
{
192
int saved_errno;
193
diff --git a/tcg/tcg.c b/tcg/tcg.c
194
index XXXXXXX..XXXXXXX 100644
195
--- a/tcg/tcg.c
196
+++ b/tcg/tcg.c
197
@@ -XXX,XX +XXX,XX @@
198
#include "tcg/tcg-ldst.h"
199
#include "tcg/tcg-temp-internal.h"
200
#include "tcg-internal.h"
201
-#include "accel/tcg/perf.h"
202
+#include "tcg/perf.h"
203
#ifdef CONFIG_USER_ONLY
204
#include "exec/user/guest-base.h"
205
#endif
206
diff --git a/accel/tcg/meson.build b/accel/tcg/meson.build
207
index XXXXXXX..XXXXXXX 100644
208
--- a/accel/tcg/meson.build
209
+++ b/accel/tcg/meson.build
210
@@ -XXX,XX +XXX,XX @@ tcg_ss.add(when: 'CONFIG_SYSTEM_ONLY', if_false: files('user-exec-stub.c'))
211
if get_option('plugins')
212
tcg_ss.add(files('plugin-gen.c'))
213
endif
214
-tcg_ss.add(when: libdw, if_true: files('debuginfo.c'))
215
-if host_os == 'linux'
216
- tcg_ss.add(files('perf.c'))
217
-endif
218
specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_ss)
219
220
specific_ss.add(when: ['CONFIG_SYSTEM_ONLY', 'CONFIG_TCG'], if_true: files(
221
diff --git a/tcg/meson.build b/tcg/meson.build
222
index XXXXXXX..XXXXXXX 100644
223
--- a/tcg/meson.build
224
+++ b/tcg/meson.build
225
@@ -XXX,XX +XXX,XX @@ if get_option('tcg_interpreter')
226
tcg_ss.add(files('tci.c'))
227
endif
228
229
+tcg_ss.add(when: libdw, if_true: files('debuginfo.c'))
230
+if host_os == 'linux'
231
+ tcg_ss.add(files('perf.c'))
232
+endif
233
+
234
tcg_ss = tcg_ss.apply({})
235
236
libtcg_user = static_library('tcg_user',
237
--
149
--
238
2.34.1
150
2.43.0
239
240
diff view generated by jsdifflib
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
1
The big comment just above says functions should be sorted.
2
2
3
Make sure that qemu gdbstub, like gdbserver, allows reading from and
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
writing to PROT_NONE pages.
5
6
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
7
Message-Id: <20240129093410.3151-4-iii@linux.ibm.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
5
---
10
tests/tcg/multiarch/prot-none.c | 40 ++++++++++++++++++++++++
6
tcg/optimize.c | 60 +++++++++++++++++++++++++-------------------------
11
tests/tcg/multiarch/Makefile.target | 9 +++++-
7
1 file changed, 30 insertions(+), 30 deletions(-)
12
tests/tcg/multiarch/gdbstub/prot-none.py | 36 +++++++++++++++++++++
13
3 files changed, 84 insertions(+), 1 deletion(-)
14
create mode 100644 tests/tcg/multiarch/prot-none.c
15
create mode 100644 tests/tcg/multiarch/gdbstub/prot-none.py
16
8
17
diff --git a/tests/tcg/multiarch/prot-none.c b/tests/tcg/multiarch/prot-none.c
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
18
new file mode 100644
10
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX
11
--- a/tcg/optimize.c
20
--- /dev/null
12
+++ b/tcg/optimize.c
21
+++ b/tests/tcg/multiarch/prot-none.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_call(OptContext *ctx, TCGOp *op)
22
@@ -XXX,XX +XXX,XX @@
14
return true;
23
+/*
15
}
24
+ * Test that GDB can access PROT_NONE pages.
16
25
+ *
17
+static bool fold_cmp_vec(OptContext *ctx, TCGOp *op)
26
+ * SPDX-License-Identifier: GPL-2.0-or-later
27
+ */
28
+#include <assert.h>
29
+#include <stdlib.h>
30
+#include <string.h>
31
+#include <sys/mman.h>
32
+#include <unistd.h>
33
+
34
+void break_here(void *q)
35
+{
18
+{
19
+ /* Canonicalize the comparison to put immediate second. */
20
+ if (swap_commutative(NO_DEST, &op->args[1], &op->args[2])) {
21
+ op->args[3] = tcg_swap_cond(op->args[3]);
22
+ }
23
+ return finish_folding(ctx, op);
36
+}
24
+}
37
+
25
+
38
+int main(void)
26
+static bool fold_cmpsel_vec(OptContext *ctx, TCGOp *op)
39
+{
27
+{
40
+ long pagesize = sysconf(_SC_PAGESIZE);
28
+ /* If true and false values are the same, eliminate the cmp. */
41
+ void *p, *q;
29
+ if (args_are_copies(op->args[3], op->args[4])) {
42
+ int err;
30
+ return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[3]);
43
+
44
+ p = mmap(NULL, pagesize * 2, PROT_READ | PROT_WRITE,
45
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
46
+ assert(p != MAP_FAILED);
47
+ q = p + pagesize - 1;
48
+ strcpy(q, "42");
49
+
50
+ err = mprotect(p, pagesize * 2, PROT_NONE);
51
+ assert(err == 0);
52
+
53
+ break_here(q);
54
+
55
+ err = mprotect(p, pagesize * 2, PROT_READ);
56
+ assert(err == 0);
57
+ if (getenv("PROT_NONE_PY")) {
58
+ assert(strcmp(q, "24") == 0);
59
+ }
31
+ }
60
+
32
+
61
+ return EXIT_SUCCESS;
33
+ /* Canonicalize the comparison to put immediate second. */
34
+ if (swap_commutative(NO_DEST, &op->args[1], &op->args[2])) {
35
+ op->args[5] = tcg_swap_cond(op->args[5]);
36
+ }
37
+ /*
38
+ * Canonicalize the "false" input reg to match the destination,
39
+ * so that the tcg backend can implement "move if true".
40
+ */
41
+ if (swap_commutative(op->args[0], &op->args[4], &op->args[3])) {
42
+ op->args[5] = tcg_invert_cond(op->args[5]);
43
+ }
44
+ return finish_folding(ctx, op);
62
+}
45
+}
63
diff --git a/tests/tcg/multiarch/Makefile.target b/tests/tcg/multiarch/Makefile.target
64
index XXXXXXX..XXXXXXX 100644
65
--- a/tests/tcg/multiarch/Makefile.target
66
+++ b/tests/tcg/multiarch/Makefile.target
67
@@ -XXX,XX +XXX,XX @@ run-gdbstub-registers: sha512
68
        --bin $< --test $(MULTIARCH_SRC)/gdbstub/registers.py, \
69
    checking register enumeration)
70
71
+run-gdbstub-prot-none: prot-none
72
+    $(call run-test, $@, env PROT_NONE_PY=1 $(GDB_SCRIPT) \
73
+        --gdb $(GDB) \
74
+        --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
75
+        --bin $< --test $(MULTIARCH_SRC)/gdbstub/prot-none.py, \
76
+    accessing PROT_NONE memory)
77
+
46
+
78
else
47
static bool fold_count_zeros(OptContext *ctx, TCGOp *op)
79
run-gdbstub-%:
48
{
80
    $(call skip-test, "gdbstub test $*", "need working gdb with $(patsubst -%,,$(TARGET_NAME)) support")
49
uint64_t z_mask, s_mask;
81
endif
50
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond2(OptContext *ctx, TCGOp *op)
82
EXTRA_RUNS += run-gdbstub-sha1 run-gdbstub-qxfer-auxv-read \
51
return tcg_opt_gen_movi(ctx, op, op->args[0], i);
83
     run-gdbstub-proc-mappings run-gdbstub-thread-breakpoint \
52
}
84
-     run-gdbstub-registers
53
85
+     run-gdbstub-registers run-gdbstub-prot-none
54
-static bool fold_cmp_vec(OptContext *ctx, TCGOp *op)
86
55
-{
87
# ARM Compatible Semi Hosting Tests
56
- /* Canonicalize the comparison to put immediate second. */
88
#
57
- if (swap_commutative(NO_DEST, &op->args[1], &op->args[2])) {
89
diff --git a/tests/tcg/multiarch/gdbstub/prot-none.py b/tests/tcg/multiarch/gdbstub/prot-none.py
58
- op->args[3] = tcg_swap_cond(op->args[3]);
90
new file mode 100644
59
- }
91
index XXXXXXX..XXXXXXX
60
- return finish_folding(ctx, op);
92
--- /dev/null
61
-}
93
+++ b/tests/tcg/multiarch/gdbstub/prot-none.py
62
-
94
@@ -XXX,XX +XXX,XX @@
63
-static bool fold_cmpsel_vec(OptContext *ctx, TCGOp *op)
95
+"""Test that GDB can access PROT_NONE pages.
64
-{
96
+
65
- /* If true and false values are the same, eliminate the cmp. */
97
+This runs as a sourced script (via -x, via run-test.py).
66
- if (args_are_copies(op->args[3], op->args[4])) {
98
+
67
- return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[3]);
99
+SPDX-License-Identifier: GPL-2.0-or-later
68
- }
100
+"""
69
-
101
+import ctypes
70
- /* Canonicalize the comparison to put immediate second. */
102
+from test_gdbstub import main, report
71
- if (swap_commutative(NO_DEST, &op->args[1], &op->args[2])) {
103
+
72
- op->args[5] = tcg_swap_cond(op->args[5]);
104
+
73
- }
105
+def probe_proc_self_mem():
74
- /*
106
+ buf = ctypes.create_string_buffer(b'aaa')
75
- * Canonicalize the "false" input reg to match the destination,
107
+ try:
76
- * so that the tcg backend can implement "move if true".
108
+ with open("/proc/self/mem", "rb") as fp:
77
- */
109
+ fp.seek(ctypes.addressof(buf))
78
- if (swap_commutative(op->args[0], &op->args[4], &op->args[3])) {
110
+ return fp.read(3) == b'aaa'
79
- op->args[5] = tcg_invert_cond(op->args[5]);
111
+ except OSError:
80
- }
112
+ return False
81
- return finish_folding(ctx, op);
113
+
82
-}
114
+
83
-
115
+def run_test():
84
static bool fold_sextract(OptContext *ctx, TCGOp *op)
116
+ """Run through the tests one by one"""
85
{
117
+ if not probe_proc_self_mem:
86
uint64_t z_mask, s_mask, s_mask_old;
118
+ print("SKIP: /proc/self/mem is not usable")
119
+ exit(0)
120
+ gdb.Breakpoint("break_here")
121
+ gdb.execute("continue")
122
+ val = gdb.parse_and_eval("*(char[2] *)q").string()
123
+ report(val == "42", "{} == 42".format(val))
124
+ gdb.execute("set *(char[3] *)q = \"24\"")
125
+ gdb.execute("continue")
126
+ exitcode = int(gdb.parse_and_eval("$_exitcode"))
127
+ report(exitcode == 0, "{} == 0".format(exitcode))
128
+
129
+
130
+main(run_test)
131
--
87
--
132
2.34.1
88
2.43.0
diff view generated by jsdifflib
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
1
We currently have a flag, float_muladd_halve_result, to scale
2
2
the result by 2**-1. Extend this to handle arbitrary scaling.
3
Currently tb_cflags() is defined in exec-all.h, which is not usable
4
from target-agnostic code. Move it to translation-block.h, which is.
5
3
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-ID: <20231212003837.64090-3-iii@linux.ibm.com>
10
Message-Id: <20240125054631.78867-3-philmd@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
---
6
---
13
include/exec/exec-all.h | 6 ------
7
include/fpu/softfloat.h | 6 ++++
14
include/exec/translation-block.h | 6 ++++++
8
fpu/softfloat.c | 58 ++++++++++++++++++++++-----------------
15
2 files changed, 6 insertions(+), 6 deletions(-)
9
fpu/softfloat-parts.c.inc | 7 +++--
16
10
3 files changed, 44 insertions(+), 27 deletions(-)
17
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
11
12
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/include/exec/exec-all.h
14
--- a/include/fpu/softfloat.h
20
+++ b/include/exec/exec-all.h
15
+++ b/include/fpu/softfloat.h
21
@@ -XXX,XX +XXX,XX @@ int probe_access_full_mmu(CPUArchState *env, vaddr addr, int size,
16
@@ -XXX,XX +XXX,XX @@ float16 float16_add(float16, float16, float_status *status);
22
17
float16 float16_sub(float16, float16, float_status *status);
23
#endif
18
float16 float16_mul(float16, float16, float_status *status);
24
19
float16 float16_muladd(float16, float16, float16, int, float_status *status);
25
-/* Hide the qatomic_read to make code a little easier on the eyes */
20
+float16 float16_muladd_scalbn(float16, float16, float16,
26
-static inline uint32_t tb_cflags(const TranslationBlock *tb)
21
+ int, int, float_status *status);
27
-{
22
float16 float16_div(float16, float16, float_status *status);
28
- return qatomic_read(&tb->cflags);
23
float16 float16_scalbn(float16, int, float_status *status);
29
-}
24
float16 float16_min(float16, float16, float_status *status);
30
-
25
@@ -XXX,XX +XXX,XX @@ float32 float32_mul(float32, float32, float_status *status);
31
static inline tb_page_addr_t tb_page_addr0(const TranslationBlock *tb)
26
float32 float32_div(float32, float32, float_status *status);
32
{
27
float32 float32_rem(float32, float32, float_status *status);
33
#ifdef CONFIG_USER_ONLY
28
float32 float32_muladd(float32, float32, float32, int, float_status *status);
34
diff --git a/include/exec/translation-block.h b/include/exec/translation-block.h
29
+float32 float32_muladd_scalbn(float32, float32, float32,
30
+ int, int, float_status *status);
31
float32 float32_sqrt(float32, float_status *status);
32
float32 float32_exp2(float32, float_status *status);
33
float32 float32_log2(float32, float_status *status);
34
@@ -XXX,XX +XXX,XX @@ float64 float64_mul(float64, float64, float_status *status);
35
float64 float64_div(float64, float64, float_status *status);
36
float64 float64_rem(float64, float64, float_status *status);
37
float64 float64_muladd(float64, float64, float64, int, float_status *status);
38
+float64 float64_muladd_scalbn(float64, float64, float64,
39
+ int, int, float_status *status);
40
float64 float64_sqrt(float64, float_status *status);
41
float64 float64_log2(float64, float_status *status);
42
FloatRelation float64_compare(float64, float64, float_status *status);
43
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
35
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
36
--- a/include/exec/translation-block.h
45
--- a/fpu/softfloat.c
37
+++ b/include/exec/translation-block.h
46
+++ b/fpu/softfloat.c
38
@@ -XXX,XX +XXX,XX @@ struct TranslationBlock {
47
@@ -XXX,XX +XXX,XX @@ static FloatParts128 *parts128_mul(FloatParts128 *a, FloatParts128 *b,
39
/* The alignment given to TranslationBlock during allocation. */
48
#define parts_mul(A, B, S) \
40
#define CODE_GEN_ALIGN 16
49
PARTS_GENERIC_64_128(mul, A)(A, B, S)
41
50
42
+/* Hide the qatomic_read to make code a little easier on the eyes */
51
-static FloatParts64 *parts64_muladd(FloatParts64 *a, FloatParts64 *b,
43
+static inline uint32_t tb_cflags(const TranslationBlock *tb)
52
- FloatParts64 *c, int flags,
53
- float_status *s);
54
-static FloatParts128 *parts128_muladd(FloatParts128 *a, FloatParts128 *b,
55
- FloatParts128 *c, int flags,
56
- float_status *s);
57
+static FloatParts64 *parts64_muladd_scalbn(FloatParts64 *a, FloatParts64 *b,
58
+ FloatParts64 *c, int scale,
59
+ int flags, float_status *s);
60
+static FloatParts128 *parts128_muladd_scalbn(FloatParts128 *a, FloatParts128 *b,
61
+ FloatParts128 *c, int scale,
62
+ int flags, float_status *s);
63
64
-#define parts_muladd(A, B, C, Z, S) \
65
- PARTS_GENERIC_64_128(muladd, A)(A, B, C, Z, S)
66
+#define parts_muladd_scalbn(A, B, C, Z, Y, S) \
67
+ PARTS_GENERIC_64_128(muladd_scalbn, A)(A, B, C, Z, Y, S)
68
69
static FloatParts64 *parts64_div(FloatParts64 *a, FloatParts64 *b,
70
float_status *s);
71
@@ -XXX,XX +XXX,XX @@ floatx80_mul(floatx80 a, floatx80 b, float_status *status)
72
* Fused multiply-add
73
*/
74
75
-float16 QEMU_FLATTEN float16_muladd(float16 a, float16 b, float16 c,
76
- int flags, float_status *status)
77
+float16 QEMU_FLATTEN
78
+float16_muladd_scalbn(float16 a, float16 b, float16 c,
79
+ int scale, int flags, float_status *status)
80
{
81
FloatParts64 pa, pb, pc, *pr;
82
83
float16_unpack_canonical(&pa, a, status);
84
float16_unpack_canonical(&pb, b, status);
85
float16_unpack_canonical(&pc, c, status);
86
- pr = parts_muladd(&pa, &pb, &pc, flags, status);
87
+ pr = parts_muladd_scalbn(&pa, &pb, &pc, scale, flags, status);
88
89
return float16_round_pack_canonical(pr, status);
90
}
91
92
-static float32 QEMU_SOFTFLOAT_ATTR
93
-soft_f32_muladd(float32 a, float32 b, float32 c, int flags,
94
- float_status *status)
95
+float16 float16_muladd(float16 a, float16 b, float16 c,
96
+ int flags, float_status *status)
44
+{
97
+{
45
+ return qatomic_read(&tb->cflags);
98
+ return float16_muladd_scalbn(a, b, c, 0, flags, status);
46
+}
99
+}
47
+
100
+
48
#endif /* EXEC_TRANSLATION_BLOCK_H */
101
+float32 QEMU_SOFTFLOAT_ATTR
102
+float32_muladd_scalbn(float32 a, float32 b, float32 c,
103
+ int scale, int flags, float_status *status)
104
{
105
FloatParts64 pa, pb, pc, *pr;
106
107
float32_unpack_canonical(&pa, a, status);
108
float32_unpack_canonical(&pb, b, status);
109
float32_unpack_canonical(&pc, c, status);
110
- pr = parts_muladd(&pa, &pb, &pc, flags, status);
111
+ pr = parts_muladd_scalbn(&pa, &pb, &pc, scale, flags, status);
112
113
return float32_round_pack_canonical(pr, status);
114
}
115
116
-static float64 QEMU_SOFTFLOAT_ATTR
117
-soft_f64_muladd(float64 a, float64 b, float64 c, int flags,
118
- float_status *status)
119
+float64 QEMU_SOFTFLOAT_ATTR
120
+float64_muladd_scalbn(float64 a, float64 b, float64 c,
121
+ int scale, int flags, float_status *status)
122
{
123
FloatParts64 pa, pb, pc, *pr;
124
125
float64_unpack_canonical(&pa, a, status);
126
float64_unpack_canonical(&pb, b, status);
127
float64_unpack_canonical(&pc, c, status);
128
- pr = parts_muladd(&pa, &pb, &pc, flags, status);
129
+ pr = parts_muladd_scalbn(&pa, &pb, &pc, scale, flags, status);
130
131
return float64_round_pack_canonical(pr, status);
132
}
133
@@ -XXX,XX +XXX,XX @@ float32_muladd(float32 xa, float32 xb, float32 xc, int flags, float_status *s)
134
return ur.s;
135
136
soft:
137
- return soft_f32_muladd(ua.s, ub.s, uc.s, flags, s);
138
+ return float32_muladd_scalbn(ua.s, ub.s, uc.s, 0, flags, s);
139
}
140
141
float64 QEMU_FLATTEN
142
@@ -XXX,XX +XXX,XX @@ float64_muladd(float64 xa, float64 xb, float64 xc, int flags, float_status *s)
143
return ur.s;
144
145
soft:
146
- return soft_f64_muladd(ua.s, ub.s, uc.s, flags, s);
147
+ return float64_muladd_scalbn(ua.s, ub.s, uc.s, 0, flags, s);
148
}
149
150
float64 float64r32_muladd(float64 a, float64 b, float64 c,
151
@@ -XXX,XX +XXX,XX @@ float64 float64r32_muladd(float64 a, float64 b, float64 c,
152
float64_unpack_canonical(&pa, a, status);
153
float64_unpack_canonical(&pb, b, status);
154
float64_unpack_canonical(&pc, c, status);
155
- pr = parts_muladd(&pa, &pb, &pc, flags, status);
156
+ pr = parts_muladd_scalbn(&pa, &pb, &pc, 0, flags, status);
157
158
return float64r32_round_pack_canonical(pr, status);
159
}
160
@@ -XXX,XX +XXX,XX @@ bfloat16 QEMU_FLATTEN bfloat16_muladd(bfloat16 a, bfloat16 b, bfloat16 c,
161
bfloat16_unpack_canonical(&pa, a, status);
162
bfloat16_unpack_canonical(&pb, b, status);
163
bfloat16_unpack_canonical(&pc, c, status);
164
- pr = parts_muladd(&pa, &pb, &pc, flags, status);
165
+ pr = parts_muladd_scalbn(&pa, &pb, &pc, 0, flags, status);
166
167
return bfloat16_round_pack_canonical(pr, status);
168
}
169
@@ -XXX,XX +XXX,XX @@ float128 QEMU_FLATTEN float128_muladd(float128 a, float128 b, float128 c,
170
float128_unpack_canonical(&pa, a, status);
171
float128_unpack_canonical(&pb, b, status);
172
float128_unpack_canonical(&pc, c, status);
173
- pr = parts_muladd(&pa, &pb, &pc, flags, status);
174
+ pr = parts_muladd_scalbn(&pa, &pb, &pc, 0, flags, status);
175
176
return float128_round_pack_canonical(pr, status);
177
}
178
@@ -XXX,XX +XXX,XX @@ float32 float32_exp2(float32 a, float_status *status)
179
180
float64_unpack_canonical(&rp, float64_one, status);
181
for (i = 0 ; i < 15 ; i++) {
182
+
183
float64_unpack_canonical(&tp, float32_exp2_coefficients[i], status);
184
- rp = *parts_muladd(&tp, &xnp, &rp, 0, status);
185
+ rp = *parts_muladd_scalbn(&tp, &xnp, &rp, 0, 0, status);
186
xnp = *parts_mul(&xnp, &xp, status);
187
}
188
189
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
190
index XXXXXXX..XXXXXXX 100644
191
--- a/fpu/softfloat-parts.c.inc
192
+++ b/fpu/softfloat-parts.c.inc
193
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(mul)(FloatPartsN *a, FloatPartsN *b,
194
* Requires A and C extracted into a double-sized structure to provide the
195
* extra space for the widening multiply.
196
*/
197
-static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b,
198
- FloatPartsN *c, int flags, float_status *s)
199
+static FloatPartsN *partsN(muladd_scalbn)(FloatPartsN *a, FloatPartsN *b,
200
+ FloatPartsN *c, int scale,
201
+ int flags, float_status *s)
202
{
203
int ab_mask, abc_mask;
204
FloatPartsW p_widen, c_widen;
205
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b,
206
a->exp = p_widen.exp;
207
208
return_normal:
209
+ /* TODO: Replace all use of float_muladd_halve_result with scale. */
210
if (flags & float_muladd_halve_result) {
211
a->exp -= 1;
212
}
213
+ a->exp += scale;
214
finish_sign:
215
if (flags & float_muladd_negate_result) {
216
a->sign ^= 1;
49
--
217
--
50
2.34.1
218
2.43.0
51
219
52
220
diff view generated by jsdifflib
1
QEMU coding style recommends using structure typedefs.
1
Use the scalbn interface instead of float_muladd_halve_result.
2
2
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
5
---
6
include/hw/core/cpu.h | 5 +----
6
target/arm/tcg/helper-a64.c | 6 +++---
7
include/qemu/typedefs.h | 1 +
7
1 file changed, 3 insertions(+), 3 deletions(-)
8
bsd-user/signal.c | 4 ++--
9
linux-user/signal.c | 4 ++--
10
target/alpha/cpu.c | 2 +-
11
target/arm/cpu.c | 2 +-
12
target/arm/tcg/cpu32.c | 2 +-
13
target/avr/cpu.c | 2 +-
14
target/cris/cpu.c | 4 ++--
15
target/hexagon/cpu.c | 2 +-
16
target/hppa/cpu.c | 2 +-
17
target/i386/tcg/tcg-cpu.c | 2 +-
18
target/loongarch/cpu.c | 2 +-
19
target/m68k/cpu.c | 2 +-
20
target/microblaze/cpu.c | 2 +-
21
target/mips/cpu.c | 2 +-
22
target/nios2/cpu.c | 2 +-
23
target/openrisc/cpu.c | 2 +-
24
target/ppc/cpu_init.c | 2 +-
25
target/riscv/tcg/tcg-cpu.c | 2 +-
26
target/rx/cpu.c | 2 +-
27
target/s390x/cpu.c | 2 +-
28
target/sh4/cpu.c | 2 +-
29
target/sparc/cpu.c | 2 +-
30
target/tricore/cpu.c | 2 +-
31
target/xtensa/cpu.c | 2 +-
32
26 files changed, 29 insertions(+), 31 deletions(-)
33
8
34
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
9
diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c
35
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/core/cpu.h
11
--- a/target/arm/tcg/helper-a64.c
37
+++ b/include/hw/core/cpu.h
12
+++ b/target/arm/tcg/helper-a64.c
38
@@ -XXX,XX +XXX,XX @@ typedef enum MMUAccessType {
13
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(rsqrtsf_f16)(uint32_t a, uint32_t b, float_status *fpst)
39
14
(float16_is_infinity(b) && float16_is_zero(a))) {
40
typedef struct CPUWatchpoint CPUWatchpoint;
15
return float16_one_point_five;
41
16
}
42
-/* see tcg-cpu-ops.h */
17
- return float16_muladd(a, b, float16_three, float_muladd_halve_result, fpst);
43
-struct TCGCPUOps;
18
+ return float16_muladd_scalbn(a, b, float16_three, -1, 0, fpst);
44
-
45
/* see accel-cpu.h */
46
struct AccelCPUClass;
47
48
@@ -XXX,XX +XXX,XX @@ struct CPUClass {
49
const struct SysemuCPUOps *sysemu_ops;
50
51
/* when TCG is not available, this pointer is NULL */
52
- const struct TCGCPUOps *tcg_ops;
53
+ const TCGCPUOps *tcg_ops;
54
55
/*
56
* if not NULL, this is called in order for the CPUClass to initialize
57
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
58
index XXXXXXX..XXXXXXX 100644
59
--- a/include/qemu/typedefs.h
60
+++ b/include/qemu/typedefs.h
61
@@ -XXX,XX +XXX,XX @@ typedef struct Range Range;
62
typedef struct ReservedRegion ReservedRegion;
63
typedef struct SHPCDevice SHPCDevice;
64
typedef struct SSIBus SSIBus;
65
+typedef struct TCGCPUOps TCGCPUOps;
66
typedef struct TCGHelperInfo TCGHelperInfo;
67
typedef struct TranslationBlock TranslationBlock;
68
typedef struct VirtIODevice VirtIODevice;
69
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/bsd-user/signal.c
72
+++ b/bsd-user/signal.c
73
@@ -XXX,XX +XXX,XX @@ void process_pending_signals(CPUArchState *env)
74
void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr,
75
MMUAccessType access_type, bool maperr, uintptr_t ra)
76
{
77
- const struct TCGCPUOps *tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
78
+ const TCGCPUOps *tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
79
80
if (tcg_ops->record_sigsegv) {
81
tcg_ops->record_sigsegv(cpu, addr, access_type, maperr, ra);
82
@@ -XXX,XX +XXX,XX @@ void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr,
83
void cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr,
84
MMUAccessType access_type, uintptr_t ra)
85
{
86
- const struct TCGCPUOps *tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
87
+ const TCGCPUOps *tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
88
89
if (tcg_ops->record_sigbus) {
90
tcg_ops->record_sigbus(cpu, addr, access_type, ra);
91
diff --git a/linux-user/signal.c b/linux-user/signal.c
92
index XXXXXXX..XXXXXXX 100644
93
--- a/linux-user/signal.c
94
+++ b/linux-user/signal.c
95
@@ -XXX,XX +XXX,XX @@ void force_sigsegv(int oldsig)
96
void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr,
97
MMUAccessType access_type, bool maperr, uintptr_t ra)
98
{
99
- const struct TCGCPUOps *tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
100
+ const TCGCPUOps *tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
101
102
if (tcg_ops->record_sigsegv) {
103
tcg_ops->record_sigsegv(cpu, addr, access_type, maperr, ra);
104
@@ -XXX,XX +XXX,XX @@ void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr,
105
void cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr,
106
MMUAccessType access_type, uintptr_t ra)
107
{
108
- const struct TCGCPUOps *tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
109
+ const TCGCPUOps *tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
110
111
if (tcg_ops->record_sigbus) {
112
tcg_ops->record_sigbus(cpu, addr, access_type, ra);
113
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/target/alpha/cpu.c
116
+++ b/target/alpha/cpu.c
117
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps alpha_sysemu_ops = {
118
119
#include "hw/core/tcg-cpu-ops.h"
120
121
-static const struct TCGCPUOps alpha_tcg_ops = {
122
+static const TCGCPUOps alpha_tcg_ops = {
123
.initialize = alpha_translate_init,
124
.restore_state_to_opc = alpha_restore_state_to_opc,
125
126
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/target/arm/cpu.c
129
+++ b/target/arm/cpu.c
130
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps arm_sysemu_ops = {
131
#endif
132
133
#ifdef CONFIG_TCG
134
-static const struct TCGCPUOps arm_tcg_ops = {
135
+static const TCGCPUOps arm_tcg_ops = {
136
.initialize = arm_translate_init,
137
.synchronize_from_tb = arm_cpu_synchronize_from_tb,
138
.debug_excp_handler = arm_debug_excp_handler,
139
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
140
index XXXXXXX..XXXXXXX 100644
141
--- a/target/arm/tcg/cpu32.c
142
+++ b/target/arm/tcg/cpu32.c
143
@@ -XXX,XX +XXX,XX @@ static void pxa270c5_initfn(Object *obj)
144
cpu->reset_sctlr = 0x00000078;
145
}
19
}
146
20
147
-static const struct TCGCPUOps arm_v7m_tcg_ops = {
21
float32 HELPER(rsqrtsf_f32)(float32 a, float32 b, float_status *fpst)
148
+static const TCGCPUOps arm_v7m_tcg_ops = {
22
@@ -XXX,XX +XXX,XX @@ float32 HELPER(rsqrtsf_f32)(float32 a, float32 b, float_status *fpst)
149
.initialize = arm_translate_init,
23
(float32_is_infinity(b) && float32_is_zero(a))) {
150
.synchronize_from_tb = arm_cpu_synchronize_from_tb,
24
return float32_one_point_five;
151
.debug_excp_handler = arm_debug_excp_handler,
25
}
152
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
26
- return float32_muladd(a, b, float32_three, float_muladd_halve_result, fpst);
153
index XXXXXXX..XXXXXXX 100644
27
+ return float32_muladd_scalbn(a, b, float32_three, -1, 0, fpst);
154
--- a/target/avr/cpu.c
155
+++ b/target/avr/cpu.c
156
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps avr_sysemu_ops = {
157
158
#include "hw/core/tcg-cpu-ops.h"
159
160
-static const struct TCGCPUOps avr_tcg_ops = {
161
+static const TCGCPUOps avr_tcg_ops = {
162
.initialize = avr_cpu_tcg_init,
163
.synchronize_from_tb = avr_cpu_synchronize_from_tb,
164
.restore_state_to_opc = avr_restore_state_to_opc,
165
diff --git a/target/cris/cpu.c b/target/cris/cpu.c
166
index XXXXXXX..XXXXXXX 100644
167
--- a/target/cris/cpu.c
168
+++ b/target/cris/cpu.c
169
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps cris_sysemu_ops = {
170
171
#include "hw/core/tcg-cpu-ops.h"
172
173
-static const struct TCGCPUOps crisv10_tcg_ops = {
174
+static const TCGCPUOps crisv10_tcg_ops = {
175
.initialize = cris_initialize_crisv10_tcg,
176
.restore_state_to_opc = cris_restore_state_to_opc,
177
178
@@ -XXX,XX +XXX,XX @@ static const struct TCGCPUOps crisv10_tcg_ops = {
179
#endif /* !CONFIG_USER_ONLY */
180
};
181
182
-static const struct TCGCPUOps crisv32_tcg_ops = {
183
+static const TCGCPUOps crisv32_tcg_ops = {
184
.initialize = cris_initialize_tcg,
185
.restore_state_to_opc = cris_restore_state_to_opc,
186
187
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
188
index XXXXXXX..XXXXXXX 100644
189
--- a/target/hexagon/cpu.c
190
+++ b/target/hexagon/cpu.c
191
@@ -XXX,XX +XXX,XX @@ static void hexagon_cpu_init(Object *obj)
192
193
#include "hw/core/tcg-cpu-ops.h"
194
195
-static const struct TCGCPUOps hexagon_tcg_ops = {
196
+static const TCGCPUOps hexagon_tcg_ops = {
197
.initialize = hexagon_translate_init,
198
.synchronize_from_tb = hexagon_cpu_synchronize_from_tb,
199
.restore_state_to_opc = hexagon_restore_state_to_opc,
200
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
201
index XXXXXXX..XXXXXXX 100644
202
--- a/target/hppa/cpu.c
203
+++ b/target/hppa/cpu.c
204
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps hppa_sysemu_ops = {
205
206
#include "hw/core/tcg-cpu-ops.h"
207
208
-static const struct TCGCPUOps hppa_tcg_ops = {
209
+static const TCGCPUOps hppa_tcg_ops = {
210
.initialize = hppa_translate_init,
211
.synchronize_from_tb = hppa_cpu_synchronize_from_tb,
212
.restore_state_to_opc = hppa_restore_state_to_opc,
213
diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c
214
index XXXXXXX..XXXXXXX 100644
215
--- a/target/i386/tcg/tcg-cpu.c
216
+++ b/target/i386/tcg/tcg-cpu.c
217
@@ -XXX,XX +XXX,XX @@ static bool x86_debug_check_breakpoint(CPUState *cs)
218
219
#include "hw/core/tcg-cpu-ops.h"
220
221
-static const struct TCGCPUOps x86_tcg_ops = {
222
+static const TCGCPUOps x86_tcg_ops = {
223
.initialize = tcg_x86_init,
224
.synchronize_from_tb = x86_cpu_synchronize_from_tb,
225
.restore_state_to_opc = x86_restore_state_to_opc,
226
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
227
index XXXXXXX..XXXXXXX 100644
228
--- a/target/loongarch/cpu.c
229
+++ b/target/loongarch/cpu.c
230
@@ -XXX,XX +XXX,XX @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags)
231
#ifdef CONFIG_TCG
232
#include "hw/core/tcg-cpu-ops.h"
233
234
-static struct TCGCPUOps loongarch_tcg_ops = {
235
+static TCGCPUOps loongarch_tcg_ops = {
236
.initialize = loongarch_translate_init,
237
.synchronize_from_tb = loongarch_cpu_synchronize_from_tb,
238
.restore_state_to_opc = loongarch_restore_state_to_opc,
239
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
240
index XXXXXXX..XXXXXXX 100644
241
--- a/target/m68k/cpu.c
242
+++ b/target/m68k/cpu.c
243
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps m68k_sysemu_ops = {
244
245
#include "hw/core/tcg-cpu-ops.h"
246
247
-static const struct TCGCPUOps m68k_tcg_ops = {
248
+static const TCGCPUOps m68k_tcg_ops = {
249
.initialize = m68k_tcg_init,
250
.restore_state_to_opc = m68k_restore_state_to_opc,
251
252
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
253
index XXXXXXX..XXXXXXX 100644
254
--- a/target/microblaze/cpu.c
255
+++ b/target/microblaze/cpu.c
256
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps mb_sysemu_ops = {
257
258
#include "hw/core/tcg-cpu-ops.h"
259
260
-static const struct TCGCPUOps mb_tcg_ops = {
261
+static const TCGCPUOps mb_tcg_ops = {
262
.initialize = mb_tcg_init,
263
.synchronize_from_tb = mb_cpu_synchronize_from_tb,
264
.restore_state_to_opc = mb_restore_state_to_opc,
265
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
266
index XXXXXXX..XXXXXXX 100644
267
--- a/target/mips/cpu.c
268
+++ b/target/mips/cpu.c
269
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps mips_sysemu_ops = {
270
* NB: cannot be const, as some elements are changed for specific
271
* mips hardware (see hw/mips/jazz.c).
272
*/
273
-static const struct TCGCPUOps mips_tcg_ops = {
274
+static const TCGCPUOps mips_tcg_ops = {
275
.initialize = mips_tcg_init,
276
.synchronize_from_tb = mips_cpu_synchronize_from_tb,
277
.restore_state_to_opc = mips_restore_state_to_opc,
278
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
279
index XXXXXXX..XXXXXXX 100644
280
--- a/target/nios2/cpu.c
281
+++ b/target/nios2/cpu.c
282
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps nios2_sysemu_ops = {
283
284
#include "hw/core/tcg-cpu-ops.h"
285
286
-static const struct TCGCPUOps nios2_tcg_ops = {
287
+static const TCGCPUOps nios2_tcg_ops = {
288
.initialize = nios2_tcg_init,
289
.restore_state_to_opc = nios2_restore_state_to_opc,
290
291
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
292
index XXXXXXX..XXXXXXX 100644
293
--- a/target/openrisc/cpu.c
294
+++ b/target/openrisc/cpu.c
295
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps openrisc_sysemu_ops = {
296
297
#include "hw/core/tcg-cpu-ops.h"
298
299
-static const struct TCGCPUOps openrisc_tcg_ops = {
300
+static const TCGCPUOps openrisc_tcg_ops = {
301
.initialize = openrisc_translate_init,
302
.synchronize_from_tb = openrisc_cpu_synchronize_from_tb,
303
.restore_state_to_opc = openrisc_restore_state_to_opc,
304
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
305
index XXXXXXX..XXXXXXX 100644
306
--- a/target/ppc/cpu_init.c
307
+++ b/target/ppc/cpu_init.c
308
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps ppc_sysemu_ops = {
309
#ifdef CONFIG_TCG
310
#include "hw/core/tcg-cpu-ops.h"
311
312
-static const struct TCGCPUOps ppc_tcg_ops = {
313
+static const TCGCPUOps ppc_tcg_ops = {
314
.initialize = ppc_translate_init,
315
.restore_state_to_opc = ppc_restore_state_to_opc,
316
317
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
318
index XXXXXXX..XXXXXXX 100644
319
--- a/target/riscv/tcg/tcg-cpu.c
320
+++ b/target/riscv/tcg/tcg-cpu.c
321
@@ -XXX,XX +XXX,XX @@ static void riscv_restore_state_to_opc(CPUState *cs,
322
env->bins = data[1];
323
}
28
}
324
29
325
-static const struct TCGCPUOps riscv_tcg_ops = {
30
float64 HELPER(rsqrtsf_f64)(float64 a, float64 b, float_status *fpst)
326
+static const TCGCPUOps riscv_tcg_ops = {
31
@@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrtsf_f64)(float64 a, float64 b, float_status *fpst)
327
.initialize = riscv_translate_init,
32
(float64_is_infinity(b) && float64_is_zero(a))) {
328
.synchronize_from_tb = riscv_cpu_synchronize_from_tb,
33
return float64_one_point_five;
329
.restore_state_to_opc = riscv_restore_state_to_opc,
34
}
330
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
35
- return float64_muladd(a, b, float64_three, float_muladd_halve_result, fpst);
331
index XXXXXXX..XXXXXXX 100644
36
+ return float64_muladd_scalbn(a, b, float64_three, -1, 0, fpst);
332
--- a/target/rx/cpu.c
37
}
333
+++ b/target/rx/cpu.c
38
334
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps rx_sysemu_ops = {
39
/* Floating-point reciprocal exponent - see FPRecpX in ARM ARM */
335
336
#include "hw/core/tcg-cpu-ops.h"
337
338
-static const struct TCGCPUOps rx_tcg_ops = {
339
+static const TCGCPUOps rx_tcg_ops = {
340
.initialize = rx_translate_init,
341
.synchronize_from_tb = rx_cpu_synchronize_from_tb,
342
.restore_state_to_opc = rx_restore_state_to_opc,
343
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
344
index XXXXXXX..XXXXXXX 100644
345
--- a/target/s390x/cpu.c
346
+++ b/target/s390x/cpu.c
347
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_full(DeviceState *dev)
348
#ifdef CONFIG_TCG
349
#include "hw/core/tcg-cpu-ops.h"
350
351
-static const struct TCGCPUOps s390_tcg_ops = {
352
+static const TCGCPUOps s390_tcg_ops = {
353
.initialize = s390x_translate_init,
354
.restore_state_to_opc = s390x_restore_state_to_opc,
355
356
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
357
index XXXXXXX..XXXXXXX 100644
358
--- a/target/sh4/cpu.c
359
+++ b/target/sh4/cpu.c
360
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps sh4_sysemu_ops = {
361
362
#include "hw/core/tcg-cpu-ops.h"
363
364
-static const struct TCGCPUOps superh_tcg_ops = {
365
+static const TCGCPUOps superh_tcg_ops = {
366
.initialize = sh4_translate_init,
367
.synchronize_from_tb = superh_cpu_synchronize_from_tb,
368
.restore_state_to_opc = superh_restore_state_to_opc,
369
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
370
index XXXXXXX..XXXXXXX 100644
371
--- a/target/sparc/cpu.c
372
+++ b/target/sparc/cpu.c
373
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps sparc_sysemu_ops = {
374
#ifdef CONFIG_TCG
375
#include "hw/core/tcg-cpu-ops.h"
376
377
-static const struct TCGCPUOps sparc_tcg_ops = {
378
+static const TCGCPUOps sparc_tcg_ops = {
379
.initialize = sparc_tcg_init,
380
.synchronize_from_tb = sparc_cpu_synchronize_from_tb,
381
.restore_state_to_opc = sparc_restore_state_to_opc,
382
diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c
383
index XXXXXXX..XXXXXXX 100644
384
--- a/target/tricore/cpu.c
385
+++ b/target/tricore/cpu.c
386
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps tricore_sysemu_ops = {
387
388
#include "hw/core/tcg-cpu-ops.h"
389
390
-static const struct TCGCPUOps tricore_tcg_ops = {
391
+static const TCGCPUOps tricore_tcg_ops = {
392
.initialize = tricore_tcg_init,
393
.synchronize_from_tb = tricore_cpu_synchronize_from_tb,
394
.restore_state_to_opc = tricore_restore_state_to_opc,
395
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
396
index XXXXXXX..XXXXXXX 100644
397
--- a/target/xtensa/cpu.c
398
+++ b/target/xtensa/cpu.c
399
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps xtensa_sysemu_ops = {
400
401
#include "hw/core/tcg-cpu-ops.h"
402
403
-static const struct TCGCPUOps xtensa_tcg_ops = {
404
+static const TCGCPUOps xtensa_tcg_ops = {
405
.initialize = xtensa_translate_init,
406
.debug_excp_handler = xtensa_breakpoint_handler,
407
.restore_state_to_opc = xtensa_restore_state_to_opc,
408
--
40
--
409
2.34.1
41
2.43.0
410
42
411
43
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
Use the scalbn interface instead of float_muladd_halve_result.
2
2
3
Replace the manual rcu_read_(un)lock calls in cpu_exec().
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-Id: <20240124074201.8239-2-philmd@linaro.org>
7
[rth: Use RCU_READ_LOCK_GUARD not WITH_RCU_READ_LOCK_GUARD]
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
5
---
11
accel/tcg/cpu-exec.c | 4 +---
6
target/sparc/helper.h | 4 +-
12
1 file changed, 1 insertion(+), 3 deletions(-)
7
target/sparc/fop_helper.c | 8 ++--
13
8
target/sparc/translate.c | 80 +++++++++++++++++++++++----------------
14
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
9
3 files changed, 54 insertions(+), 38 deletions(-)
10
11
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
15
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
16
--- a/accel/tcg/cpu-exec.c
13
--- a/target/sparc/helper.h
17
+++ b/accel/tcg/cpu-exec.c
14
+++ b/target/sparc/helper.h
18
@@ -XXX,XX +XXX,XX @@ int cpu_exec(CPUState *cpu)
15
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_WG, f64, env, f64, f64)
19
return EXCP_HALTED;
16
DEF_HELPER_FLAGS_3(fsubd, TCG_CALL_NO_WG, f64, env, f64, f64)
20
}
17
DEF_HELPER_FLAGS_3(fmuld, TCG_CALL_NO_WG, f64, env, f64, f64)
21
18
DEF_HELPER_FLAGS_3(fdivd, TCG_CALL_NO_WG, f64, env, f64, f64)
22
- rcu_read_lock();
19
-DEF_HELPER_FLAGS_5(fmaddd, TCG_CALL_NO_WG, f64, env, f64, f64, f64, i32)
23
+ RCU_READ_LOCK_GUARD();
20
+DEF_HELPER_FLAGS_6(fmaddd, TCG_CALL_NO_WG, f64, env, f64, f64, f64, s32, i32)
24
cpu_exec_enter(cpu);
21
DEF_HELPER_FLAGS_3(fnaddd, TCG_CALL_NO_WG, f64, env, f64, f64)
25
22
DEF_HELPER_FLAGS_3(fnmuld, TCG_CALL_NO_WG, f64, env, f64, f64)
26
/*
23
27
@@ -XXX,XX +XXX,XX @@ int cpu_exec(CPUState *cpu)
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(fadds, TCG_CALL_NO_WG, f32, env, f32, f32)
28
ret = cpu_exec_setjmp(cpu, &sc);
25
DEF_HELPER_FLAGS_3(fsubs, TCG_CALL_NO_WG, f32, env, f32, f32)
29
26
DEF_HELPER_FLAGS_3(fmuls, TCG_CALL_NO_WG, f32, env, f32, f32)
30
cpu_exec_exit(cpu);
27
DEF_HELPER_FLAGS_3(fdivs, TCG_CALL_NO_WG, f32, env, f32, f32)
31
- rcu_read_unlock();
28
-DEF_HELPER_FLAGS_5(fmadds, TCG_CALL_NO_WG, f32, env, f32, f32, f32, i32)
32
-
29
+DEF_HELPER_FLAGS_6(fmadds, TCG_CALL_NO_WG, f32, env, f32, f32, f32, s32, i32)
30
DEF_HELPER_FLAGS_3(fnadds, TCG_CALL_NO_WG, f32, env, f32, f32)
31
DEF_HELPER_FLAGS_3(fnmuls, TCG_CALL_NO_WG, f32, env, f32, f32)
32
33
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/sparc/fop_helper.c
36
+++ b/target/sparc/fop_helper.c
37
@@ -XXX,XX +XXX,XX @@ Int128 helper_fsqrtq(CPUSPARCState *env, Int128 src)
38
}
39
40
float32 helper_fmadds(CPUSPARCState *env, float32 s1,
41
- float32 s2, float32 s3, uint32_t op)
42
+ float32 s2, float32 s3, int32_t sc, uint32_t op)
43
{
44
- float32 ret = float32_muladd(s1, s2, s3, op, &env->fp_status);
45
+ float32 ret = float32_muladd_scalbn(s1, s2, s3, sc, op, &env->fp_status);
46
check_ieee_exceptions(env, GETPC());
33
return ret;
47
return ret;
34
}
48
}
35
49
50
float64 helper_fmaddd(CPUSPARCState *env, float64 s1,
51
- float64 s2, float64 s3, uint32_t op)
52
+ float64 s2, float64 s3, int32_t sc, uint32_t op)
53
{
54
- float64 ret = float64_muladd(s1, s2, s3, op, &env->fp_status);
55
+ float64 ret = float64_muladd_scalbn(s1, s2, s3, sc, op, &env->fp_status);
56
check_ieee_exceptions(env, GETPC());
57
return ret;
58
}
59
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/target/sparc/translate.c
62
+++ b/target/sparc/translate.c
63
@@ -XXX,XX +XXX,XX @@ static void gen_op_fabsq(TCGv_i128 dst, TCGv_i128 src)
64
65
static void gen_op_fmadds(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2, TCGv_i32 s3)
66
{
67
- gen_helper_fmadds(d, tcg_env, s1, s2, s3, tcg_constant_i32(0));
68
+ TCGv_i32 z = tcg_constant_i32(0);
69
+ gen_helper_fmadds(d, tcg_env, s1, s2, s3, z, z);
70
}
71
72
static void gen_op_fmaddd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2, TCGv_i64 s3)
73
{
74
- gen_helper_fmaddd(d, tcg_env, s1, s2, s3, tcg_constant_i32(0));
75
+ TCGv_i32 z = tcg_constant_i32(0);
76
+ gen_helper_fmaddd(d, tcg_env, s1, s2, s3, z, z);
77
}
78
79
static void gen_op_fmsubs(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2, TCGv_i32 s3)
80
{
81
- int op = float_muladd_negate_c;
82
- gen_helper_fmadds(d, tcg_env, s1, s2, s3, tcg_constant_i32(op));
83
+ TCGv_i32 z = tcg_constant_i32(0);
84
+ TCGv_i32 op = tcg_constant_i32(float_muladd_negate_c);
85
+ gen_helper_fmadds(d, tcg_env, s1, s2, s3, z, op);
86
}
87
88
static void gen_op_fmsubd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2, TCGv_i64 s3)
89
{
90
- int op = float_muladd_negate_c;
91
- gen_helper_fmaddd(d, tcg_env, s1, s2, s3, tcg_constant_i32(op));
92
+ TCGv_i32 z = tcg_constant_i32(0);
93
+ TCGv_i32 op = tcg_constant_i32(float_muladd_negate_c);
94
+ gen_helper_fmaddd(d, tcg_env, s1, s2, s3, z, op);
95
}
96
97
static void gen_op_fnmsubs(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2, TCGv_i32 s3)
98
{
99
- int op = float_muladd_negate_c | float_muladd_negate_result;
100
- gen_helper_fmadds(d, tcg_env, s1, s2, s3, tcg_constant_i32(op));
101
+ TCGv_i32 z = tcg_constant_i32(0);
102
+ TCGv_i32 op = tcg_constant_i32(float_muladd_negate_c |
103
+ float_muladd_negate_result);
104
+ gen_helper_fmadds(d, tcg_env, s1, s2, s3, z, op);
105
}
106
107
static void gen_op_fnmsubd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2, TCGv_i64 s3)
108
{
109
- int op = float_muladd_negate_c | float_muladd_negate_result;
110
- gen_helper_fmaddd(d, tcg_env, s1, s2, s3, tcg_constant_i32(op));
111
+ TCGv_i32 z = tcg_constant_i32(0);
112
+ TCGv_i32 op = tcg_constant_i32(float_muladd_negate_c |
113
+ float_muladd_negate_result);
114
+ gen_helper_fmaddd(d, tcg_env, s1, s2, s3, z, op);
115
}
116
117
static void gen_op_fnmadds(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2, TCGv_i32 s3)
118
{
119
- int op = float_muladd_negate_result;
120
- gen_helper_fmadds(d, tcg_env, s1, s2, s3, tcg_constant_i32(op));
121
+ TCGv_i32 z = tcg_constant_i32(0);
122
+ TCGv_i32 op = tcg_constant_i32(float_muladd_negate_result);
123
+ gen_helper_fmadds(d, tcg_env, s1, s2, s3, z, op);
124
}
125
126
static void gen_op_fnmaddd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2, TCGv_i64 s3)
127
{
128
- int op = float_muladd_negate_result;
129
- gen_helper_fmaddd(d, tcg_env, s1, s2, s3, tcg_constant_i32(op));
130
+ TCGv_i32 z = tcg_constant_i32(0);
131
+ TCGv_i32 op = tcg_constant_i32(float_muladd_negate_result);
132
+ gen_helper_fmaddd(d, tcg_env, s1, s2, s3, z, op);
133
}
134
135
/* Use muladd to compute (1 * src1) + src2 / 2 with one rounding. */
136
static void gen_op_fhadds(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2)
137
{
138
- TCGv_i32 one = tcg_constant_i32(float32_one);
139
- int op = float_muladd_halve_result;
140
- gen_helper_fmadds(d, tcg_env, one, s1, s2, tcg_constant_i32(op));
141
+ TCGv_i32 fone = tcg_constant_i32(float32_one);
142
+ TCGv_i32 mone = tcg_constant_i32(-1);
143
+ TCGv_i32 op = tcg_constant_i32(0);
144
+ gen_helper_fmadds(d, tcg_env, fone, s1, s2, mone, op);
145
}
146
147
static void gen_op_fhaddd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2)
148
{
149
- TCGv_i64 one = tcg_constant_i64(float64_one);
150
- int op = float_muladd_halve_result;
151
- gen_helper_fmaddd(d, tcg_env, one, s1, s2, tcg_constant_i32(op));
152
+ TCGv_i64 fone = tcg_constant_i64(float64_one);
153
+ TCGv_i32 mone = tcg_constant_i32(-1);
154
+ TCGv_i32 op = tcg_constant_i32(0);
155
+ gen_helper_fmaddd(d, tcg_env, fone, s1, s2, mone, op);
156
}
157
158
/* Use muladd to compute (1 * src1) - src2 / 2 with one rounding. */
159
static void gen_op_fhsubs(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2)
160
{
161
- TCGv_i32 one = tcg_constant_i32(float32_one);
162
- int op = float_muladd_negate_c | float_muladd_halve_result;
163
- gen_helper_fmadds(d, tcg_env, one, s1, s2, tcg_constant_i32(op));
164
+ TCGv_i32 fone = tcg_constant_i32(float32_one);
165
+ TCGv_i32 mone = tcg_constant_i32(-1);
166
+ TCGv_i32 op = tcg_constant_i32(float_muladd_negate_c);
167
+ gen_helper_fmadds(d, tcg_env, fone, s1, s2, mone, op);
168
}
169
170
static void gen_op_fhsubd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2)
171
{
172
- TCGv_i64 one = tcg_constant_i64(float64_one);
173
- int op = float_muladd_negate_c | float_muladd_halve_result;
174
- gen_helper_fmaddd(d, tcg_env, one, s1, s2, tcg_constant_i32(op));
175
+ TCGv_i64 fone = tcg_constant_i64(float64_one);
176
+ TCGv_i32 mone = tcg_constant_i32(-1);
177
+ TCGv_i32 op = tcg_constant_i32(float_muladd_negate_c);
178
+ gen_helper_fmaddd(d, tcg_env, fone, s1, s2, mone, op);
179
}
180
181
/* Use muladd to compute -((1 * src1) + src2 / 2) with one rounding. */
182
static void gen_op_fnhadds(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2)
183
{
184
- TCGv_i32 one = tcg_constant_i32(float32_one);
185
- int op = float_muladd_negate_result | float_muladd_halve_result;
186
- gen_helper_fmadds(d, tcg_env, one, s1, s2, tcg_constant_i32(op));
187
+ TCGv_i32 fone = tcg_constant_i32(float32_one);
188
+ TCGv_i32 mone = tcg_constant_i32(-1);
189
+ TCGv_i32 op = tcg_constant_i32(float_muladd_negate_result);
190
+ gen_helper_fmadds(d, tcg_env, fone, s1, s2, mone, op);
191
}
192
193
static void gen_op_fnhaddd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2)
194
{
195
- TCGv_i64 one = tcg_constant_i64(float64_one);
196
- int op = float_muladd_negate_result | float_muladd_halve_result;
197
- gen_helper_fmaddd(d, tcg_env, one, s1, s2, tcg_constant_i32(op));
198
+ TCGv_i64 fone = tcg_constant_i64(float64_one);
199
+ TCGv_i32 mone = tcg_constant_i32(-1);
200
+ TCGv_i32 op = tcg_constant_i32(float_muladd_negate_result);
201
+ gen_helper_fmaddd(d, tcg_env, fone, s1, s2, mone, op);
202
}
203
204
static void gen_op_fpexception_im(DisasContext *dc, int ftt)
36
--
205
--
37
2.34.1
206
2.43.0
38
207
39
208
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
All uses have been convered to float*_muladd_scalbn.
2
2
3
In order to make accel/tcg/ target agnostic,
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
introduce the need_replay_interrupt() handler.
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Anton Johansson <anjo@rev.ng>
9
Reviewed-by: Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
10
Message-Id: <20240124101639.30056-7-philmd@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
---
5
---
13
include/hw/core/tcg-cpu-ops.h | 5 +++++
6
include/fpu/softfloat.h | 3 ---
14
accel/tcg/cpu-exec.c | 8 +++++---
7
fpu/softfloat.c | 6 ------
15
2 files changed, 10 insertions(+), 3 deletions(-)
8
fpu/softfloat-parts.c.inc | 4 ----
9
3 files changed, 13 deletions(-)
16
10
17
diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
11
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
18
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/core/tcg-cpu-ops.h
13
--- a/include/fpu/softfloat.h
20
+++ b/include/hw/core/tcg-cpu-ops.h
14
+++ b/include/fpu/softfloat.h
21
@@ -XXX,XX +XXX,XX @@ struct TCGCPUOps {
15
@@ -XXX,XX +XXX,XX @@ bfloat16 bfloat16_squash_input_denormal(bfloat16 a, float_status *status);
22
*/
16
| Using these differs from negating an input or output before calling
23
bool (*io_recompile_replay_branch)(CPUState *cpu,
17
| the muladd function in that this means that a NaN doesn't have its
24
const TranslationBlock *tb);
18
| sign bit inverted before it is propagated.
25
+ /**
19
-| We also support halving the result before rounding, as a special
26
+ * @need_replay_interrupt: Return %true if @interrupt_request
20
-| case to support the ARM fused-sqrt-step instruction FRSQRTS.
27
+ * needs to be recorded for replay purposes.
21
*----------------------------------------------------------------------------*/
28
+ */
22
enum {
29
+ bool (*need_replay_interrupt)(int interrupt_request);
23
float_muladd_negate_c = 1,
30
#endif /* !CONFIG_USER_ONLY */
24
float_muladd_negate_product = 2,
31
#endif /* NEED_CPU_H */
25
float_muladd_negate_result = 4,
32
26
- float_muladd_halve_result = 8,
33
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
27
};
28
29
/*----------------------------------------------------------------------------
30
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
34
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
35
--- a/accel/tcg/cpu-exec.c
32
--- a/fpu/softfloat.c
36
+++ b/accel/tcg/cpu-exec.c
33
+++ b/fpu/softfloat.c
37
@@ -XXX,XX +XXX,XX @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
34
@@ -XXX,XX +XXX,XX @@ float32_muladd(float32 xa, float32 xb, float32 xc, int flags, float_status *s)
38
* "real" interrupt event later. It does not need to be recorded for
35
if (unlikely(!can_use_fpu(s))) {
39
* replay purposes.
36
goto soft;
40
*/
37
}
41
-static inline bool need_replay_interrupt(int interrupt_request)
38
- if (unlikely(flags & float_muladd_halve_result)) {
42
+static inline bool need_replay_interrupt(CPUState *cpu, int interrupt_request)
39
- goto soft;
43
{
40
- }
44
#if defined(TARGET_I386)
41
45
return !(interrupt_request & CPU_INTERRUPT_POLL);
42
float32_input_flush3(&ua.s, &ub.s, &uc.s, s);
46
#else
43
if (unlikely(!f32_is_zon3(ua, ub, uc))) {
47
- return true;
44
@@ -XXX,XX +XXX,XX @@ float64_muladd(float64 xa, float64 xb, float64 xc, int flags, float_status *s)
48
+ const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
45
if (unlikely(!can_use_fpu(s))) {
49
+ return !tcg_ops->need_replay_interrupt
46
goto soft;
50
+ || tcg_ops->need_replay_interrupt(interrupt_request);
47
}
51
#endif
48
- if (unlikely(flags & float_muladd_halve_result)) {
52
}
49
- goto soft;
53
#endif /* !CONFIG_USER_ONLY */
50
- }
54
@@ -XXX,XX +XXX,XX @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
51
55
52
float64_input_flush3(&ua.s, &ub.s, &uc.s, s);
56
if (tcg_ops->cpu_exec_interrupt &&
53
if (unlikely(!f64_is_zon3(ua, ub, uc))) {
57
tcg_ops->cpu_exec_interrupt(cpu, interrupt_request)) {
54
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
58
- if (need_replay_interrupt(interrupt_request)) {
55
index XXXXXXX..XXXXXXX 100644
59
+ if (need_replay_interrupt(cpu, interrupt_request)) {
56
--- a/fpu/softfloat-parts.c.inc
60
replay_interrupt();
57
+++ b/fpu/softfloat-parts.c.inc
61
}
58
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(muladd_scalbn)(FloatPartsN *a, FloatPartsN *b,
62
/*
59
a->exp = p_widen.exp;
60
61
return_normal:
62
- /* TODO: Replace all use of float_muladd_halve_result with scale. */
63
- if (flags & float_muladd_halve_result) {
64
- a->exp -= 1;
65
- }
66
a->exp += scale;
67
finish_sign:
68
if (flags & float_muladd_negate_result) {
63
--
69
--
64
2.34.1
70
2.43.0
65
71
66
72
diff view generated by jsdifflib
New patch
1
This rounding mode is used by Hexagon.
1
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
5
include/fpu/softfloat-types.h | 2 ++
6
fpu/softfloat-parts.c.inc | 3 +++
7
2 files changed, 5 insertions(+)
8
9
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
10
index XXXXXXX..XXXXXXX 100644
11
--- a/include/fpu/softfloat-types.h
12
+++ b/include/fpu/softfloat-types.h
13
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
14
float_round_to_odd = 5,
15
/* Not an IEEE rounding mode: round to closest odd, overflow to inf */
16
float_round_to_odd_inf = 6,
17
+ /* Not an IEEE rounding mode: round to nearest even, overflow to max */
18
+ float_round_nearest_even_max = 7,
19
} FloatRoundMode;
20
21
/*
22
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
23
index XXXXXXX..XXXXXXX 100644
24
--- a/fpu/softfloat-parts.c.inc
25
+++ b/fpu/softfloat-parts.c.inc
26
@@ -XXX,XX +XXX,XX @@ static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s,
27
int exp, flags = 0;
28
29
switch (s->float_rounding_mode) {
30
+ case float_round_nearest_even_max:
31
+ overflow_norm = true;
32
+ /* fall through */
33
case float_round_nearest_even:
34
if (N > 64 && frac_lsb == 0) {
35
inc = ((p->frac_hi & 1) || (p->frac_lo & round_mask) != frac_lsbm1
36
--
37
2.43.0
diff view generated by jsdifflib
New patch
1
Certain Hexagon instructions suppress changes to the result
2
when the product of fma() is a true zero.
1
3
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
include/fpu/softfloat.h | 5 +++++
7
fpu/softfloat.c | 3 +++
8
fpu/softfloat-parts.c.inc | 4 +++-
9
3 files changed, 11 insertions(+), 1 deletion(-)
10
11
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/include/fpu/softfloat.h
14
+++ b/include/fpu/softfloat.h
15
@@ -XXX,XX +XXX,XX @@ bfloat16 bfloat16_squash_input_denormal(bfloat16 a, float_status *status);
16
| Using these differs from negating an input or output before calling
17
| the muladd function in that this means that a NaN doesn't have its
18
| sign bit inverted before it is propagated.
19
+|
20
+| With float_muladd_suppress_add_product_zero, if A or B is zero
21
+| such that the product is a true zero, then return C without addition.
22
+| This preserves the sign of C when C is +/- 0. Used for Hexagon.
23
*----------------------------------------------------------------------------*/
24
enum {
25
float_muladd_negate_c = 1,
26
float_muladd_negate_product = 2,
27
float_muladd_negate_result = 4,
28
+ float_muladd_suppress_add_product_zero = 8,
29
};
30
31
/*----------------------------------------------------------------------------
32
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/fpu/softfloat.c
35
+++ b/fpu/softfloat.c
36
@@ -XXX,XX +XXX,XX @@ float32_muladd(float32 xa, float32 xb, float32 xc, int flags, float_status *s)
37
if (unlikely(!can_use_fpu(s))) {
38
goto soft;
39
}
40
+ if (unlikely(flags & float_muladd_suppress_add_product_zero)) {
41
+ goto soft;
42
+ }
43
44
float32_input_flush3(&ua.s, &ub.s, &uc.s, s);
45
if (unlikely(!f32_is_zon3(ua, ub, uc))) {
46
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
47
index XXXXXXX..XXXXXXX 100644
48
--- a/fpu/softfloat-parts.c.inc
49
+++ b/fpu/softfloat-parts.c.inc
50
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(muladd_scalbn)(FloatPartsN *a, FloatPartsN *b,
51
goto return_normal;
52
}
53
if (c->cls == float_class_zero) {
54
- if (a->sign != c->sign) {
55
+ if (flags & float_muladd_suppress_add_product_zero) {
56
+ a->sign = c->sign;
57
+ } else if (a->sign != c->sign) {
58
goto return_sub_zero;
59
}
60
goto return_zero;
61
--
62
2.43.0
diff view generated by jsdifflib
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
1
There are no special cases for this instruction.
2
Remove internal_mpyf as unused.
2
3
3
Currently qemu_target_page_mask() is usable only from the softmmu
4
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
4
code. Make it possible to use it from the *-user code as well.
5
6
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
7
Message-ID: <20231208003754.3688038-2-iii@linux.ibm.com>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-Id: <20240124075609.14756-2-philmd@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
[rth: Split out change to accel/tcg/perf.c]
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
---
6
---
14
system/physmem.c | 5 -----
7
target/hexagon/fma_emu.h | 1 -
15
target/target-common.c | 10 ++++++++++
8
target/hexagon/fma_emu.c | 8 --------
16
target/meson.build | 2 ++
9
target/hexagon/op_helper.c | 2 +-
17
3 files changed, 12 insertions(+), 5 deletions(-)
10
3 files changed, 1 insertion(+), 10 deletions(-)
18
create mode 100644 target/target-common.c
19
11
20
diff --git a/system/physmem.c b/system/physmem.c
12
diff --git a/target/hexagon/fma_emu.h b/target/hexagon/fma_emu.h
21
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
22
--- a/system/physmem.c
14
--- a/target/hexagon/fma_emu.h
23
+++ b/system/physmem.c
15
+++ b/target/hexagon/fma_emu.h
24
@@ -XXX,XX +XXX,XX @@ size_t qemu_target_page_size(void)
16
@@ -XXX,XX +XXX,XX @@ int32_t float32_getexp(float32 f32);
25
return TARGET_PAGE_SIZE;
17
float32 infinite_float32(uint8_t sign);
18
float32 internal_fmafx(float32 a, float32 b, float32 c,
19
int scale, float_status *fp_status);
20
-float32 internal_mpyf(float32 a, float32 b, float_status *fp_status);
21
float64 internal_mpyhh(float64 a, float64 b,
22
unsigned long long int accumulated,
23
float_status *fp_status);
24
diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/hexagon/fma_emu.c
27
+++ b/target/hexagon/fma_emu.c
28
@@ -XXX,XX +XXX,XX @@ float32 internal_fmafx(float32 a, float32 b, float32 c, int scale,
29
return accum_round_float32(result, fp_status);
26
}
30
}
27
31
28
-int qemu_target_page_mask(void)
32
-float32 internal_mpyf(float32 a, float32 b, float_status *fp_status)
29
-{
33
-{
30
- return TARGET_PAGE_MASK;
34
- if (float32_is_zero(a) || float32_is_zero(b)) {
35
- return float32_mul(a, b, fp_status);
36
- }
37
- return internal_fmafx(a, b, float32_zero, 0, fp_status);
31
-}
38
-}
32
-
39
-
33
int qemu_target_page_bits(void)
40
float64 internal_mpyhh(float64 a, float64 b,
41
unsigned long long int accumulated,
42
float_status *fp_status)
43
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/hexagon/op_helper.c
46
+++ b/target/hexagon/op_helper.c
47
@@ -XXX,XX +XXX,XX @@ float32 HELPER(sfmpy)(CPUHexagonState *env, float32 RsV, float32 RtV)
34
{
48
{
35
return TARGET_PAGE_BITS;
49
float32 RdV;
36
diff --git a/target/target-common.c b/target/target-common.c
50
arch_fpop_start(env);
37
new file mode 100644
51
- RdV = internal_mpyf(RsV, RtV, &env->fp_status);
38
index XXXXXXX..XXXXXXX
52
+ RdV = float32_mul(RsV, RtV, &env->fp_status);
39
--- /dev/null
53
arch_fpop_end(env);
40
+++ b/target/target-common.c
54
return RdV;
41
@@ -XXX,XX +XXX,XX @@
55
}
42
+/* SPDX-License-Identifier: GPL-2.0-or-later */
43
+#include "qemu/osdep.h"
44
+
45
+#include "cpu.h"
46
+#include "exec/target_page.h"
47
+
48
+int qemu_target_page_mask(void)
49
+{
50
+ return TARGET_PAGE_MASK;
51
+}
52
diff --git a/target/meson.build b/target/meson.build
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/meson.build
55
+++ b/target/meson.build
56
@@ -XXX,XX +XXX,XX @@ subdir('sh4')
57
subdir('sparc')
58
subdir('tricore')
59
subdir('xtensa')
60
+
61
+specific_ss.add(files('target-common.c'))
62
--
56
--
63
2.34.1
57
2.43.0
64
65
diff view generated by jsdifflib
1
There are no special cases for this instruction.
2
3
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
1
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
---
5
---
3
target/loongarch/cpu.c | 2 +-
6
target/hexagon/op_helper.c | 2 +-
4
1 file changed, 1 insertion(+), 1 deletion(-)
7
1 file changed, 1 insertion(+), 1 deletion(-)
5
8
6
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
9
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
7
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
8
--- a/target/loongarch/cpu.c
11
--- a/target/hexagon/op_helper.c
9
+++ b/target/loongarch/cpu.c
12
+++ b/target/hexagon/op_helper.c
10
@@ -XXX,XX +XXX,XX @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags)
13
@@ -XXX,XX +XXX,XX @@ float32 HELPER(sffma)(CPUHexagonState *env, float32 RxV,
11
#ifdef CONFIG_TCG
14
float32 RsV, float32 RtV)
12
#include "hw/core/tcg-cpu-ops.h"
15
{
13
16
arch_fpop_start(env);
14
-static TCGCPUOps loongarch_tcg_ops = {
17
- RxV = internal_fmafx(RsV, RtV, RxV, 0, &env->fp_status);
15
+static const TCGCPUOps loongarch_tcg_ops = {
18
+ RxV = float32_muladd(RsV, RtV, RxV, 0, &env->fp_status);
16
.initialize = loongarch_translate_init,
19
arch_fpop_end(env);
17
.synchronize_from_tb = loongarch_cpu_synchronize_from_tb,
20
return RxV;
18
.restore_state_to_opc = loongarch_restore_state_to_opc,
21
}
19
--
22
--
20
2.34.1
23
2.43.0
diff view generated by jsdifflib
1
From: Anton Johansson <anjo@rev.ng>
1
There are no special cases for this instruction. Since hexagon
2
always uses default-nan mode, explicitly negating the first
3
input is unnecessary. Use float_muladd_negate_product instead.
2
4
3
Always include fake_user_interrupt in user-only build, despite
5
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
4
only being used for i386. This will enable cpu-exec.c to be
5
compiled only once.
6
7
Signed-off-by: Anton Johansson <anjo@rev.ng>
8
Message-ID: <20240119144024.14289-18-anjo@rev.ng>
9
[rth: Split out of a larger patch; remove TARGET_I386 conditional.]
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
7
---
12
include/hw/core/tcg-cpu-ops.h | 5 ++---
8
target/hexagon/op_helper.c | 5 ++---
13
1 file changed, 2 insertions(+), 3 deletions(-)
9
1 file changed, 2 insertions(+), 3 deletions(-)
14
10
15
diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
11
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/core/tcg-cpu-ops.h
13
--- a/target/hexagon/op_helper.c
18
+++ b/include/hw/core/tcg-cpu-ops.h
14
+++ b/target/hexagon/op_helper.c
19
@@ -XXX,XX +XXX,XX @@ struct TCGCPUOps {
15
@@ -XXX,XX +XXX,XX @@ float32 HELPER(sffma_sc)(CPUHexagonState *env, float32 RxV,
20
void (*debug_excp_handler)(CPUState *cpu);
16
float32 HELPER(sffms)(CPUHexagonState *env, float32 RxV,
21
17
float32 RsV, float32 RtV)
22
#ifdef NEED_CPU_H
18
{
23
-#if defined(CONFIG_USER_ONLY) && defined(TARGET_I386)
19
- float32 neg_RsV;
24
+#ifdef CONFIG_USER_ONLY
20
arch_fpop_start(env);
25
/**
21
- neg_RsV = float32_set_sign(RsV, float32_is_neg(RsV) ? 0 : 1);
26
* @fake_user_interrupt: Callback for 'fake exception' handling.
22
- RxV = internal_fmafx(neg_RsV, RtV, RxV, 0, &env->fp_status);
27
*
23
+ RxV = float32_muladd(RsV, RtV, RxV, float_muladd_negate_product,
28
@@ -XXX,XX +XXX,XX @@ struct TCGCPUOps {
24
+ &env->fp_status);
29
* cpu execution loop (hack for x86 user mode).
25
arch_fpop_end(env);
30
*/
26
return RxV;
31
void (*fake_user_interrupt)(CPUState *cpu);
27
}
32
-#endif /* !CONFIG_USER_ONLY || !TARGET_I386 */
33
-#ifdef CONFIG_USER_ONLY
34
+
35
/**
36
* record_sigsegv:
37
* @cpu: cpu context
38
--
28
--
39
2.34.1
29
2.43.0
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
This instruction has a special case that 0 * x + c returns c
2
without the normal sign folding that comes with 0 + -0.
3
Use the new float_muladd_suppress_add_product_zero to
4
describe this.
2
5
3
tcg_ss[] source set contains target-specific units.
6
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
4
Rename it as 'tcg_specific_ss[]' for clarity.
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Anton Johansson <anjo@rev.ng>
9
Message-Id: <20240124101639.30056-2-philmd@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
8
---
12
accel/tcg/meson.build | 12 ++++++------
9
target/hexagon/op_helper.c | 11 +++--------
13
1 file changed, 6 insertions(+), 6 deletions(-)
10
1 file changed, 3 insertions(+), 8 deletions(-)
14
11
15
diff --git a/accel/tcg/meson.build b/accel/tcg/meson.build
12
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/accel/tcg/meson.build
14
--- a/target/hexagon/op_helper.c
18
+++ b/accel/tcg/meson.build
15
+++ b/target/hexagon/op_helper.c
19
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static float32 check_nan(float32 dst, float32 x, float_status *fp_status)
20
-tcg_ss = ss.source_set()
17
float32 HELPER(sffma_sc)(CPUHexagonState *env, float32 RxV,
21
common_ss.add(when: 'CONFIG_TCG', if_true: files(
18
float32 RsV, float32 RtV, float32 PuV)
22
'cpu-exec-common.c',
19
{
23
))
20
- size4s_t tmp;
24
-tcg_ss.add(files(
21
arch_fpop_start(env);
25
+tcg_specific_ss = ss.source_set()
22
- RxV = check_nan(RxV, RxV, &env->fp_status);
26
+tcg_specific_ss.add(files(
23
- RxV = check_nan(RxV, RsV, &env->fp_status);
27
'tcg-all.c',
24
- RxV = check_nan(RxV, RtV, &env->fp_status);
28
'cpu-exec.c',
25
- tmp = internal_fmafx(RsV, RtV, RxV, fSXTN(8, 64, PuV), &env->fp_status);
29
'tb-maint.c',
26
- if (!(float32_is_zero(RxV) && is_zero_prod(RsV, RtV))) {
30
@@ -XXX,XX +XXX,XX @@ tcg_ss.add(files(
27
- RxV = tmp;
31
'translate-all.c',
28
- }
32
'translator.c',
29
+ RxV = float32_muladd_scalbn(RsV, RtV, RxV, fSXTN(8, 64, PuV),
33
))
30
+ float_muladd_suppress_add_product_zero,
34
-tcg_ss.add(when: 'CONFIG_USER_ONLY', if_true: files('user-exec.c'))
31
+ &env->fp_status);
35
-tcg_ss.add(when: 'CONFIG_SYSTEM_ONLY', if_false: files('user-exec-stub.c'))
32
arch_fpop_end(env);
36
+tcg_specific_ss.add(when: 'CONFIG_USER_ONLY', if_true: files('user-exec.c'))
33
return RxV;
37
+tcg_specific_ss.add(when: 'CONFIG_SYSTEM_ONLY', if_false: files('user-exec-stub.c'))
34
}
38
if get_option('plugins')
39
- tcg_ss.add(files('plugin-gen.c'))
40
+ tcg_specific_ss.add(files('plugin-gen.c'))
41
endif
42
-specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_ss)
43
+specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_specific_ss)
44
45
specific_ss.add(when: ['CONFIG_SYSTEM_ONLY', 'CONFIG_TCG'], if_true: files(
46
'cputlb.c',
47
--
35
--
48
2.34.1
36
2.43.0
49
50
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
There are multiple special cases for this instruction.
2
(1) The saturate to normal maximum instead of overflow to infinity is
3
handled by the new float_round_nearest_even_max rounding mode.
4
(2) The 0 * n + c special case is handled by the new
5
float_muladd_suppress_add_product_zero flag.
6
(3) The Inf - Inf -> 0 special case can be detected after the fact
7
by examining float_flag_invalid_isi.
2
8
3
tcg_cpus_exec() operates on a single vCPU, rename it
9
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
4
as 'tcg_cpu_exec'.
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Anton Johansson <anjo@rev.ng>
9
Message-Id: <20240124101639.30056-4-philmd@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
11
---
12
accel/tcg/tcg-accel-ops.h | 2 +-
12
target/hexagon/op_helper.c | 105 +++++++++----------------------------
13
accel/tcg/tcg-accel-ops-mttcg.c | 2 +-
13
1 file changed, 26 insertions(+), 79 deletions(-)
14
accel/tcg/tcg-accel-ops-rr.c | 2 +-
15
accel/tcg/tcg-accel-ops.c | 2 +-
16
4 files changed, 4 insertions(+), 4 deletions(-)
17
14
18
diff --git a/accel/tcg/tcg-accel-ops.h b/accel/tcg/tcg-accel-ops.h
15
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/accel/tcg/tcg-accel-ops.h
17
--- a/target/hexagon/op_helper.c
21
+++ b/accel/tcg/tcg-accel-ops.h
18
+++ b/target/hexagon/op_helper.c
22
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ float32 HELPER(sffma)(CPUHexagonState *env, float32 RxV,
23
#include "sysemu/cpus.h"
20
return RxV;
24
25
void tcg_cpu_destroy(CPUState *cpu);
26
-int tcg_cpus_exec(CPUState *cpu);
27
+int tcg_cpu_exec(CPUState *cpu);
28
void tcg_handle_interrupt(CPUState *cpu, int mask);
29
void tcg_cpu_init_cflags(CPUState *cpu, bool parallel);
30
31
diff --git a/accel/tcg/tcg-accel-ops-mttcg.c b/accel/tcg/tcg-accel-ops-mttcg.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/accel/tcg/tcg-accel-ops-mttcg.c
34
+++ b/accel/tcg/tcg-accel-ops-mttcg.c
35
@@ -XXX,XX +XXX,XX @@ static void *mttcg_cpu_thread_fn(void *arg)
36
if (cpu_can_run(cpu)) {
37
int r;
38
bql_unlock();
39
- r = tcg_cpus_exec(cpu);
40
+ r = tcg_cpu_exec(cpu);
41
bql_lock();
42
switch (r) {
43
case EXCP_DEBUG:
44
diff --git a/accel/tcg/tcg-accel-ops-rr.c b/accel/tcg/tcg-accel-ops-rr.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/accel/tcg/tcg-accel-ops-rr.c
47
+++ b/accel/tcg/tcg-accel-ops-rr.c
48
@@ -XXX,XX +XXX,XX @@ static void *rr_cpu_thread_fn(void *arg)
49
if (icount_enabled()) {
50
icount_prepare_for_run(cpu, cpu_budget);
51
}
52
- r = tcg_cpus_exec(cpu);
53
+ r = tcg_cpu_exec(cpu);
54
if (icount_enabled()) {
55
icount_process_data(cpu);
56
}
57
diff --git a/accel/tcg/tcg-accel-ops.c b/accel/tcg/tcg-accel-ops.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/accel/tcg/tcg-accel-ops.c
60
+++ b/accel/tcg/tcg-accel-ops.c
61
@@ -XXX,XX +XXX,XX @@ void tcg_cpu_destroy(CPUState *cpu)
62
cpu_thread_signal_destroyed(cpu);
63
}
21
}
64
22
65
-int tcg_cpus_exec(CPUState *cpu)
23
-static bool is_zero_prod(float32 a, float32 b)
66
+int tcg_cpu_exec(CPUState *cpu)
24
-{
25
- return ((float32_is_zero(a) && is_finite(b)) ||
26
- (float32_is_zero(b) && is_finite(a)));
27
-}
28
-
29
-static float32 check_nan(float32 dst, float32 x, float_status *fp_status)
30
-{
31
- float32 ret = dst;
32
- if (float32_is_any_nan(x)) {
33
- if (extract32(x, 22, 1) == 0) {
34
- float_raise(float_flag_invalid, fp_status);
35
- }
36
- ret = make_float32(0xffffffff); /* nan */
37
- }
38
- return ret;
39
-}
40
-
41
float32 HELPER(sffma_sc)(CPUHexagonState *env, float32 RxV,
42
float32 RsV, float32 RtV, float32 PuV)
67
{
43
{
68
int ret;
44
@@ -XXX,XX +XXX,XX @@ float32 HELPER(sffms)(CPUHexagonState *env, float32 RxV,
69
assert(tcg_enabled());
45
return RxV;
46
}
47
48
-static bool is_inf_prod(int32_t a, int32_t b)
49
+static float32 do_sffma_lib(CPUHexagonState *env, float32 RxV,
50
+ float32 RsV, float32 RtV, int negate)
51
{
52
- return (float32_is_infinity(a) && float32_is_infinity(b)) ||
53
- (float32_is_infinity(a) && is_finite(b) && !float32_is_zero(b)) ||
54
- (float32_is_infinity(b) && is_finite(a) && !float32_is_zero(a));
55
+ int flags;
56
+
57
+ arch_fpop_start(env);
58
+
59
+ set_float_rounding_mode(float_round_nearest_even_max, &env->fp_status);
60
+ RxV = float32_muladd(RsV, RtV, RxV,
61
+ negate | float_muladd_suppress_add_product_zero,
62
+ &env->fp_status);
63
+
64
+ flags = get_float_exception_flags(&env->fp_status);
65
+ if (flags) {
66
+ /* Flags are suppressed by this instruction. */
67
+ set_float_exception_flags(0, &env->fp_status);
68
+
69
+ /* Return 0 for Inf - Inf. */
70
+ if (flags & float_flag_invalid_isi) {
71
+ RxV = 0;
72
+ }
73
+ }
74
+
75
+ arch_fpop_end(env);
76
+ return RxV;
77
}
78
79
float32 HELPER(sffma_lib)(CPUHexagonState *env, float32 RxV,
80
float32 RsV, float32 RtV)
81
{
82
- bool infinp;
83
- bool infminusinf;
84
- float32 tmp;
85
-
86
- arch_fpop_start(env);
87
- set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
88
- infminusinf = float32_is_infinity(RxV) &&
89
- is_inf_prod(RsV, RtV) &&
90
- (fGETBIT(31, RsV ^ RxV ^ RtV) != 0);
91
- infinp = float32_is_infinity(RxV) ||
92
- float32_is_infinity(RtV) ||
93
- float32_is_infinity(RsV);
94
- RxV = check_nan(RxV, RxV, &env->fp_status);
95
- RxV = check_nan(RxV, RsV, &env->fp_status);
96
- RxV = check_nan(RxV, RtV, &env->fp_status);
97
- tmp = internal_fmafx(RsV, RtV, RxV, 0, &env->fp_status);
98
- if (!(float32_is_zero(RxV) && is_zero_prod(RsV, RtV))) {
99
- RxV = tmp;
100
- }
101
- set_float_exception_flags(0, &env->fp_status);
102
- if (float32_is_infinity(RxV) && !infinp) {
103
- RxV = RxV - 1;
104
- }
105
- if (infminusinf) {
106
- RxV = 0;
107
- }
108
- arch_fpop_end(env);
109
- return RxV;
110
+ return do_sffma_lib(env, RxV, RsV, RtV, 0);
111
}
112
113
float32 HELPER(sffms_lib)(CPUHexagonState *env, float32 RxV,
114
float32 RsV, float32 RtV)
115
{
116
- bool infinp;
117
- bool infminusinf;
118
- float32 tmp;
119
-
120
- arch_fpop_start(env);
121
- set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
122
- infminusinf = float32_is_infinity(RxV) &&
123
- is_inf_prod(RsV, RtV) &&
124
- (fGETBIT(31, RsV ^ RxV ^ RtV) == 0);
125
- infinp = float32_is_infinity(RxV) ||
126
- float32_is_infinity(RtV) ||
127
- float32_is_infinity(RsV);
128
- RxV = check_nan(RxV, RxV, &env->fp_status);
129
- RxV = check_nan(RxV, RsV, &env->fp_status);
130
- RxV = check_nan(RxV, RtV, &env->fp_status);
131
- float32 minus_RsV = float32_sub(float32_zero, RsV, &env->fp_status);
132
- tmp = internal_fmafx(minus_RsV, RtV, RxV, 0, &env->fp_status);
133
- if (!(float32_is_zero(RxV) && is_zero_prod(RsV, RtV))) {
134
- RxV = tmp;
135
- }
136
- set_float_exception_flags(0, &env->fp_status);
137
- if (float32_is_infinity(RxV) && !infinp) {
138
- RxV = RxV - 1;
139
- }
140
- if (infminusinf) {
141
- RxV = 0;
142
- }
143
- arch_fpop_end(env);
144
- return RxV;
145
+ return do_sffma_lib(env, RxV, RsV, RtV, float_muladd_negate_product);
146
}
147
148
float64 HELPER(dfmpyfix)(CPUHexagonState *env, float64 RssV, float64 RttV)
70
--
149
--
71
2.34.1
150
2.43.0
72
73
diff view generated by jsdifflib
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
1
The function is now unused.
2
2
3
Both the report() function as well as the initial gdbstub test sequence
3
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
4
are copy-pasted into ~10 files with slight modifications. This
5
indicates that they are indeed generic, so factor them out. While
6
at it, add a few newlines to make the formatting closer to PEP-8.
7
8
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
9
Message-Id: <20240129093410.3151-3-iii@linux.ibm.com>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
5
---
12
tests/guest-debug/run-test.py | 7 ++-
6
target/hexagon/fma_emu.h | 2 -
13
tests/guest-debug/test_gdbstub.py | 60 +++++++++++++++++++
7
target/hexagon/fma_emu.c | 171 ---------------------------------------
14
tests/tcg/aarch64/gdbstub/test-sve-ioctl.py | 34 +----------
8
2 files changed, 173 deletions(-)
15
tests/tcg/aarch64/gdbstub/test-sve.py | 33 +---------
16
tests/tcg/multiarch/gdbstub/interrupt.py | 47 ++-------------
17
tests/tcg/multiarch/gdbstub/memory.py | 39 +-----------
18
tests/tcg/multiarch/gdbstub/registers.py | 41 ++-----------
19
tests/tcg/multiarch/gdbstub/sha1.py | 38 ++----------
20
.../multiarch/gdbstub/test-proc-mappings.py | 39 +-----------
21
.../multiarch/gdbstub/test-qxfer-auxv-read.py | 37 +-----------
22
.../gdbstub/test-thread-breakpoint.py | 37 +-----------
23
tests/tcg/s390x/gdbstub/test-signals-s390x.py | 42 +------------
24
tests/tcg/s390x/gdbstub/test-svc.py | 39 +-----------
25
13 files changed, 98 insertions(+), 395 deletions(-)
26
create mode 100644 tests/guest-debug/test_gdbstub.py
27
9
28
diff --git a/tests/guest-debug/run-test.py b/tests/guest-debug/run-test.py
10
diff --git a/target/hexagon/fma_emu.h b/target/hexagon/fma_emu.h
29
index XXXXXXX..XXXXXXX 100755
30
--- a/tests/guest-debug/run-test.py
31
+++ b/tests/guest-debug/run-test.py
32
@@ -XXX,XX +XXX,XX @@ def log(output, msg):
33
sleep(1)
34
log(output, "GDB CMD: %s" % (gdb_cmd))
35
36
- result = subprocess.call(gdb_cmd, shell=True, stdout=output, stderr=stderr)
37
+ gdb_env = dict(os.environ)
38
+ gdb_pythonpath = gdb_env.get("PYTHONPATH", "").split(os.pathsep)
39
+ gdb_pythonpath.append(os.path.dirname(os.path.realpath(__file__)))
40
+ gdb_env["PYTHONPATH"] = os.pathsep.join(gdb_pythonpath)
41
+ result = subprocess.call(gdb_cmd, shell=True, stdout=output, stderr=stderr,
42
+ env=gdb_env)
43
44
# A result of greater than 128 indicates a fatal signal (likely a
45
# crash due to gdb internal failure). That's a problem for GDB and
46
diff --git a/tests/guest-debug/test_gdbstub.py b/tests/guest-debug/test_gdbstub.py
47
new file mode 100644
48
index XXXXXXX..XXXXXXX
49
--- /dev/null
50
+++ b/tests/guest-debug/test_gdbstub.py
51
@@ -XXX,XX +XXX,XX @@
52
+"""Helper functions for gdbstub testing
53
+
54
+"""
55
+from __future__ import print_function
56
+import gdb
57
+import os
58
+import sys
59
+import traceback
60
+
61
+fail_count = 0
62
+
63
+
64
+def report(cond, msg):
65
+ """Report success/fail of a test"""
66
+ if cond:
67
+ print("PASS: {}".format(msg))
68
+ else:
69
+ print("FAIL: {}".format(msg))
70
+ global fail_count
71
+ fail_count += 1
72
+
73
+
74
+def main(test, expected_arch=None):
75
+ """Run a test function
76
+
77
+ This runs as the script it sourced (via -x, via run-test.py)."""
78
+ try:
79
+ inferior = gdb.selected_inferior()
80
+ arch = inferior.architecture()
81
+ print("ATTACHED: {}".format(arch.name()))
82
+ if expected_arch is not None:
83
+ report(arch.name() == expected_arch,
84
+ "connected to {}".format(expected_arch))
85
+ except (gdb.error, AttributeError):
86
+ print("SKIP: not connected")
87
+ exit(0)
88
+
89
+ if gdb.parse_and_eval("$pc") == 0:
90
+ print("SKIP: PC not set")
91
+ exit(0)
92
+
93
+ try:
94
+ test()
95
+ except:
96
+ print("GDB Exception:")
97
+ traceback.print_exc(file=sys.stdout)
98
+ global fail_count
99
+ fail_count += 1
100
+ if "QEMU_TEST_INTERACTIVE" in os.environ:
101
+ import code
102
+ code.InteractiveConsole(locals=globals()).interact()
103
+ raise
104
+
105
+ try:
106
+ gdb.execute("kill")
107
+ except gdb.error:
108
+ pass
109
+
110
+ print("All tests complete: {} failures".format(fail_count))
111
+ exit(fail_count)
112
diff --git a/tests/tcg/aarch64/gdbstub/test-sve-ioctl.py b/tests/tcg/aarch64/gdbstub/test-sve-ioctl.py
113
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
114
--- a/tests/tcg/aarch64/gdbstub/test-sve-ioctl.py
12
--- a/target/hexagon/fma_emu.h
115
+++ b/tests/tcg/aarch64/gdbstub/test-sve-ioctl.py
13
+++ b/target/hexagon/fma_emu.h
116
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static inline uint32_t float32_getexp_raw(float32 f32)
117
#
15
}
118
16
int32_t float32_getexp(float32 f32);
119
import gdb
17
float32 infinite_float32(uint8_t sign);
120
-import sys
18
-float32 internal_fmafx(float32 a, float32 b, float32 c,
121
+from test_gdbstub import main, report
19
- int scale, float_status *fp_status);
122
20
float64 internal_mpyhh(float64 a, float64 b,
123
initial_vlen = 0
21
unsigned long long int accumulated,
124
-failcount = 0
22
float_status *fp_status);
125
23
diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c
126
-def report(cond, msg):
127
- "Report success/fail of test"
128
- if cond:
129
- print ("PASS: %s" % (msg))
130
- else:
131
- print ("FAIL: %s" % (msg))
132
- global failcount
133
- failcount += 1
134
135
class TestBreakpoint(gdb.Breakpoint):
136
def __init__(self, sym_name="__sve_ld_done"):
137
@@ -XXX,XX +XXX,XX @@ def run_test():
138
139
gdb.execute("c")
140
141
-#
142
-# This runs as the script it sourced (via -x, via run-test.py)
143
-#
144
-try:
145
- inferior = gdb.selected_inferior()
146
- arch = inferior.architecture()
147
- report(arch.name() == "aarch64", "connected to aarch64")
148
-except (gdb.error, AttributeError):
149
- print("SKIPPING (not connected)", file=sys.stderr)
150
- exit(0)
151
152
-try:
153
- # Run the actual tests
154
- run_test()
155
-except:
156
- print ("GDB Exception: %s" % (sys.exc_info()[0]))
157
- failcount += 1
158
- import code
159
- code.InteractiveConsole(locals=globals()).interact()
160
- raise
161
-
162
-print("All tests complete: %d failures" % failcount)
163
-exit(failcount)
164
+main(run_test, expected_arch="aarch64")
165
diff --git a/tests/tcg/aarch64/gdbstub/test-sve.py b/tests/tcg/aarch64/gdbstub/test-sve.py
166
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
167
--- a/tests/tcg/aarch64/gdbstub/test-sve.py
25
--- a/target/hexagon/fma_emu.c
168
+++ b/tests/tcg/aarch64/gdbstub/test-sve.py
26
+++ b/target/hexagon/fma_emu.c
169
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@ int32_t float64_getexp(float64 f64)
170
#
28
return -1;
171
29
}
172
import gdb
30
173
-import sys
31
-static uint64_t float32_getmant(float32 f32)
174
+from test_gdbstub import main, report
32
-{
175
33
- Float a = { .i = f32 };
176
MAGIC = 0xDEADBEEF
34
- if (float32_is_normal(f32)) {
177
35
- return a.mant | 1ULL << 23;
178
-failcount = 0
36
- }
179
-
37
- if (float32_is_zero(f32)) {
180
-def report(cond, msg):
38
- return 0;
181
- "Report success/fail of test"
39
- }
182
- if cond:
40
- if (float32_is_denormal(f32)) {
183
- print ("PASS: %s" % (msg))
41
- return a.mant;
184
- else:
42
- }
185
- print ("FAIL: %s" % (msg))
43
- return ~0ULL;
186
- global failcount
44
-}
187
- failcount += 1
45
-
188
46
int32_t float32_getexp(float32 f32)
189
def run_test():
47
{
190
"Run through the tests one by one"
48
Float a = { .i = f32 };
191
@@ -XXX,XX +XXX,XX @@ def run_test():
49
@@ -XXX,XX +XXX,XX @@ float32 infinite_float32(uint8_t sign)
192
report(str(v.type) == "uint64_t", "size of %s" % (reg))
50
}
193
report(int(v) == MAGIC, "%s is 0x%x" % (reg, MAGIC))
51
194
52
/* Return a maximum finite value with the requested sign */
195
-#
53
-static float32 maxfinite_float32(uint8_t sign)
196
-# This runs as the script it sourced (via -x, via run-test.py)
54
-{
197
-#
55
- if (sign) {
198
-try:
56
- return make_float32(SF_MINUS_MAXF);
199
- inferior = gdb.selected_inferior()
57
- } else {
200
- arch = inferior.architecture()
58
- return make_float32(SF_MAXF);
201
- report(arch.name() == "aarch64", "connected to aarch64")
59
- }
202
-except (gdb.error, AttributeError):
60
-}
203
- print("SKIPPING (not connected)", file=sys.stderr)
61
-
204
- exit(0)
62
-/* Return a zero value with requested sign */
205
63
-static float32 zero_float32(uint8_t sign)
206
-try:
64
-{
207
- # Run the actual tests
65
- if (sign) {
208
- run_test()
66
- return make_float32(0x80000000);
209
-except:
67
- } else {
210
- print ("GDB Exception: %s" % (sys.exc_info()[0]))
68
- return float32_zero;
211
- failcount += 1
69
- }
212
-
70
-}
213
-print("All tests complete: %d failures" % failcount)
71
-
214
-
72
#define GEN_XF_ROUND(SUFFIX, MANTBITS, INF_EXP, INTERNAL_TYPE) \
215
-exit(failcount)
73
static SUFFIX accum_round_##SUFFIX(Accum a, float_status * fp_status) \
216
+main(run_test, expected_arch="aarch64")
74
{ \
217
diff --git a/tests/tcg/multiarch/gdbstub/interrupt.py b/tests/tcg/multiarch/gdbstub/interrupt.py
75
@@ -XXX,XX +XXX,XX @@ static SUFFIX accum_round_##SUFFIX(Accum a, float_status * fp_status) \
218
index XXXXXXX..XXXXXXX 100644
76
}
219
--- a/tests/tcg/multiarch/gdbstub/interrupt.py
77
220
+++ b/tests/tcg/multiarch/gdbstub/interrupt.py
78
GEN_XF_ROUND(float64, DF_MANTBITS, DF_INF_EXP, Double)
221
@@ -XXX,XX +XXX,XX @@
79
-GEN_XF_ROUND(float32, SF_MANTBITS, SF_INF_EXP, Float)
222
#
80
-
223
81
-static bool is_inf_prod(float64 a, float64 b)
224
import gdb
82
-{
225
-import sys
83
- return ((float64_is_infinity(a) && float64_is_infinity(b)) ||
226
-
84
- (float64_is_infinity(a) && is_finite(b) && (!float64_is_zero(b))) ||
227
-failcount = 0
85
- (float64_is_infinity(b) && is_finite(a) && (!float64_is_zero(a))));
228
-
86
-}
229
-
87
-
230
-def report(cond, msg):
88
-static float64 special_fma(float64 a, float64 b, float64 c,
231
- "Report success/fail of test"
89
- float_status *fp_status)
232
- if cond:
90
-{
233
- print("PASS: %s" % (msg))
91
- float64 ret = make_float64(0);
234
- else:
92
-
235
- print("FAIL: %s" % (msg))
93
- /*
236
- global failcount
94
- * If A multiplied by B is an exact infinity and C is also an infinity
237
- failcount += 1
95
- * but with the opposite sign, FMA returns NaN and raises invalid.
238
+from test_gdbstub import main, report
96
- */
239
97
- uint8_t a_sign = float64_is_neg(a);
240
98
- uint8_t b_sign = float64_is_neg(b);
241
def check_interrupt(thread):
99
- uint8_t c_sign = float64_is_neg(c);
242
@@ -XXX,XX +XXX,XX @@ def run_test():
100
- if (is_inf_prod(a, b) && float64_is_infinity(c)) {
243
Test if interrupting the code always lands us on the same thread when
101
- if ((a_sign ^ b_sign) != c_sign) {
244
running with scheduler-lock enabled.
102
- ret = make_float64(DF_NAN);
245
"""
103
- float_raise(float_flag_invalid, fp_status);
246
+ if len(gdb.selected_inferior().threads()) == 1:
104
- return ret;
247
+ print("SKIP: set to run on a single thread")
105
- }
248
+ exit(0)
106
- }
249
107
- if ((float64_is_infinity(a) && float64_is_zero(b)) ||
250
gdb.execute("set scheduler-locking on")
108
- (float64_is_zero(a) && float64_is_infinity(b))) {
251
for thread in gdb.selected_inferior().threads():
109
- ret = make_float64(DF_NAN);
252
@@ -XXX,XX +XXX,XX @@ def run_test():
110
- float_raise(float_flag_invalid, fp_status);
253
"thread %d resumes correctly on interrupt" % thread.num)
111
- return ret;
254
112
- }
255
113
- /*
256
-#
114
- * If none of the above checks are true and C is a NaN,
257
-# This runs as the script it sourced (via -x, via run-test.py)
115
- * a NaN shall be returned
258
-#
116
- * If A or B are NaN, a NAN shall be returned.
259
-try:
117
- */
260
- inferior = gdb.selected_inferior()
118
- if (float64_is_any_nan(a) ||
261
- arch = inferior.architecture()
119
- float64_is_any_nan(b) ||
262
- print("ATTACHED: %s" % arch.name())
120
- float64_is_any_nan(c)) {
263
-except (gdb.error, AttributeError):
121
- if (float64_is_any_nan(a) && (fGETBIT(51, a) == 0)) {
264
- print("SKIPPING (not connected)", file=sys.stderr)
122
- float_raise(float_flag_invalid, fp_status);
265
- exit(0)
123
- }
266
-
124
- if (float64_is_any_nan(b) && (fGETBIT(51, b) == 0)) {
267
-if gdb.parse_and_eval('$pc') == 0:
125
- float_raise(float_flag_invalid, fp_status);
268
- print("SKIP: PC not set")
126
- }
269
- exit(0)
127
- if (float64_is_any_nan(c) && (fGETBIT(51, c) == 0)) {
270
-if len(gdb.selected_inferior().threads()) == 1:
128
- float_raise(float_flag_invalid, fp_status);
271
- print("SKIP: set to run on a single thread")
129
- }
272
- exit(0)
130
- ret = make_float64(DF_NAN);
273
-
131
- return ret;
274
-try:
132
- }
275
- # Run the actual tests
133
- /*
276
- run_test()
134
- * We have checked for adding opposite-signed infinities.
277
-except (gdb.error):
135
- * Other infinities return infinity with the correct sign
278
- print("GDB Exception: %s" % (sys.exc_info()[0]))
136
- */
279
- failcount += 1
137
- if (float64_is_infinity(c)) {
280
- pass
138
- ret = infinite_float64(c_sign);
281
-
139
- return ret;
282
-# Finally kill the inferior and exit gdb with a count of failures
140
- }
283
-gdb.execute("kill")
141
- if (float64_is_infinity(a) || float64_is_infinity(b)) {
284
-exit(failcount)
142
- ret = infinite_float64(a_sign ^ b_sign);
285
+main(run_test)
143
- return ret;
286
diff --git a/tests/tcg/multiarch/gdbstub/memory.py b/tests/tcg/multiarch/gdbstub/memory.py
144
- }
287
index XXXXXXX..XXXXXXX 100644
145
- g_assert_not_reached();
288
--- a/tests/tcg/multiarch/gdbstub/memory.py
146
-}
289
+++ b/tests/tcg/multiarch/gdbstub/memory.py
147
-
290
@@ -XXX,XX +XXX,XX @@
148
-static float32 special_fmaf(float32 a, float32 b, float32 c,
291
149
- float_status *fp_status)
292
import gdb
150
-{
293
import sys
151
- float64 aa, bb, cc;
294
-
152
- aa = float32_to_float64(a, fp_status);
295
-failcount = 0
153
- bb = float32_to_float64(b, fp_status);
296
-
154
- cc = float32_to_float64(c, fp_status);
297
-
155
- return float64_to_float32(special_fma(aa, bb, cc, fp_status), fp_status);
298
-def report(cond, msg):
156
-}
299
- "Report success/fail of test"
157
-
300
- if cond:
158
-float32 internal_fmafx(float32 a, float32 b, float32 c, int scale,
301
- print("PASS: %s" % (msg))
159
- float_status *fp_status)
302
- else:
160
-{
303
- print("FAIL: %s" % (msg))
161
- Accum prod;
304
- global failcount
162
- Accum acc;
305
- failcount += 1
163
- Accum result;
306
+from test_gdbstub import main, report
164
- accum_init(&prod);
307
165
- accum_init(&acc);
308
166
- accum_init(&result);
309
def check_step():
167
-
310
@@ -XXX,XX +XXX,XX @@ def run_test():
168
- uint8_t a_sign = float32_is_neg(a);
311
169
- uint8_t b_sign = float32_is_neg(b);
312
report(cbp.hit_count == 0, "didn't reach backstop")
170
- uint8_t c_sign = float32_is_neg(c);
313
171
- if (float32_is_infinity(a) ||
314
-#
172
- float32_is_infinity(b) ||
315
-# This runs as the script it sourced (via -x, via run-test.py)
173
- float32_is_infinity(c)) {
316
-#
174
- return special_fmaf(a, b, c, fp_status);
317
-try:
175
- }
318
- inferior = gdb.selected_inferior()
176
- if (float32_is_any_nan(a) ||
319
- arch = inferior.architecture()
177
- float32_is_any_nan(b) ||
320
- print("ATTACHED: %s" % arch.name())
178
- float32_is_any_nan(c)) {
321
-except (gdb.error, AttributeError):
179
- return special_fmaf(a, b, c, fp_status);
322
- print("SKIPPING (not connected)", file=sys.stderr)
180
- }
323
- exit(0)
181
- if ((scale == 0) && (float32_is_zero(a) || float32_is_zero(b))) {
324
182
- float32 tmp = float32_mul(a, b, fp_status);
325
-if gdb.parse_and_eval('$pc') == 0:
183
- tmp = float32_add(tmp, c, fp_status);
326
- print("SKIP: PC not set")
184
- return tmp;
327
- exit(0)
185
- }
328
-
186
-
329
-try:
187
- /* (a * 2**b) * (c * 2**d) == a*c * 2**(b+d) */
330
- # Run the actual tests
188
- prod.mant = int128_mul_6464(float32_getmant(a), float32_getmant(b));
331
- run_test()
189
-
332
-except (gdb.error):
190
- /*
333
- print("GDB Exception: %s" % (sys.exc_info()[0]))
191
- * Note: extracting the mantissa into an int is multiplying by
334
- failcount += 1
192
- * 2**23, so adjust here
335
- pass
193
- */
336
-
194
- prod.exp = float32_getexp(a) + float32_getexp(b) - SF_BIAS - 23;
337
-# Finally kill the inferior and exit gdb with a count of failures
195
- prod.sign = a_sign ^ b_sign;
338
-gdb.execute("kill")
196
- if (float32_is_zero(a) || float32_is_zero(b)) {
339
-exit(failcount)
197
- prod.exp = -2 * WAY_BIG_EXP;
340
+main(run_test)
198
- }
341
diff --git a/tests/tcg/multiarch/gdbstub/registers.py b/tests/tcg/multiarch/gdbstub/registers.py
199
- if ((scale > 0) && float32_is_denormal(c)) {
342
index XXXXXXX..XXXXXXX 100644
200
- acc.mant = int128_mul_6464(0, 0);
343
--- a/tests/tcg/multiarch/gdbstub/registers.py
201
- acc.exp = -WAY_BIG_EXP;
344
+++ b/tests/tcg/multiarch/gdbstub/registers.py
202
- acc.sign = c_sign;
345
@@ -XXX,XX +XXX,XX @@
203
- acc.sticky = 1;
346
# SPDX-License-Identifier: GPL-2.0-or-later
204
- result = accum_add(prod, acc);
347
205
- } else if (!float32_is_zero(c)) {
348
import gdb
206
- acc.mant = int128_mul_6464(float32_getmant(c), 1);
349
-import sys
207
- acc.exp = float32_getexp(c);
350
import xml.etree.ElementTree as ET
208
- acc.sign = c_sign;
351
+from test_gdbstub import main, report
209
- result = accum_add(prod, acc);
352
+
210
- } else {
353
211
- result = prod;
354
initial_vlen = 0
212
- }
355
-failcount = 0
213
- result.exp += scale;
356
-
214
- return accum_round_float32(result, fp_status);
357
-def report(cond, msg):
215
-}
358
- "Report success/fail of test."
216
359
- if cond:
217
float64 internal_mpyhh(float64 a, float64 b,
360
- print("PASS: %s" % (msg))
218
unsigned long long int accumulated,
361
- else:
362
- print("FAIL: %s" % (msg))
363
- global failcount
364
- failcount += 1
365
366
367
def fetch_xml_regmap():
368
@@ -XXX,XX +XXX,XX @@ def fetch_xml_regmap():
369
370
return reg_map
371
372
+
373
def get_register_by_regnum(reg_map, regnum):
374
"""
375
Helper to find a register from the map via its XML regnum
376
@@ -XXX,XX +XXX,XX @@ def get_register_by_regnum(reg_map, regnum):
377
return entry
378
return None
379
380
+
381
def crosscheck_remote_xml(reg_map):
382
"""
383
Cross-check the list of remote-registers with the XML info.
384
@@ -XXX,XX +XXX,XX @@ def crosscheck_remote_xml(reg_map):
385
elif "seen" not in x_reg:
386
print(f"{x_reg} wasn't seen in remote-registers")
387
388
+
389
def initial_register_read(reg_map):
390
"""
391
Do an initial read of all registers that we know gdb cares about
392
@@ -XXX,XX +XXX,XX @@ def run_test():
393
complete_and_diff(reg_map)
394
395
396
-#
397
-# This runs as the script it sourced (via -x, via run-test.py)
398
-#
399
-try:
400
- inferior = gdb.selected_inferior()
401
- arch = inferior.architecture()
402
- print("ATTACHED: %s" % arch.name())
403
-except (gdb.error, AttributeError):
404
- print("SKIPPING (not connected)", file=sys.stderr)
405
- exit(0)
406
-
407
-if gdb.parse_and_eval('$pc') == 0:
408
- print("SKIP: PC not set")
409
- exit(0)
410
-
411
-try:
412
- run_test()
413
-except (gdb.error):
414
- print ("GDB Exception: %s" % (sys.exc_info()[0]))
415
- failcount += 1
416
- pass
417
-
418
-print("All tests complete: %d failures" % failcount)
419
-exit(failcount)
420
+main(run_test)
421
diff --git a/tests/tcg/multiarch/gdbstub/sha1.py b/tests/tcg/multiarch/gdbstub/sha1.py
422
index XXXXXXX..XXXXXXX 100644
423
--- a/tests/tcg/multiarch/gdbstub/sha1.py
424
+++ b/tests/tcg/multiarch/gdbstub/sha1.py
425
@@ -XXX,XX +XXX,XX @@
426
#
427
428
import gdb
429
-import sys
430
+from test_gdbstub import main, report
431
+
432
433
initial_vlen = 0
434
-failcount = 0
435
436
-def report(cond, msg):
437
- "Report success/fail of test"
438
- if cond:
439
- print("PASS: %s" % (msg))
440
- else:
441
- print("FAIL: %s" % (msg))
442
- global failcount
443
- failcount += 1
444
445
def check_break(sym_name):
446
"Setup breakpoint, continue and check we stopped."
447
@@ -XXX,XX +XXX,XX @@ def check_break(sym_name):
448
449
bp.delete()
450
451
+
452
def run_test():
453
"Run through the tests one by one"
454
455
@@ -XXX,XX +XXX,XX @@ def run_test():
456
# finally check we don't barf inspecting registers
457
gdb.execute("info registers")
458
459
-#
460
-# This runs as the script it sourced (via -x, via run-test.py)
461
-#
462
-try:
463
- inferior = gdb.selected_inferior()
464
- arch = inferior.architecture()
465
- print("ATTACHED: %s" % arch.name())
466
-except (gdb.error, AttributeError):
467
- print("SKIPPING (not connected)", file=sys.stderr)
468
- exit(0)
469
470
-if gdb.parse_and_eval('$pc') == 0:
471
- print("SKIP: PC not set")
472
- exit(0)
473
-
474
-try:
475
- # Run the actual tests
476
- run_test()
477
-except (gdb.error):
478
- print ("GDB Exception: %s" % (sys.exc_info()[0]))
479
- failcount += 1
480
- pass
481
-
482
-print("All tests complete: %d failures" % failcount)
483
-exit(failcount)
484
+main(run_test)
485
diff --git a/tests/tcg/multiarch/gdbstub/test-proc-mappings.py b/tests/tcg/multiarch/gdbstub/test-proc-mappings.py
486
index XXXXXXX..XXXXXXX 100644
487
--- a/tests/tcg/multiarch/gdbstub/test-proc-mappings.py
488
+++ b/tests/tcg/multiarch/gdbstub/test-proc-mappings.py
489
@@ -XXX,XX +XXX,XX @@
490
This runs as a sourced script (via -x, via run-test.py)."""
491
from __future__ import print_function
492
import gdb
493
-import sys
494
-
495
-
496
-n_failures = 0
497
-
498
-
499
-def report(cond, msg):
500
- """Report success/fail of a test"""
501
- if cond:
502
- print("PASS: {}".format(msg))
503
- else:
504
- print("FAIL: {}".format(msg))
505
- global n_failures
506
- n_failures += 1
507
+from test_gdbstub import main, report
508
509
510
def run_test():
511
@@ -XXX,XX +XXX,XX @@ def run_test():
512
# report("/sha1" in mappings, "Found the test binary name in the mappings")
513
514
515
-def main():
516
- """Prepare the environment and run through the tests"""
517
- try:
518
- inferior = gdb.selected_inferior()
519
- print("ATTACHED: {}".format(inferior.architecture().name()))
520
- except (gdb.error, AttributeError):
521
- print("SKIPPING (not connected)")
522
- exit(0)
523
-
524
- if gdb.parse_and_eval('$pc') == 0:
525
- print("SKIP: PC not set")
526
- exit(0)
527
-
528
- try:
529
- # Run the actual tests
530
- run_test()
531
- except gdb.error:
532
- report(False, "GDB Exception: {}".format(sys.exc_info()[0]))
533
- print("All tests complete: %d failures" % n_failures)
534
- exit(n_failures)
535
-
536
-
537
-main()
538
+main(run_test)
539
diff --git a/tests/tcg/multiarch/gdbstub/test-qxfer-auxv-read.py b/tests/tcg/multiarch/gdbstub/test-qxfer-auxv-read.py
540
index XXXXXXX..XXXXXXX 100644
541
--- a/tests/tcg/multiarch/gdbstub/test-qxfer-auxv-read.py
542
+++ b/tests/tcg/multiarch/gdbstub/test-qxfer-auxv-read.py
543
@@ -XXX,XX +XXX,XX @@
544
#
545
546
import gdb
547
-import sys
548
+from test_gdbstub import main, report
549
550
-failcount = 0
551
-
552
-def report(cond, msg):
553
- "Report success/fail of test"
554
- if cond:
555
- print ("PASS: %s" % (msg))
556
- else:
557
- print ("FAIL: %s" % (msg))
558
- global failcount
559
- failcount += 1
560
561
def run_test():
562
"Run through the tests one by one"
563
@@ -XXX,XX +XXX,XX @@ def run_test():
564
report(isinstance(auxv, str), "Fetched auxv from inferior")
565
report(auxv.find("sha1"), "Found test binary name in auxv")
566
567
-#
568
-# This runs as the script it sourced (via -x, via run-test.py)
569
-#
570
-try:
571
- inferior = gdb.selected_inferior()
572
- arch = inferior.architecture()
573
- print("ATTACHED: %s" % arch.name())
574
-except (gdb.error, AttributeError):
575
- print("SKIPPING (not connected)", file=sys.stderr)
576
- exit(0)
577
578
-if gdb.parse_and_eval('$pc') == 0:
579
- print("SKIP: PC not set")
580
- exit(0)
581
-
582
-try:
583
- # Run the actual tests
584
- run_test()
585
-except (gdb.error):
586
- print ("GDB Exception: %s" % (sys.exc_info()[0]))
587
- failcount += 1
588
- pass
589
-
590
-print("All tests complete: %d failures" % failcount)
591
-exit(failcount)
592
+main(run_test)
593
diff --git a/tests/tcg/multiarch/gdbstub/test-thread-breakpoint.py b/tests/tcg/multiarch/gdbstub/test-thread-breakpoint.py
594
index XXXXXXX..XXXXXXX 100644
595
--- a/tests/tcg/multiarch/gdbstub/test-thread-breakpoint.py
596
+++ b/tests/tcg/multiarch/gdbstub/test-thread-breakpoint.py
597
@@ -XXX,XX +XXX,XX @@
598
#
599
600
import gdb
601
-import sys
602
+from test_gdbstub import main, report
603
604
-failcount = 0
605
-
606
-def report(cond, msg):
607
- "Report success/fail of test"
608
- if cond:
609
- print ("PASS: %s" % (msg))
610
- else:
611
- print ("FAIL: %s" % (msg))
612
- global failcount
613
- failcount += 1
614
615
def run_test():
616
"Run through the tests one by one"
617
@@ -XXX,XX +XXX,XX @@ def run_test():
618
frame = gdb.selected_frame()
619
report(str(frame.function()) == "thread1_func", "break @ %s"%frame)
620
621
-#
622
-# This runs as the script it sourced (via -x, via run-test.py)
623
-#
624
-try:
625
- inferior = gdb.selected_inferior()
626
- arch = inferior.architecture()
627
- print("ATTACHED: %s" % arch.name())
628
-except (gdb.error, AttributeError):
629
- print("SKIPPING (not connected)", file=sys.stderr)
630
- exit(0)
631
632
-if gdb.parse_and_eval('$pc') == 0:
633
- print("SKIP: PC not set")
634
- exit(0)
635
-
636
-try:
637
- # Run the actual tests
638
- run_test()
639
-except (gdb.error):
640
- print ("GDB Exception: %s" % (sys.exc_info()[0]))
641
- failcount += 1
642
- pass
643
-
644
-print("All tests complete: %d failures" % failcount)
645
-exit(failcount)
646
+main(run_test)
647
diff --git a/tests/tcg/s390x/gdbstub/test-signals-s390x.py b/tests/tcg/s390x/gdbstub/test-signals-s390x.py
648
index XXXXXXX..XXXXXXX 100644
649
--- a/tests/tcg/s390x/gdbstub/test-signals-s390x.py
650
+++ b/tests/tcg/s390x/gdbstub/test-signals-s390x.py
651
@@ -XXX,XX +XXX,XX @@
652
#
653
654
import gdb
655
-import sys
656
-
657
-failcount = 0
658
-
659
-
660
-def report(cond, msg):
661
- """Report success/fail of test"""
662
- if cond:
663
- print("PASS: %s" % (msg))
664
- else:
665
- print("FAIL: %s" % (msg))
666
- global failcount
667
- failcount += 1
668
+from test_gdbstub import main, report
669
670
671
def run_test():
672
@@ -XXX,XX +XXX,XX @@ def run_test():
673
gdb.Breakpoint("_exit")
674
gdb.execute("c")
675
status = int(gdb.parse_and_eval("$r2"))
676
- report(status == 0, "status == 0");
677
+ report(status == 0, "status == 0")
678
679
680
-#
681
-# This runs as the script it sourced (via -x, via run-test.py)
682
-#
683
-try:
684
- inferior = gdb.selected_inferior()
685
- arch = inferior.architecture()
686
- print("ATTACHED: %s" % arch.name())
687
-except (gdb.error, AttributeError):
688
- print("SKIPPING (not connected)", file=sys.stderr)
689
- exit(0)
690
-
691
-if gdb.parse_and_eval("$pc") == 0:
692
- print("SKIP: PC not set")
693
- exit(0)
694
-
695
-try:
696
- # Run the actual tests
697
- run_test()
698
-except (gdb.error):
699
- print("GDB Exception: %s" % (sys.exc_info()[0]))
700
- failcount += 1
701
- pass
702
-
703
-print("All tests complete: %d failures" % failcount)
704
-exit(failcount)
705
+main(run_test)
706
diff --git a/tests/tcg/s390x/gdbstub/test-svc.py b/tests/tcg/s390x/gdbstub/test-svc.py
707
index XXXXXXX..XXXXXXX 100644
708
--- a/tests/tcg/s390x/gdbstub/test-svc.py
709
+++ b/tests/tcg/s390x/gdbstub/test-svc.py
710
@@ -XXX,XX +XXX,XX @@
711
This runs as a sourced script (via -x, via run-test.py)."""
712
from __future__ import print_function
713
import gdb
714
-import sys
715
-
716
-
717
-n_failures = 0
718
-
719
-
720
-def report(cond, msg):
721
- """Report success/fail of a test"""
722
- if cond:
723
- print("PASS: {}".format(msg))
724
- else:
725
- print("FAIL: {}".format(msg))
726
- global n_failures
727
- n_failures += 1
728
+from test_gdbstub import main, report
729
730
731
def run_test():
732
@@ -XXX,XX +XXX,XX @@ def run_test():
733
gdb.execute("si")
734
735
736
-def main():
737
- """Prepare the environment and run through the tests"""
738
- try:
739
- inferior = gdb.selected_inferior()
740
- print("ATTACHED: {}".format(inferior.architecture().name()))
741
- except (gdb.error, AttributeError):
742
- print("SKIPPING (not connected)")
743
- exit(0)
744
-
745
- if gdb.parse_and_eval('$pc') == 0:
746
- print("SKIP: PC not set")
747
- exit(0)
748
-
749
- try:
750
- # Run the actual tests
751
- run_test()
752
- except gdb.error:
753
- report(False, "GDB Exception: {}".format(sys.exc_info()[0]))
754
- print("All tests complete: %d failures" % n_failures)
755
- exit(n_failures)
756
-
757
-
758
-main()
759
+main(run_test)
760
--
219
--
761
2.34.1
220
2.43.0
diff view generated by jsdifflib
1
From: Anton Johansson <anjo@rev.ng>
1
This massive macro is now only used once.
2
Expand it for use only by float64.
2
3
3
The ifdef out of which it is moved is not quite right: do_interrupt is
4
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
4
only needed for system mode. Move it to the top of a different ifdef
5
block, which preserves its position within the structure for that case.
6
7
Signed-off-by: Anton Johansson <anjo@rev.ng>
8
Message-Id: <20240119144024.14289-18-anjo@rev.ng>
9
[rth: Split from a larger patch and simplified.]
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
6
---
12
include/hw/core/tcg-cpu-ops.h | 7 ++-----
7
target/hexagon/fma_emu.c | 255 +++++++++++++++++++--------------------
13
1 file changed, 2 insertions(+), 5 deletions(-)
8
1 file changed, 127 insertions(+), 128 deletions(-)
14
9
15
diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
10
diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c
16
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/core/tcg-cpu-ops.h
12
--- a/target/hexagon/fma_emu.c
18
+++ b/include/hw/core/tcg-cpu-ops.h
13
+++ b/target/hexagon/fma_emu.c
19
@@ -XXX,XX +XXX,XX @@ struct TCGCPUOps {
14
@@ -XXX,XX +XXX,XX @@ float32 infinite_float32(uint8_t sign)
20
* cpu execution loop (hack for x86 user mode).
15
}
21
*/
16
22
void (*fake_user_interrupt)(CPUState *cpu);
17
/* Return a maximum finite value with the requested sign */
23
-#else
18
-#define GEN_XF_ROUND(SUFFIX, MANTBITS, INF_EXP, INTERNAL_TYPE) \
24
- /**
19
-static SUFFIX accum_round_##SUFFIX(Accum a, float_status * fp_status) \
25
- * @do_interrupt: Callback for interrupt handling.
20
-{ \
26
- */
21
- if ((int128_gethi(a.mant) == 0) && (int128_getlo(a.mant) == 0) \
27
- void (*do_interrupt)(CPUState *cpu);
22
- && ((a.guard | a.round | a.sticky) == 0)) { \
28
#endif /* !CONFIG_USER_ONLY || !TARGET_I386 */
23
- /* result zero */ \
29
#ifdef CONFIG_USER_ONLY
24
- switch (fp_status->float_rounding_mode) { \
30
/**
25
- case float_round_down: \
31
@@ -XXX,XX +XXX,XX @@ struct TCGCPUOps {
26
- return zero_##SUFFIX(1); \
32
void (*record_sigbus)(CPUState *cpu, vaddr addr,
27
- default: \
33
MMUAccessType access_type, uintptr_t ra);
28
- return zero_##SUFFIX(0); \
34
#else
29
- } \
35
+ /** @do_interrupt: Callback for interrupt handling. */
30
- } \
36
+ void (*do_interrupt)(CPUState *cpu);
31
- /* Normalize right */ \
37
/** @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec */
32
- /* We want MANTBITS bits of mantissa plus the leading one. */ \
38
bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request);
33
- /* That means that we want MANTBITS+1 bits, or 0x000000000000FF_FFFF */ \
39
/**
34
- /* So we need to normalize right while the high word is non-zero and \
35
- * while the low word is nonzero when masked with 0xffe0_0000_0000_0000 */ \
36
- while ((int128_gethi(a.mant) != 0) || \
37
- ((int128_getlo(a.mant) >> (MANTBITS + 1)) != 0)) { \
38
- a = accum_norm_right(a, 1); \
39
- } \
40
- /* \
41
- * OK, now normalize left \
42
- * We want to normalize left until we have a leading one in bit 24 \
43
- * Theoretically, we only need to shift a maximum of one to the left if we \
44
- * shifted out lots of bits from B, or if we had no shift / 1 shift sticky \
45
- * should be 0 \
46
- */ \
47
- while ((int128_getlo(a.mant) & (1ULL << MANTBITS)) == 0) { \
48
- a = accum_norm_left(a); \
49
- } \
50
- /* \
51
- * OK, now we might need to denormalize because of potential underflow. \
52
- * We need to do this before rounding, and rounding might make us normal \
53
- * again \
54
- */ \
55
- while (a.exp <= 0) { \
56
- a = accum_norm_right(a, 1 - a.exp); \
57
- /* \
58
- * Do we have underflow? \
59
- * That's when we get an inexact answer because we ran out of bits \
60
- * in a denormal. \
61
- */ \
62
- if (a.guard || a.round || a.sticky) { \
63
- float_raise(float_flag_underflow, fp_status); \
64
- } \
65
- } \
66
- /* OK, we're relatively canonical... now we need to round */ \
67
- if (a.guard || a.round || a.sticky) { \
68
- float_raise(float_flag_inexact, fp_status); \
69
- switch (fp_status->float_rounding_mode) { \
70
- case float_round_to_zero: \
71
- /* Chop and we're done */ \
72
- break; \
73
- case float_round_up: \
74
- if (a.sign == 0) { \
75
- a.mant = int128_add(a.mant, int128_one()); \
76
- } \
77
- break; \
78
- case float_round_down: \
79
- if (a.sign != 0) { \
80
- a.mant = int128_add(a.mant, int128_one()); \
81
- } \
82
- break; \
83
- default: \
84
- if (a.round || a.sticky) { \
85
- /* round up if guard is 1, down if guard is zero */ \
86
- a.mant = int128_add(a.mant, int128_make64(a.guard)); \
87
- } else if (a.guard) { \
88
- /* exactly .5, round up if odd */ \
89
- a.mant = int128_add(a.mant, int128_and(a.mant, int128_one())); \
90
- } \
91
- break; \
92
- } \
93
- } \
94
- /* \
95
- * OK, now we might have carried all the way up. \
96
- * So we might need to shr once \
97
- * at least we know that the lsb should be zero if we rounded and \
98
- * got a carry out... \
99
- */ \
100
- if ((int128_getlo(a.mant) >> (MANTBITS + 1)) != 0) { \
101
- a = accum_norm_right(a, 1); \
102
- } \
103
- /* Overflow? */ \
104
- if (a.exp >= INF_EXP) { \
105
- /* Yep, inf result */ \
106
- float_raise(float_flag_overflow, fp_status); \
107
- float_raise(float_flag_inexact, fp_status); \
108
- switch (fp_status->float_rounding_mode) { \
109
- case float_round_to_zero: \
110
- return maxfinite_##SUFFIX(a.sign); \
111
- case float_round_up: \
112
- if (a.sign == 0) { \
113
- return infinite_##SUFFIX(a.sign); \
114
- } else { \
115
- return maxfinite_##SUFFIX(a.sign); \
116
- } \
117
- case float_round_down: \
118
- if (a.sign != 0) { \
119
- return infinite_##SUFFIX(a.sign); \
120
- } else { \
121
- return maxfinite_##SUFFIX(a.sign); \
122
- } \
123
- default: \
124
- return infinite_##SUFFIX(a.sign); \
125
- } \
126
- } \
127
- /* Underflow? */ \
128
- if (int128_getlo(a.mant) & (1ULL << MANTBITS)) { \
129
- /* Leading one means: No, we're normal. So, we should be done... */ \
130
- INTERNAL_TYPE ret; \
131
- ret.i = 0; \
132
- ret.sign = a.sign; \
133
- ret.exp = a.exp; \
134
- ret.mant = int128_getlo(a.mant); \
135
- return ret.i; \
136
- } \
137
- assert(a.exp == 1); \
138
- INTERNAL_TYPE ret; \
139
- ret.i = 0; \
140
- ret.sign = a.sign; \
141
- ret.exp = 0; \
142
- ret.mant = int128_getlo(a.mant); \
143
- return ret.i; \
144
+static float64 accum_round_float64(Accum a, float_status *fp_status)
145
+{
146
+ if ((int128_gethi(a.mant) == 0) && (int128_getlo(a.mant) == 0)
147
+ && ((a.guard | a.round | a.sticky) == 0)) {
148
+ /* result zero */
149
+ switch (fp_status->float_rounding_mode) {
150
+ case float_round_down:
151
+ return zero_float64(1);
152
+ default:
153
+ return zero_float64(0);
154
+ }
155
+ }
156
+ /*
157
+ * Normalize right
158
+ * We want DF_MANTBITS bits of mantissa plus the leading one.
159
+ * That means that we want DF_MANTBITS+1 bits, or 0x000000000000FF_FFFF
160
+ * So we need to normalize right while the high word is non-zero and
161
+ * while the low word is nonzero when masked with 0xffe0_0000_0000_0000
162
+ */
163
+ while ((int128_gethi(a.mant) != 0) ||
164
+ ((int128_getlo(a.mant) >> (DF_MANTBITS + 1)) != 0)) {
165
+ a = accum_norm_right(a, 1);
166
+ }
167
+ /*
168
+ * OK, now normalize left
169
+ * We want to normalize left until we have a leading one in bit 24
170
+ * Theoretically, we only need to shift a maximum of one to the left if we
171
+ * shifted out lots of bits from B, or if we had no shift / 1 shift sticky
172
+ * should be 0
173
+ */
174
+ while ((int128_getlo(a.mant) & (1ULL << DF_MANTBITS)) == 0) {
175
+ a = accum_norm_left(a);
176
+ }
177
+ /*
178
+ * OK, now we might need to denormalize because of potential underflow.
179
+ * We need to do this before rounding, and rounding might make us normal
180
+ * again
181
+ */
182
+ while (a.exp <= 0) {
183
+ a = accum_norm_right(a, 1 - a.exp);
184
+ /*
185
+ * Do we have underflow?
186
+ * That's when we get an inexact answer because we ran out of bits
187
+ * in a denormal.
188
+ */
189
+ if (a.guard || a.round || a.sticky) {
190
+ float_raise(float_flag_underflow, fp_status);
191
+ }
192
+ }
193
+ /* OK, we're relatively canonical... now we need to round */
194
+ if (a.guard || a.round || a.sticky) {
195
+ float_raise(float_flag_inexact, fp_status);
196
+ switch (fp_status->float_rounding_mode) {
197
+ case float_round_to_zero:
198
+ /* Chop and we're done */
199
+ break;
200
+ case float_round_up:
201
+ if (a.sign == 0) {
202
+ a.mant = int128_add(a.mant, int128_one());
203
+ }
204
+ break;
205
+ case float_round_down:
206
+ if (a.sign != 0) {
207
+ a.mant = int128_add(a.mant, int128_one());
208
+ }
209
+ break;
210
+ default:
211
+ if (a.round || a.sticky) {
212
+ /* round up if guard is 1, down if guard is zero */
213
+ a.mant = int128_add(a.mant, int128_make64(a.guard));
214
+ } else if (a.guard) {
215
+ /* exactly .5, round up if odd */
216
+ a.mant = int128_add(a.mant, int128_and(a.mant, int128_one()));
217
+ }
218
+ break;
219
+ }
220
+ }
221
+ /*
222
+ * OK, now we might have carried all the way up.
223
+ * So we might need to shr once
224
+ * at least we know that the lsb should be zero if we rounded and
225
+ * got a carry out...
226
+ */
227
+ if ((int128_getlo(a.mant) >> (DF_MANTBITS + 1)) != 0) {
228
+ a = accum_norm_right(a, 1);
229
+ }
230
+ /* Overflow? */
231
+ if (a.exp >= DF_INF_EXP) {
232
+ /* Yep, inf result */
233
+ float_raise(float_flag_overflow, fp_status);
234
+ float_raise(float_flag_inexact, fp_status);
235
+ switch (fp_status->float_rounding_mode) {
236
+ case float_round_to_zero:
237
+ return maxfinite_float64(a.sign);
238
+ case float_round_up:
239
+ if (a.sign == 0) {
240
+ return infinite_float64(a.sign);
241
+ } else {
242
+ return maxfinite_float64(a.sign);
243
+ }
244
+ case float_round_down:
245
+ if (a.sign != 0) {
246
+ return infinite_float64(a.sign);
247
+ } else {
248
+ return maxfinite_float64(a.sign);
249
+ }
250
+ default:
251
+ return infinite_float64(a.sign);
252
+ }
253
+ }
254
+ /* Underflow? */
255
+ if (int128_getlo(a.mant) & (1ULL << DF_MANTBITS)) {
256
+ /* Leading one means: No, we're normal. So, we should be done... */
257
+ Double ret;
258
+ ret.i = 0;
259
+ ret.sign = a.sign;
260
+ ret.exp = a.exp;
261
+ ret.mant = int128_getlo(a.mant);
262
+ return ret.i;
263
+ }
264
+ assert(a.exp == 1);
265
+ Double ret;
266
+ ret.i = 0;
267
+ ret.sign = a.sign;
268
+ ret.exp = 0;
269
+ ret.mant = int128_getlo(a.mant);
270
+ return ret.i;
271
}
272
273
-GEN_XF_ROUND(float64, DF_MANTBITS, DF_INF_EXP, Double)
274
-
275
float64 internal_mpyhh(float64 a, float64 b,
276
unsigned long long int accumulated,
277
float_status *fp_status)
40
--
278
--
41
2.34.1
279
2.43.0
diff view generated by jsdifflib
1
From: Anton Johansson <anjo@rev.ng>
1
This structure, with bitfields, is incorrect for big-endian.
2
Use the existing float32_getexp_raw which uses extract32.
2
3
3
Needed to work around circular includes. vaddr is currently defined in
4
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
4
cpu-common.h and needed by hw/core/cpu.h, but cpu-common.h also need
5
cpu.h to know the size of the CPUState.
6
7
[Maybe we can instead move parts of cpu-common.h w. hw/core/cpu.h to
8
sort out the circular inclusion.]
9
10
Signed-off-by: Anton Johansson <anjo@rev.ng>
11
Message-Id: <20240119144024.14289-7-anjo@rev.ng>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
[rth: Add include of vaddr.h into cpu-common.h]
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
---
6
---
16
include/exec/cpu-common.h | 13 +------------
7
target/hexagon/fma_emu.c | 16 +++-------------
17
include/exec/vaddr.h | 18 ++++++++++++++++++
8
1 file changed, 3 insertions(+), 13 deletions(-)
18
2 files changed, 19 insertions(+), 12 deletions(-)
19
create mode 100644 include/exec/vaddr.h
20
9
21
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
10
diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c
22
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
23
--- a/include/exec/cpu-common.h
12
--- a/target/hexagon/fma_emu.c
24
+++ b/include/exec/cpu-common.h
13
+++ b/target/hexagon/fma_emu.c
25
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ typedef union {
26
15
};
27
/* CPU interfaces that are target independent. */
16
} Double;
28
17
29
+#include "exec/vaddr.h"
18
-typedef union {
30
#ifndef CONFIG_USER_ONLY
19
- float f;
31
#include "exec/hwaddr.h"
20
- uint32_t i;
32
#endif
21
- struct {
33
@@ -XXX,XX +XXX,XX @@
22
- uint32_t mant:23;
34
#define EXCP_YIELD 0x10004 /* cpu wants to yield timeslice to another */
23
- uint32_t exp:8;
35
#define EXCP_ATOMIC 0x10005 /* stop-the-world and emulate atomic */
24
- uint32_t sign:1;
36
25
- };
37
-/**
26
-} Float;
38
- * vaddr:
39
- * Type wide enough to contain any #target_ulong virtual address.
40
- */
41
-typedef uint64_t vaddr;
42
-#define VADDR_PRId PRId64
43
-#define VADDR_PRIu PRIu64
44
-#define VADDR_PRIo PRIo64
45
-#define VADDR_PRIx PRIx64
46
-#define VADDR_PRIX PRIX64
47
-#define VADDR_MAX UINT64_MAX
48
-
27
-
49
void cpu_exec_init_all(void);
28
static uint64_t float64_getmant(float64 f64)
50
void cpu_exec_step_atomic(CPUState *cpu);
29
{
51
30
Double a = { .i = f64 };
52
diff --git a/include/exec/vaddr.h b/include/exec/vaddr.h
31
@@ -XXX,XX +XXX,XX @@ int32_t float64_getexp(float64 f64)
53
new file mode 100644
32
54
index XXXXXXX..XXXXXXX
33
int32_t float32_getexp(float32 f32)
55
--- /dev/null
34
{
56
+++ b/include/exec/vaddr.h
35
- Float a = { .i = f32 };
57
@@ -XXX,XX +XXX,XX @@
36
+ int exp = float32_getexp_raw(f32);
58
+/* Define vaddr. */
37
if (float32_is_normal(f32)) {
59
+
38
- return a.exp;
60
+#ifndef VADDR_H
39
+ return exp;
61
+#define VADDR_H
40
}
62
+
41
if (float32_is_denormal(f32)) {
63
+/**
42
- return a.exp + 1;
64
+ * vaddr:
43
+ return exp + 1;
65
+ * Type wide enough to contain any #target_ulong virtual address.
44
}
66
+ */
45
return -1;
67
+typedef uint64_t vaddr;
46
}
68
+#define VADDR_PRId PRId64
69
+#define VADDR_PRIu PRIu64
70
+#define VADDR_PRIo PRIo64
71
+#define VADDR_PRIx PRIx64
72
+#define VADDR_PRIX PRIX64
73
+#define VADDR_MAX UINT64_MAX
74
+
75
+#endif
76
--
47
--
77
2.34.1
48
2.43.0
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
This structure, with bitfields, is incorrect for big-endian.
2
Use extract64 and deposit64 instead.
2
3
3
tcg_cpus_destroy() operates on a single vCPU, rename it
4
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
4
as 'tcg_cpu_destroy'.
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Anton Johansson <anjo@rev.ng>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-Id: <20240124101639.30056-3-philmd@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
6
---
12
accel/tcg/tcg-accel-ops.h | 2 +-
7
target/hexagon/fma_emu.c | 46 ++++++++++++++--------------------------
13
accel/tcg/tcg-accel-ops-mttcg.c | 2 +-
8
1 file changed, 16 insertions(+), 30 deletions(-)
14
accel/tcg/tcg-accel-ops-rr.c | 2 +-
15
accel/tcg/tcg-accel-ops.c | 2 +-
16
4 files changed, 4 insertions(+), 4 deletions(-)
17
9
18
diff --git a/accel/tcg/tcg-accel-ops.h b/accel/tcg/tcg-accel-ops.h
10
diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c
19
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
20
--- a/accel/tcg/tcg-accel-ops.h
12
--- a/target/hexagon/fma_emu.c
21
+++ b/accel/tcg/tcg-accel-ops.h
13
+++ b/target/hexagon/fma_emu.c
22
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@
23
15
24
#include "sysemu/cpus.h"
16
#define WAY_BIG_EXP 4096
25
17
26
-void tcg_cpus_destroy(CPUState *cpu);
18
-typedef union {
27
+void tcg_cpu_destroy(CPUState *cpu);
19
- double f;
28
int tcg_cpus_exec(CPUState *cpu);
20
- uint64_t i;
29
void tcg_handle_interrupt(CPUState *cpu, int mask);
21
- struct {
30
void tcg_cpu_init_cflags(CPUState *cpu, bool parallel);
22
- uint64_t mant:52;
31
diff --git a/accel/tcg/tcg-accel-ops-mttcg.c b/accel/tcg/tcg-accel-ops-mttcg.c
23
- uint64_t exp:11;
32
index XXXXXXX..XXXXXXX 100644
24
- uint64_t sign:1;
33
--- a/accel/tcg/tcg-accel-ops-mttcg.c
25
- };
34
+++ b/accel/tcg/tcg-accel-ops-mttcg.c
26
-} Double;
35
@@ -XXX,XX +XXX,XX @@ static void *mttcg_cpu_thread_fn(void *arg)
27
-
36
qemu_wait_io_event(cpu);
28
static uint64_t float64_getmant(float64 f64)
37
} while (!cpu->unplug || cpu_can_run(cpu));
29
{
38
30
- Double a = { .i = f64 };
39
- tcg_cpus_destroy(cpu);
31
+ uint64_t mant = extract64(f64, 0, 52);
40
+ tcg_cpu_destroy(cpu);
32
if (float64_is_normal(f64)) {
41
bql_unlock();
33
- return a.mant | 1ULL << 52;
42
rcu_remove_force_rcu_notifier(&force_rcu.notifier);
34
+ return mant | 1ULL << 52;
43
rcu_unregister_thread();
35
}
44
diff --git a/accel/tcg/tcg-accel-ops-rr.c b/accel/tcg/tcg-accel-ops-rr.c
36
if (float64_is_zero(f64)) {
45
index XXXXXXX..XXXXXXX 100644
37
return 0;
46
--- a/accel/tcg/tcg-accel-ops-rr.c
38
}
47
+++ b/accel/tcg/tcg-accel-ops-rr.c
39
if (float64_is_denormal(f64)) {
48
@@ -XXX,XX +XXX,XX @@ static void rr_deal_with_unplugged_cpus(void)
40
- return a.mant;
49
41
+ return mant;
50
CPU_FOREACH(cpu) {
42
}
51
if (cpu->unplug && !cpu_can_run(cpu)) {
43
return ~0ULL;
52
- tcg_cpus_destroy(cpu);
44
}
53
+ tcg_cpu_destroy(cpu);
45
54
break;
46
int32_t float64_getexp(float64 f64)
47
{
48
- Double a = { .i = f64 };
49
+ int exp = extract64(f64, 52, 11);
50
if (float64_is_normal(f64)) {
51
- return a.exp;
52
+ return exp;
53
}
54
if (float64_is_denormal(f64)) {
55
- return a.exp + 1;
56
+ return exp + 1;
57
}
58
return -1;
59
}
60
@@ -XXX,XX +XXX,XX @@ float32 infinite_float32(uint8_t sign)
61
/* Return a maximum finite value with the requested sign */
62
static float64 accum_round_float64(Accum a, float_status *fp_status)
63
{
64
+ uint64_t ret;
65
+
66
if ((int128_gethi(a.mant) == 0) && (int128_getlo(a.mant) == 0)
67
&& ((a.guard | a.round | a.sticky) == 0)) {
68
/* result zero */
69
@@ -XXX,XX +XXX,XX @@ static float64 accum_round_float64(Accum a, float_status *fp_status)
55
}
70
}
56
}
71
}
57
diff --git a/accel/tcg/tcg-accel-ops.c b/accel/tcg/tcg-accel-ops.c
72
/* Underflow? */
58
index XXXXXXX..XXXXXXX 100644
73
- if (int128_getlo(a.mant) & (1ULL << DF_MANTBITS)) {
59
--- a/accel/tcg/tcg-accel-ops.c
74
+ ret = int128_getlo(a.mant);
60
+++ b/accel/tcg/tcg-accel-ops.c
75
+ if (ret & (1ULL << DF_MANTBITS)) {
61
@@ -XXX,XX +XXX,XX @@ void tcg_cpu_init_cflags(CPUState *cpu, bool parallel)
76
/* Leading one means: No, we're normal. So, we should be done... */
62
cpu->tcg_cflags |= cflags;
77
- Double ret;
78
- ret.i = 0;
79
- ret.sign = a.sign;
80
- ret.exp = a.exp;
81
- ret.mant = int128_getlo(a.mant);
82
- return ret.i;
83
+ ret = deposit64(ret, 52, 11, a.exp);
84
+ } else {
85
+ assert(a.exp == 1);
86
+ ret = deposit64(ret, 52, 11, 0);
87
}
88
- assert(a.exp == 1);
89
- Double ret;
90
- ret.i = 0;
91
- ret.sign = a.sign;
92
- ret.exp = 0;
93
- ret.mant = int128_getlo(a.mant);
94
- return ret.i;
95
+ ret = deposit64(ret, 63, 1, a.sign);
96
+ return ret;
63
}
97
}
64
98
65
-void tcg_cpus_destroy(CPUState *cpu)
99
float64 internal_mpyhh(float64 a, float64 b,
66
+void tcg_cpu_destroy(CPUState *cpu)
67
{
68
cpu_thread_signal_destroyed(cpu);
69
}
70
--
100
--
71
2.34.1
101
2.43.0
72
73
diff view generated by jsdifflib
1
From: Anton Johansson <anjo@rev.ng>
1
No need to open-code 64x64->128-bit multiplication.
2
2
3
Functions are target independent.
3
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
4
5
Signed-off-by: Anton Johansson <anjo@rev.ng>
6
Message-Id: <20240119144024.14289-17-anjo@rev.ng>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
5
---
11
include/exec/cpu-all.h | 25 -------------------------
6
target/hexagon/fma_emu.c | 32 +++-----------------------------
12
include/exec/cpu-common.h | 26 ++++++++++++++++++++++++++
7
1 file changed, 3 insertions(+), 29 deletions(-)
13
2 files changed, 26 insertions(+), 25 deletions(-)
14
8
15
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
9
diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c
16
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
17
--- a/include/exec/cpu-all.h
11
--- a/target/hexagon/fma_emu.c
18
+++ b/include/exec/cpu-all.h
12
+++ b/target/hexagon/fma_emu.c
19
@@ -XXX,XX +XXX,XX @@ static inline bool tlb_hit(uint64_t tlb_addr, vaddr addr)
13
@@ -XXX,XX +XXX,XX @@ int32_t float32_getexp(float32 f32)
20
14
return -1;
21
#endif /* !CONFIG_USER_ONLY */
15
}
22
16
23
-/* accel/tcg/cpu-exec.c */
17
-static uint32_t int128_getw0(Int128 x)
24
-int cpu_exec(CPUState *cpu);
25
-
26
/* Validate correct placement of CPUArchState. */
27
QEMU_BUILD_BUG_ON(offsetof(ArchCPU, parent_obj) != 0);
28
QEMU_BUILD_BUG_ON(offsetof(ArchCPU, env) != sizeof(CPUState));
29
30
-/**
31
- * env_archcpu(env)
32
- * @env: The architecture environment
33
- *
34
- * Return the ArchCPU associated with the environment.
35
- */
36
-static inline ArchCPU *env_archcpu(CPUArchState *env)
37
-{
18
-{
38
- return (void *)env - sizeof(CPUState);
19
- return int128_getlo(x);
39
-}
20
-}
40
-
21
-
41
-/**
22
-static uint32_t int128_getw1(Int128 x)
42
- * env_cpu(env)
43
- * @env: The architecture environment
44
- *
45
- * Return the CPUState associated with the environment.
46
- */
47
-static inline CPUState *env_cpu(CPUArchState *env)
48
-{
23
-{
49
- return (void *)env - sizeof(CPUState);
24
- return int128_getlo(x) >> 32;
50
-}
25
-}
51
-
26
-
52
#endif /* CPU_ALL_H */
27
static Int128 int128_mul_6464(uint64_t ai, uint64_t bi)
53
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
28
{
54
index XXXXXXX..XXXXXXX 100644
29
- Int128 a, b;
55
--- a/include/exec/cpu-common.h
30
- uint64_t pp0, pp1a, pp1b, pp1s, pp2;
56
+++ b/include/exec/cpu-common.h
31
+ uint64_t l, h;
57
@@ -XXX,XX +XXX,XX @@
32
58
#ifndef CONFIG_USER_ONLY
33
- a = int128_make64(ai);
59
#include "exec/hwaddr.h"
34
- b = int128_make64(bi);
60
#endif
35
- pp0 = (uint64_t)int128_getw0(a) * (uint64_t)int128_getw0(b);
61
+#include "hw/core/cpu.h"
36
- pp1a = (uint64_t)int128_getw1(a) * (uint64_t)int128_getw0(b);
62
37
- pp1b = (uint64_t)int128_getw1(b) * (uint64_t)int128_getw0(a);
63
#define EXCP_INTERRUPT 0x10000 /* async interruption */
38
- pp2 = (uint64_t)int128_getw1(a) * (uint64_t)int128_getw1(b);
64
#define EXCP_HLT 0x10001 /* hlt instruction reached */
39
-
65
@@ -XXX,XX +XXX,XX @@ G_NORETURN void cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc);
40
- pp1s = pp1a + pp1b;
66
*/
41
- if ((pp1s < pp1a) || (pp1s < pp1b)) {
67
#define PAGE_PASSTHROUGH 0x0800
42
- pp2 += (1ULL << 32);
68
43
- }
69
+/* accel/tcg/cpu-exec.c */
44
- uint64_t ret_low = pp0 + (pp1s << 32);
70
+int cpu_exec(CPUState *cpu);
45
- if ((ret_low < pp0) || (ret_low < (pp1s << 32))) {
71
+
46
- pp2 += 1;
72
+/**
47
- }
73
+ * env_archcpu(env)
48
-
74
+ * @env: The architecture environment
49
- return int128_make128(ret_low, pp2 + (pp1s >> 32));
75
+ *
50
+ mulu64(&l, &h, ai, bi);
76
+ * Return the ArchCPU associated with the environment.
51
+ return int128_make128(l, h);
77
+ */
52
}
78
+static inline ArchCPU *env_archcpu(CPUArchState *env)
53
79
+{
54
static Int128 int128_sub_borrow(Int128 a, Int128 b, int borrow)
80
+ return (void *)env - sizeof(CPUState);
81
+}
82
+
83
+/**
84
+ * env_cpu(env)
85
+ * @env: The architecture environment
86
+ *
87
+ * Return the CPUState associated with the environment.
88
+ */
89
+static inline CPUState *env_cpu(CPUArchState *env)
90
+{
91
+ return (void *)env - sizeof(CPUState);
92
+}
93
+
94
#endif /* CPU_COMMON_H */
95
--
55
--
96
2.34.1
56
2.43.0
97
98
diff view generated by jsdifflib
1
From: Anton Johansson <anjo@rev.ng>
1
Initialize x with accumulated via direct assignment,
2
rather than multiplying by 1.
2
3
3
cpu-common.h is only needed for vaddr
4
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
4
5
Signed-off-by: Anton Johansson <anjo@rev.ng>
6
Message-Id: <20240119144024.14289-8-anjo@rev.ng>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
6
---
10
include/hw/core/cpu.h | 2 +-
7
target/hexagon/fma_emu.c | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
8
1 file changed, 1 insertion(+), 1 deletion(-)
12
9
13
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
10
diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c
14
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/core/cpu.h
12
--- a/target/hexagon/fma_emu.c
16
+++ b/include/hw/core/cpu.h
13
+++ b/target/hexagon/fma_emu.c
17
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ float64 internal_mpyhh(float64 a, float64 b,
18
15
float64_is_infinity(b)) {
19
#include "hw/qdev-core.h"
16
return float64_mul(a, b, fp_status);
20
#include "disas/dis-asm.h"
17
}
21
-#include "exec/cpu-common.h"
18
- x.mant = int128_mul_6464(accumulated, 1);
22
#include "exec/hwaddr.h"
19
+ x.mant = int128_make64(accumulated);
23
+#include "exec/vaddr.h"
20
x.sticky = sticky;
24
#include "exec/memattrs.h"
21
prod = fGETUWORD(1, float64_getmant(a)) * fGETUWORD(1, float64_getmant(b));
25
#include "exec/tlb-common.h"
22
x.mant = int128_add(x.mant, int128_mul_6464(prod, 0x100000000ULL));
26
#include "qapi/qapi-types-run-state.h"
27
--
23
--
28
2.34.1
24
2.43.0
diff view generated by jsdifflib
1
From: Anton Johansson <anjo@rev.ng>
1
Convert all targets simultaneously, as the gen_intermediate_code
2
function disappears from the target. While there are possible
3
workarounds, they're larger than simply performing the conversion.
2
4
3
Makes gen_intermediate_code() signature target agnostic so the function
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
can be called from accel/tcg/translate-all.c without target specifics.
5
6
Signed-off-by: Anton Johansson <anjo@rev.ng>
7
Message-Id: <20240119144024.14289-9-anjo@rev.ng>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
7
---
11
include/exec/translator.h | 2 +-
8
include/exec/translator.h | 14 --------------
12
target/alpha/translate.c | 2 +-
9
include/hw/core/tcg-cpu-ops.h | 13 +++++++++++++
13
target/arm/tcg/translate.c | 2 +-
10
target/alpha/cpu.h | 2 ++
14
target/avr/translate.c | 2 +-
11
target/arm/internals.h | 2 ++
15
target/cris/translate.c | 2 +-
12
target/avr/cpu.h | 2 ++
16
target/hexagon/translate.c | 2 +-
13
target/hexagon/cpu.h | 2 ++
17
target/hppa/translate.c | 2 +-
14
target/hppa/cpu.h | 2 ++
18
target/i386/tcg/translate.c | 2 +-
15
target/i386/tcg/helper-tcg.h | 2 ++
19
target/loongarch/tcg/translate.c | 2 +-
16
target/loongarch/internals.h | 2 ++
20
target/m68k/translate.c | 2 +-
17
target/m68k/cpu.h | 2 ++
21
target/microblaze/translate.c | 2 +-
18
target/microblaze/cpu.h | 2 ++
22
target/mips/tcg/translate.c | 2 +-
19
target/mips/tcg/tcg-internal.h | 2 ++
23
target/nios2/translate.c | 2 +-
20
target/openrisc/cpu.h | 2 ++
24
target/openrisc/translate.c | 2 +-
21
target/ppc/cpu.h | 2 ++
25
target/ppc/translate.c | 2 +-
22
target/riscv/cpu.h | 3 +++
26
target/riscv/translate.c | 2 +-
23
target/rx/cpu.h | 2 ++
27
target/rx/translate.c | 2 +-
24
target/s390x/s390x-internal.h | 2 ++
28
target/s390x/tcg/translate.c | 2 +-
25
target/sh4/cpu.h | 2 ++
29
target/sh4/translate.c | 2 +-
26
target/sparc/cpu.h | 2 ++
30
target/sparc/translate.c | 2 +-
27
target/tricore/cpu.h | 2 ++
31
target/tricore/translate.c | 2 +-
28
target/xtensa/cpu.h | 2 ++
32
target/xtensa/translate.c | 2 +-
29
accel/tcg/cpu-exec.c | 8 +++++---
33
22 files changed, 22 insertions(+), 22 deletions(-)
30
accel/tcg/translate-all.c | 8 +++++---
31
target/alpha/cpu.c | 1 +
32
target/alpha/translate.c | 4 ++--
33
target/arm/cpu.c | 1 +
34
target/arm/tcg/cpu-v7m.c | 1 +
35
target/arm/tcg/translate.c | 5 ++---
36
target/avr/cpu.c | 1 +
37
target/avr/translate.c | 6 +++---
38
target/hexagon/cpu.c | 1 +
39
target/hexagon/translate.c | 4 ++--
40
target/hppa/cpu.c | 1 +
41
target/hppa/translate.c | 4 ++--
42
target/i386/tcg/tcg-cpu.c | 1 +
43
target/i386/tcg/translate.c | 5 ++---
44
target/loongarch/cpu.c | 1 +
45
target/loongarch/tcg/translate.c | 4 ++--
46
target/m68k/cpu.c | 1 +
47
target/m68k/translate.c | 4 ++--
48
target/microblaze/cpu.c | 1 +
49
target/microblaze/translate.c | 4 ++--
50
target/mips/cpu.c | 1 +
51
target/mips/tcg/translate.c | 4 ++--
52
target/openrisc/cpu.c | 1 +
53
target/openrisc/translate.c | 4 ++--
54
target/ppc/cpu_init.c | 1 +
55
target/ppc/translate.c | 4 ++--
56
target/riscv/tcg/tcg-cpu.c | 1 +
57
target/riscv/translate.c | 4 ++--
58
target/rx/cpu.c | 1 +
59
target/rx/translate.c | 4 ++--
60
target/s390x/cpu.c | 1 +
61
target/s390x/tcg/translate.c | 4 ++--
62
target/sh4/cpu.c | 1 +
63
target/sh4/translate.c | 4 ++--
64
target/sparc/cpu.c | 1 +
65
target/sparc/translate.c | 4 ++--
66
target/tricore/cpu.c | 1 +
67
target/tricore/translate.c | 5 ++---
68
target/xtensa/cpu.c | 1 +
69
target/xtensa/translate.c | 4 ++--
70
62 files changed, 121 insertions(+), 62 deletions(-)
34
71
35
diff --git a/include/exec/translator.h b/include/exec/translator.h
72
diff --git a/include/exec/translator.h b/include/exec/translator.h
36
index XXXXXXX..XXXXXXX 100644
73
index XXXXXXX..XXXXXXX 100644
37
--- a/include/exec/translator.h
74
--- a/include/exec/translator.h
38
+++ b/include/exec/translator.h
75
+++ b/include/exec/translator.h
39
@@ -XXX,XX +XXX,XX @@
76
@@ -XXX,XX +XXX,XX @@
40
* the target-specific DisasContext, and then invoke translator_loop.
77
#include "qemu/bswap.h"
41
*/
78
#include "exec/vaddr.h"
42
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
79
43
- target_ulong pc, void *host_pc);
80
-/**
44
+ vaddr pc, void *host_pc);
81
- * gen_intermediate_code
45
82
- * @cpu: cpu context
83
- * @tb: translation block
84
- * @max_insns: max number of instructions to translate
85
- * @pc: guest virtual program counter address
86
- * @host_pc: host physical program counter address
87
- *
88
- * This function must be provided by the target, which should create
89
- * the target-specific DisasContext, and then invoke translator_loop.
90
- */
91
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
92
- vaddr pc, void *host_pc);
93
-
46
/**
94
/**
47
* DisasJumpType:
95
* DisasJumpType:
96
* @DISAS_NEXT: Next instruction in program order.
97
diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
98
index XXXXXXX..XXXXXXX 100644
99
--- a/include/hw/core/tcg-cpu-ops.h
100
+++ b/include/hw/core/tcg-cpu-ops.h
101
@@ -XXX,XX +XXX,XX @@ struct TCGCPUOps {
102
* Called when the first CPU is realized.
103
*/
104
void (*initialize)(void);
105
+ /**
106
+ * @translate_code: Translate guest instructions to TCGOps
107
+ * @cpu: cpu context
108
+ * @tb: translation block
109
+ * @max_insns: max number of instructions to translate
110
+ * @pc: guest virtual program counter address
111
+ * @host_pc: host physical program counter address
112
+ *
113
+ * This function must be provided by the target, which should create
114
+ * the target-specific DisasContext, and then invoke translator_loop.
115
+ */
116
+ void (*translate_code)(CPUState *cpu, TranslationBlock *tb,
117
+ int *max_insns, vaddr pc, void *host_pc);
118
/**
119
* @synchronize_from_tb: Synchronize state from a TCG #TranslationBlock
120
*
121
diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
122
index XXXXXXX..XXXXXXX 100644
123
--- a/target/alpha/cpu.h
124
+++ b/target/alpha/cpu.h
125
@@ -XXX,XX +XXX,XX @@ enum {
126
};
127
128
void alpha_translate_init(void);
129
+void alpha_translate_code(CPUState *cs, TranslationBlock *tb,
130
+ int *max_insns, vaddr pc, void *host_pc);
131
132
#define CPU_RESOLVING_TYPE TYPE_ALPHA_CPU
133
134
diff --git a/target/arm/internals.h b/target/arm/internals.h
135
index XXXXXXX..XXXXXXX 100644
136
--- a/target/arm/internals.h
137
+++ b/target/arm/internals.h
138
@@ -XXX,XX +XXX,XX @@ void init_cpreg_list(ARMCPU *cpu);
139
140
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu);
141
void arm_translate_init(void);
142
+void arm_translate_code(CPUState *cs, TranslationBlock *tb,
143
+ int *max_insns, vaddr pc, void *host_pc);
144
145
void arm_cpu_register_gdb_commands(ARMCPU *cpu);
146
void aarch64_cpu_register_gdb_commands(ARMCPU *cpu, GString *,
147
diff --git a/target/avr/cpu.h b/target/avr/cpu.h
148
index XXXXXXX..XXXXXXX 100644
149
--- a/target/avr/cpu.h
150
+++ b/target/avr/cpu.h
151
@@ -XXX,XX +XXX,XX @@ static inline void set_avr_feature(CPUAVRState *env, int feature)
152
}
153
154
void avr_cpu_tcg_init(void);
155
+void avr_cpu_translate_code(CPUState *cs, TranslationBlock *tb,
156
+ int *max_insns, vaddr pc, void *host_pc);
157
158
int cpu_avr_exec(CPUState *cpu);
159
160
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
161
index XXXXXXX..XXXXXXX 100644
162
--- a/target/hexagon/cpu.h
163
+++ b/target/hexagon/cpu.h
164
@@ -XXX,XX +XXX,XX @@ static inline void cpu_get_tb_cpu_state(CPUHexagonState *env, vaddr *pc,
165
typedef HexagonCPU ArchCPU;
166
167
void hexagon_translate_init(void);
168
+void hexagon_translate_code(CPUState *cs, TranslationBlock *tb,
169
+ int *max_insns, vaddr pc, void *host_pc);
170
171
#include "exec/cpu-all.h"
172
173
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
174
index XXXXXXX..XXXXXXX 100644
175
--- a/target/hppa/cpu.h
176
+++ b/target/hppa/cpu.h
177
@@ -XXX,XX +XXX,XX @@ static inline int HPPA_BTLB_ENTRIES(CPUHPPAState *env)
178
}
179
180
void hppa_translate_init(void);
181
+void hppa_translate_code(CPUState *cs, TranslationBlock *tb,
182
+ int *max_insns, vaddr pc, void *host_pc);
183
184
#define CPU_RESOLVING_TYPE TYPE_HPPA_CPU
185
186
diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h
187
index XXXXXXX..XXXXXXX 100644
188
--- a/target/i386/tcg/helper-tcg.h
189
+++ b/target/i386/tcg/helper-tcg.h
190
@@ -XXX,XX +XXX,XX @@ static inline target_long lshift(target_long x, int n)
191
192
/* translate.c */
193
void tcg_x86_init(void);
194
+void x86_translate_code(CPUState *cs, TranslationBlock *tb,
195
+ int *max_insns, vaddr pc, void *host_pc);
196
197
/* excp_helper.c */
198
G_NORETURN void raise_exception(CPUX86State *env, int exception_index);
199
diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h
200
index XXXXXXX..XXXXXXX 100644
201
--- a/target/loongarch/internals.h
202
+++ b/target/loongarch/internals.h
203
@@ -XXX,XX +XXX,XX @@
204
#define TARGET_VIRT_MASK MAKE_64BIT_MASK(0, TARGET_VIRT_ADDR_SPACE_BITS)
205
206
void loongarch_translate_init(void);
207
+void loongarch_translate_code(CPUState *cs, TranslationBlock *tb,
208
+ int *max_insns, vaddr pc, void *host_pc);
209
210
void G_NORETURN do_raise_exception(CPULoongArchState *env,
211
uint32_t exception,
212
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
213
index XXXXXXX..XXXXXXX 100644
214
--- a/target/m68k/cpu.h
215
+++ b/target/m68k/cpu.h
216
@@ -XXX,XX +XXX,XX @@ int m68k_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
217
int m68k_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
218
219
void m68k_tcg_init(void);
220
+void m68k_translate_code(CPUState *cs, TranslationBlock *tb,
221
+ int *max_insns, vaddr pc, void *host_pc);
222
void m68k_cpu_init_gdb(M68kCPU *cpu);
223
uint32_t cpu_m68k_get_ccr(CPUM68KState *env);
224
void cpu_m68k_set_ccr(CPUM68KState *env, uint32_t);
225
diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
226
index XXXXXXX..XXXXXXX 100644
227
--- a/target/microblaze/cpu.h
228
+++ b/target/microblaze/cpu.h
229
@@ -XXX,XX +XXX,XX @@ static inline void mb_cpu_write_msr(CPUMBState *env, uint32_t val)
230
}
231
232
void mb_tcg_init(void);
233
+void mb_translate_code(CPUState *cs, TranslationBlock *tb,
234
+ int *max_insns, vaddr pc, void *host_pc);
235
236
#define CPU_RESOLVING_TYPE TYPE_MICROBLAZE_CPU
237
238
diff --git a/target/mips/tcg/tcg-internal.h b/target/mips/tcg/tcg-internal.h
239
index XXXXXXX..XXXXXXX 100644
240
--- a/target/mips/tcg/tcg-internal.h
241
+++ b/target/mips/tcg/tcg-internal.h
242
@@ -XXX,XX +XXX,XX @@
243
#include "cpu.h"
244
245
void mips_tcg_init(void);
246
+void mips_translate_code(CPUState *cs, TranslationBlock *tb,
247
+ int *max_insns, vaddr pc, void *host_pc);
248
249
void mips_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb);
250
G_NORETURN void mips_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
251
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
252
index XXXXXXX..XXXXXXX 100644
253
--- a/target/openrisc/cpu.h
254
+++ b/target/openrisc/cpu.h
255
@@ -XXX,XX +XXX,XX @@ void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
256
int openrisc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
257
int openrisc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
258
void openrisc_translate_init(void);
259
+void openrisc_translate_code(CPUState *cs, TranslationBlock *tb,
260
+ int *max_insns, vaddr pc, void *host_pc);
261
int print_insn_or1k(bfd_vma addr, disassemble_info *info);
262
263
#ifndef CONFIG_USER_ONLY
264
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
265
index XXXXXXX..XXXXXXX 100644
266
--- a/target/ppc/cpu.h
267
+++ b/target/ppc/cpu.h
268
@@ -XXX,XX +XXX,XX @@ extern const VMStateDescription vmstate_ppc_cpu;
269
270
/*****************************************************************************/
271
void ppc_translate_init(void);
272
+void ppc_translate_code(CPUState *cs, TranslationBlock *tb,
273
+ int *max_insns, vaddr pc, void *host_pc);
274
275
#if !defined(CONFIG_USER_ONLY)
276
void ppc_store_sdr1(CPUPPCState *env, target_ulong value);
277
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
278
index XXXXXXX..XXXXXXX 100644
279
--- a/target/riscv/cpu.h
280
+++ b/target/riscv/cpu.h
281
@@ -XXX,XX +XXX,XX @@ RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit);
282
void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv, bool virt_en);
283
284
void riscv_translate_init(void);
285
+void riscv_translate_code(CPUState *cs, TranslationBlock *tb,
286
+ int *max_insns, vaddr pc, void *host_pc);
287
+
288
G_NORETURN void riscv_raise_exception(CPURISCVState *env,
289
uint32_t exception, uintptr_t pc);
290
291
diff --git a/target/rx/cpu.h b/target/rx/cpu.h
292
index XXXXXXX..XXXXXXX 100644
293
--- a/target/rx/cpu.h
294
+++ b/target/rx/cpu.h
295
@@ -XXX,XX +XXX,XX @@ int rx_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
296
int rx_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
297
298
void rx_translate_init(void);
299
+void rx_translate_code(CPUState *cs, TranslationBlock *tb,
300
+ int *max_insns, vaddr pc, void *host_pc);
301
void rx_cpu_unpack_psw(CPURXState *env, uint32_t psw, int rte);
302
303
#include "exec/cpu-all.h"
304
diff --git a/target/s390x/s390x-internal.h b/target/s390x/s390x-internal.h
305
index XXXXXXX..XXXXXXX 100644
306
--- a/target/s390x/s390x-internal.h
307
+++ b/target/s390x/s390x-internal.h
308
@@ -XXX,XX +XXX,XX @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3,
309
310
/* translate.c */
311
void s390x_translate_init(void);
312
+void s390x_translate_code(CPUState *cs, TranslationBlock *tb,
313
+ int *max_insns, vaddr pc, void *host_pc);
314
void s390x_restore_state_to_opc(CPUState *cs,
315
const TranslationBlock *tb,
316
const uint64_t *data);
317
diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
318
index XXXXXXX..XXXXXXX 100644
319
--- a/target/sh4/cpu.h
320
+++ b/target/sh4/cpu.h
321
@@ -XXX,XX +XXX,XX @@ G_NORETURN void superh_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
322
uintptr_t retaddr);
323
324
void sh4_translate_init(void);
325
+void sh4_translate_code(CPUState *cs, TranslationBlock *tb,
326
+ int *max_insns, vaddr pc, void *host_pc);
327
328
#if !defined(CONFIG_USER_ONLY)
329
hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
330
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
331
index XXXXXXX..XXXXXXX 100644
332
--- a/target/sparc/cpu.h
333
+++ b/target/sparc/cpu.h
334
@@ -XXX,XX +XXX,XX @@ int sparc_cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
335
336
/* translate.c */
337
void sparc_tcg_init(void);
338
+void sparc_translate_code(CPUState *cs, TranslationBlock *tb,
339
+ int *max_insns, vaddr pc, void *host_pc);
340
341
/* fop_helper.c */
342
target_ulong cpu_get_fsr(CPUSPARCState *);
343
diff --git a/target/tricore/cpu.h b/target/tricore/cpu.h
344
index XXXXXXX..XXXXXXX 100644
345
--- a/target/tricore/cpu.h
346
+++ b/target/tricore/cpu.h
347
@@ -XXX,XX +XXX,XX @@ FIELD(TB_FLAGS, PRIV, 0, 2)
348
349
void cpu_state_reset(CPUTriCoreState *s);
350
void tricore_tcg_init(void);
351
+void tricore_translate_code(CPUState *cs, TranslationBlock *tb,
352
+ int *max_insns, vaddr pc, void *host_pc);
353
354
static inline void cpu_get_tb_cpu_state(CPUTriCoreState *env, vaddr *pc,
355
uint64_t *cs_base, uint32_t *flags)
356
diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
357
index XXXXXXX..XXXXXXX 100644
358
--- a/target/xtensa/cpu.h
359
+++ b/target/xtensa/cpu.h
360
@@ -XXX,XX +XXX,XX @@ G_NORETURN void xtensa_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
361
362
void xtensa_collect_sr_names(const XtensaConfig *config);
363
void xtensa_translate_init(void);
364
+void xtensa_translate_code(CPUState *cs, TranslationBlock *tb,
365
+ int *max_insns, vaddr pc, void *host_pc);
366
void **xtensa_get_regfile_by_name(const char *name, int entries, int bits);
367
void xtensa_breakpoint_handler(CPUState *cs);
368
void xtensa_register_core(XtensaConfigList *node);
369
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
370
index XXXXXXX..XXXXXXX 100644
371
--- a/accel/tcg/cpu-exec.c
372
+++ b/accel/tcg/cpu-exec.c
373
@@ -XXX,XX +XXX,XX @@ bool tcg_exec_realizefn(CPUState *cpu, Error **errp)
374
375
if (!tcg_target_initialized) {
376
/* Check mandatory TCGCPUOps handlers */
377
+ const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
378
#ifndef CONFIG_USER_ONLY
379
- assert(cpu->cc->tcg_ops->cpu_exec_halt);
380
- assert(cpu->cc->tcg_ops->cpu_exec_interrupt);
381
+ assert(tcg_ops->cpu_exec_halt);
382
+ assert(tcg_ops->cpu_exec_interrupt);
383
#endif /* !CONFIG_USER_ONLY */
384
- cpu->cc->tcg_ops->initialize();
385
+ assert(tcg_ops->translate_code);
386
+ tcg_ops->initialize();
387
tcg_target_initialized = true;
388
}
389
390
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
391
index XXXXXXX..XXXXXXX 100644
392
--- a/accel/tcg/translate-all.c
393
+++ b/accel/tcg/translate-all.c
394
@@ -XXX,XX +XXX,XX @@ static int setjmp_gen_code(CPUArchState *env, TranslationBlock *tb,
395
396
tcg_func_start(tcg_ctx);
397
398
- tcg_ctx->cpu = env_cpu(env);
399
- gen_intermediate_code(env_cpu(env), tb, max_insns, pc, host_pc);
400
+ CPUState *cs = env_cpu(env);
401
+ tcg_ctx->cpu = cs;
402
+ cs->cc->tcg_ops->translate_code(cs, tb, max_insns, pc, host_pc);
403
+
404
assert(tb->size != 0);
405
tcg_ctx->cpu = NULL;
406
*max_insns = tb->icount;
407
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
408
/*
409
* Overflow of code_gen_buffer, or the current slice of it.
410
*
411
- * TODO: We don't need to re-do gen_intermediate_code, nor
412
+ * TODO: We don't need to re-do tcg_ops->translate_code, nor
413
* should we re-do the tcg optimization currently hidden
414
* inside tcg_gen_code. All that should be required is to
415
* flush the TBs, allocate a new TB, re-initialize it per
416
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
417
index XXXXXXX..XXXXXXX 100644
418
--- a/target/alpha/cpu.c
419
+++ b/target/alpha/cpu.c
420
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps alpha_sysemu_ops = {
421
422
static const TCGCPUOps alpha_tcg_ops = {
423
.initialize = alpha_translate_init,
424
+ .translate_code = alpha_translate_code,
425
.synchronize_from_tb = alpha_cpu_synchronize_from_tb,
426
.restore_state_to_opc = alpha_restore_state_to_opc,
427
48
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
428
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
49
index XXXXXXX..XXXXXXX 100644
429
index XXXXXXX..XXXXXXX 100644
50
--- a/target/alpha/translate.c
430
--- a/target/alpha/translate.c
51
+++ b/target/alpha/translate.c
431
+++ b/target/alpha/translate.c
52
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps alpha_tr_ops = {
432
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps alpha_tr_ops = {
53
};
433
.tb_stop = alpha_tr_tb_stop,
54
434
};
55
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
435
56
- target_ulong pc, void *host_pc)
436
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
57
+ vaddr pc, void *host_pc)
437
- vaddr pc, void *host_pc)
438
+void alpha_translate_code(CPUState *cpu, TranslationBlock *tb,
439
+ int *max_insns, vaddr pc, void *host_pc)
58
{
440
{
59
DisasContext dc;
441
DisasContext dc;
60
translator_loop(cpu, tb, max_insns, pc, host_pc, &alpha_tr_ops, &dc.base);
442
translator_loop(cpu, tb, max_insns, pc, host_pc, &alpha_tr_ops, &dc.base);
443
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
444
index XXXXXXX..XXXXXXX 100644
445
--- a/target/arm/cpu.c
446
+++ b/target/arm/cpu.c
447
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps arm_sysemu_ops = {
448
#ifdef CONFIG_TCG
449
static const TCGCPUOps arm_tcg_ops = {
450
.initialize = arm_translate_init,
451
+ .translate_code = arm_translate_code,
452
.synchronize_from_tb = arm_cpu_synchronize_from_tb,
453
.debug_excp_handler = arm_debug_excp_handler,
454
.restore_state_to_opc = arm_restore_state_to_opc,
455
diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c
456
index XXXXXXX..XXXXXXX 100644
457
--- a/target/arm/tcg/cpu-v7m.c
458
+++ b/target/arm/tcg/cpu-v7m.c
459
@@ -XXX,XX +XXX,XX @@ static void cortex_m55_initfn(Object *obj)
460
461
static const TCGCPUOps arm_v7m_tcg_ops = {
462
.initialize = arm_translate_init,
463
+ .translate_code = arm_translate_code,
464
.synchronize_from_tb = arm_cpu_synchronize_from_tb,
465
.debug_excp_handler = arm_debug_excp_handler,
466
.restore_state_to_opc = arm_restore_state_to_opc,
61
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
467
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
62
index XXXXXXX..XXXXXXX 100644
468
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/tcg/translate.c
469
--- a/target/arm/tcg/translate.c
64
+++ b/target/arm/tcg/translate.c
470
+++ b/target/arm/tcg/translate.c
65
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps thumb_translator_ops = {
471
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps thumb_translator_ops = {
66
472
.tb_stop = arm_tr_tb_stop,
67
/* generate intermediate code for basic block 'tb'. */
473
};
68
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
474
69
- target_ulong pc, void *host_pc)
475
-/* generate intermediate code for basic block 'tb'. */
70
+ vaddr pc, void *host_pc)
476
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
477
- vaddr pc, void *host_pc)
478
+void arm_translate_code(CPUState *cpu, TranslationBlock *tb,
479
+ int *max_insns, vaddr pc, void *host_pc)
71
{
480
{
72
DisasContext dc = { };
481
DisasContext dc = { };
73
const TranslatorOps *ops = &arm_translator_ops;
482
const TranslatorOps *ops = &arm_translator_ops;
483
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
484
index XXXXXXX..XXXXXXX 100644
485
--- a/target/avr/cpu.c
486
+++ b/target/avr/cpu.c
487
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps avr_sysemu_ops = {
488
489
static const TCGCPUOps avr_tcg_ops = {
490
.initialize = avr_cpu_tcg_init,
491
+ .translate_code = avr_cpu_translate_code,
492
.synchronize_from_tb = avr_cpu_synchronize_from_tb,
493
.restore_state_to_opc = avr_restore_state_to_opc,
494
.cpu_exec_interrupt = avr_cpu_exec_interrupt,
74
diff --git a/target/avr/translate.c b/target/avr/translate.c
495
diff --git a/target/avr/translate.c b/target/avr/translate.c
75
index XXXXXXX..XXXXXXX 100644
496
index XXXXXXX..XXXXXXX 100644
76
--- a/target/avr/translate.c
497
--- a/target/avr/translate.c
77
+++ b/target/avr/translate.c
498
+++ b/target/avr/translate.c
499
@@ -XXX,XX +XXX,XX @@ static bool trans_WDR(DisasContext *ctx, arg_WDR *a)
500
*
501
* - translate()
502
* - canonicalize_skip()
503
- * - gen_intermediate_code()
504
+ * - translate_code()
505
* - restore_state_to_opc()
506
*
507
*/
78
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps avr_tr_ops = {
508
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps avr_tr_ops = {
79
};
509
.tb_stop = avr_tr_tb_stop,
80
510
};
81
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
511
82
- target_ulong pc, void *host_pc)
512
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
83
+ vaddr pc, void *host_pc)
513
- vaddr pc, void *host_pc)
514
+void avr_cpu_translate_code(CPUState *cs, TranslationBlock *tb,
515
+ int *max_insns, vaddr pc, void *host_pc)
84
{
516
{
85
DisasContext dc = { };
517
DisasContext dc = { };
86
translator_loop(cs, tb, max_insns, pc, host_pc, &avr_tr_ops, &dc.base);
518
translator_loop(cs, tb, max_insns, pc, host_pc, &avr_tr_ops, &dc.base);
87
diff --git a/target/cris/translate.c b/target/cris/translate.c
519
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
88
index XXXXXXX..XXXXXXX 100644
520
index XXXXXXX..XXXXXXX 100644
89
--- a/target/cris/translate.c
521
--- a/target/hexagon/cpu.c
90
+++ b/target/cris/translate.c
522
+++ b/target/hexagon/cpu.c
91
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps cris_tr_ops = {
523
@@ -XXX,XX +XXX,XX @@ static void hexagon_cpu_init(Object *obj)
92
};
524
93
525
static const TCGCPUOps hexagon_tcg_ops = {
94
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
526
.initialize = hexagon_translate_init,
95
- target_ulong pc, void *host_pc)
527
+ .translate_code = hexagon_translate_code,
96
+ vaddr pc, void *host_pc)
528
.synchronize_from_tb = hexagon_cpu_synchronize_from_tb,
97
{
529
.restore_state_to_opc = hexagon_restore_state_to_opc,
98
DisasContext dc;
530
};
99
translator_loop(cs, tb, max_insns, pc, host_pc, &cris_tr_ops, &dc.base);
100
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
531
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
101
index XXXXXXX..XXXXXXX 100644
532
index XXXXXXX..XXXXXXX 100644
102
--- a/target/hexagon/translate.c
533
--- a/target/hexagon/translate.c
103
+++ b/target/hexagon/translate.c
534
+++ b/target/hexagon/translate.c
104
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps hexagon_tr_ops = {
535
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps hexagon_tr_ops = {
105
};
536
.tb_stop = hexagon_tr_tb_stop,
106
537
};
107
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
538
108
- target_ulong pc, void *host_pc)
539
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
109
+ vaddr pc, void *host_pc)
540
- vaddr pc, void *host_pc)
541
+void hexagon_translate_code(CPUState *cs, TranslationBlock *tb,
542
+ int *max_insns, vaddr pc, void *host_pc)
110
{
543
{
111
DisasContext ctx;
544
DisasContext ctx;
545
546
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
547
index XXXXXXX..XXXXXXX 100644
548
--- a/target/hppa/cpu.c
549
+++ b/target/hppa/cpu.c
550
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps hppa_sysemu_ops = {
551
552
static const TCGCPUOps hppa_tcg_ops = {
553
.initialize = hppa_translate_init,
554
+ .translate_code = hppa_translate_code,
555
.synchronize_from_tb = hppa_cpu_synchronize_from_tb,
556
.restore_state_to_opc = hppa_restore_state_to_opc,
112
557
113
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
558
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
114
index XXXXXXX..XXXXXXX 100644
559
index XXXXXXX..XXXXXXX 100644
115
--- a/target/hppa/translate.c
560
--- a/target/hppa/translate.c
116
+++ b/target/hppa/translate.c
561
+++ b/target/hppa/translate.c
117
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps hppa_tr_ops = {
562
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps hppa_tr_ops = {
118
};
563
#endif
119
564
};
120
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
565
121
- target_ulong pc, void *host_pc)
566
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
122
+ vaddr pc, void *host_pc)
567
- vaddr pc, void *host_pc)
123
{
568
+void hppa_translate_code(CPUState *cs, TranslationBlock *tb,
124
DisasContext ctx;
569
+ int *max_insns, vaddr pc, void *host_pc)
570
{
571
DisasContext ctx = { };
125
translator_loop(cs, tb, max_insns, pc, host_pc, &hppa_tr_ops, &ctx.base);
572
translator_loop(cs, tb, max_insns, pc, host_pc, &hppa_tr_ops, &ctx.base);
573
diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c
574
index XXXXXXX..XXXXXXX 100644
575
--- a/target/i386/tcg/tcg-cpu.c
576
+++ b/target/i386/tcg/tcg-cpu.c
577
@@ -XXX,XX +XXX,XX @@ static bool x86_debug_check_breakpoint(CPUState *cs)
578
579
static const TCGCPUOps x86_tcg_ops = {
580
.initialize = tcg_x86_init,
581
+ .translate_code = x86_translate_code,
582
.synchronize_from_tb = x86_cpu_synchronize_from_tb,
583
.restore_state_to_opc = x86_restore_state_to_opc,
584
.cpu_exec_enter = x86_cpu_exec_enter,
126
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
585
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
127
index XXXXXXX..XXXXXXX 100644
586
index XXXXXXX..XXXXXXX 100644
128
--- a/target/i386/tcg/translate.c
587
--- a/target/i386/tcg/translate.c
129
+++ b/target/i386/tcg/translate.c
588
+++ b/target/i386/tcg/translate.c
130
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps i386_tr_ops = {
589
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps i386_tr_ops = {
131
590
.tb_stop = i386_tr_tb_stop,
132
/* generate intermediate code for basic block 'tb'. */
591
};
133
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
592
134
- target_ulong pc, void *host_pc)
593
-/* generate intermediate code for basic block 'tb'. */
135
+ vaddr pc, void *host_pc)
594
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
595
- vaddr pc, void *host_pc)
596
+void x86_translate_code(CPUState *cpu, TranslationBlock *tb,
597
+ int *max_insns, vaddr pc, void *host_pc)
136
{
598
{
137
DisasContext dc;
599
DisasContext dc;
600
601
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
602
index XXXXXXX..XXXXXXX 100644
603
--- a/target/loongarch/cpu.c
604
+++ b/target/loongarch/cpu.c
605
@@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags)
606
607
static const TCGCPUOps loongarch_tcg_ops = {
608
.initialize = loongarch_translate_init,
609
+ .translate_code = loongarch_translate_code,
610
.synchronize_from_tb = loongarch_cpu_synchronize_from_tb,
611
.restore_state_to_opc = loongarch_restore_state_to_opc,
138
612
139
diff --git a/target/loongarch/tcg/translate.c b/target/loongarch/tcg/translate.c
613
diff --git a/target/loongarch/tcg/translate.c b/target/loongarch/tcg/translate.c
140
index XXXXXXX..XXXXXXX 100644
614
index XXXXXXX..XXXXXXX 100644
141
--- a/target/loongarch/tcg/translate.c
615
--- a/target/loongarch/tcg/translate.c
142
+++ b/target/loongarch/tcg/translate.c
616
+++ b/target/loongarch/tcg/translate.c
143
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps loongarch_tr_ops = {
617
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps loongarch_tr_ops = {
144
};
618
.tb_stop = loongarch_tr_tb_stop,
145
619
};
146
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
620
147
- target_ulong pc, void *host_pc)
621
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
148
+ vaddr pc, void *host_pc)
622
- vaddr pc, void *host_pc)
623
+void loongarch_translate_code(CPUState *cs, TranslationBlock *tb,
624
+ int *max_insns, vaddr pc, void *host_pc)
149
{
625
{
150
DisasContext ctx;
626
DisasContext ctx;
151
627
628
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
629
index XXXXXXX..XXXXXXX 100644
630
--- a/target/m68k/cpu.c
631
+++ b/target/m68k/cpu.c
632
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps m68k_sysemu_ops = {
633
634
static const TCGCPUOps m68k_tcg_ops = {
635
.initialize = m68k_tcg_init,
636
+ .translate_code = m68k_translate_code,
637
.restore_state_to_opc = m68k_restore_state_to_opc,
638
639
#ifndef CONFIG_USER_ONLY
152
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
640
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
153
index XXXXXXX..XXXXXXX 100644
641
index XXXXXXX..XXXXXXX 100644
154
--- a/target/m68k/translate.c
642
--- a/target/m68k/translate.c
155
+++ b/target/m68k/translate.c
643
+++ b/target/m68k/translate.c
156
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps m68k_tr_ops = {
644
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps m68k_tr_ops = {
157
};
645
.tb_stop = m68k_tr_tb_stop,
158
646
};
159
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
647
160
- target_ulong pc, void *host_pc)
648
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
161
+ vaddr pc, void *host_pc)
649
- vaddr pc, void *host_pc)
650
+void m68k_translate_code(CPUState *cpu, TranslationBlock *tb,
651
+ int *max_insns, vaddr pc, void *host_pc)
162
{
652
{
163
DisasContext dc;
653
DisasContext dc;
164
translator_loop(cpu, tb, max_insns, pc, host_pc, &m68k_tr_ops, &dc.base);
654
translator_loop(cpu, tb, max_insns, pc, host_pc, &m68k_tr_ops, &dc.base);
655
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
656
index XXXXXXX..XXXXXXX 100644
657
--- a/target/microblaze/cpu.c
658
+++ b/target/microblaze/cpu.c
659
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps mb_sysemu_ops = {
660
661
static const TCGCPUOps mb_tcg_ops = {
662
.initialize = mb_tcg_init,
663
+ .translate_code = mb_translate_code,
664
.synchronize_from_tb = mb_cpu_synchronize_from_tb,
665
.restore_state_to_opc = mb_restore_state_to_opc,
666
165
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
667
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
166
index XXXXXXX..XXXXXXX 100644
668
index XXXXXXX..XXXXXXX 100644
167
--- a/target/microblaze/translate.c
669
--- a/target/microblaze/translate.c
168
+++ b/target/microblaze/translate.c
670
+++ b/target/microblaze/translate.c
169
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps mb_tr_ops = {
671
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps mb_tr_ops = {
170
};
672
.tb_stop = mb_tr_tb_stop,
171
673
};
172
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
674
173
- target_ulong pc, void *host_pc)
675
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
174
+ vaddr pc, void *host_pc)
676
- vaddr pc, void *host_pc)
677
+void mb_translate_code(CPUState *cpu, TranslationBlock *tb,
678
+ int *max_insns, vaddr pc, void *host_pc)
175
{
679
{
176
DisasContext dc;
680
DisasContext dc;
177
translator_loop(cpu, tb, max_insns, pc, host_pc, &mb_tr_ops, &dc.base);
681
translator_loop(cpu, tb, max_insns, pc, host_pc, &mb_tr_ops, &dc.base);
682
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
683
index XXXXXXX..XXXXXXX 100644
684
--- a/target/mips/cpu.c
685
+++ b/target/mips/cpu.c
686
@@ -XXX,XX +XXX,XX @@ static const Property mips_cpu_properties[] = {
687
#include "hw/core/tcg-cpu-ops.h"
688
static const TCGCPUOps mips_tcg_ops = {
689
.initialize = mips_tcg_init,
690
+ .translate_code = mips_translate_code,
691
.synchronize_from_tb = mips_cpu_synchronize_from_tb,
692
.restore_state_to_opc = mips_restore_state_to_opc,
693
178
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
694
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
179
index XXXXXXX..XXXXXXX 100644
695
index XXXXXXX..XXXXXXX 100644
180
--- a/target/mips/tcg/translate.c
696
--- a/target/mips/tcg/translate.c
181
+++ b/target/mips/tcg/translate.c
697
+++ b/target/mips/tcg/translate.c
182
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps mips_tr_ops = {
698
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps mips_tr_ops = {
183
};
699
.tb_stop = mips_tr_tb_stop,
184
700
};
185
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
701
186
- target_ulong pc, void *host_pc)
702
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
187
+ vaddr pc, void *host_pc)
703
- vaddr pc, void *host_pc)
704
+void mips_translate_code(CPUState *cs, TranslationBlock *tb,
705
+ int *max_insns, vaddr pc, void *host_pc)
188
{
706
{
189
DisasContext ctx;
707
DisasContext ctx;
190
708
191
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
709
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
192
index XXXXXXX..XXXXXXX 100644
710
index XXXXXXX..XXXXXXX 100644
193
--- a/target/nios2/translate.c
711
--- a/target/openrisc/cpu.c
194
+++ b/target/nios2/translate.c
712
+++ b/target/openrisc/cpu.c
195
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps nios2_tr_ops = {
713
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps openrisc_sysemu_ops = {
196
};
714
197
715
static const TCGCPUOps openrisc_tcg_ops = {
198
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
716
.initialize = openrisc_translate_init,
199
- target_ulong pc, void *host_pc)
717
+ .translate_code = openrisc_translate_code,
200
+ vaddr pc, void *host_pc)
718
.synchronize_from_tb = openrisc_cpu_synchronize_from_tb,
201
{
719
.restore_state_to_opc = openrisc_restore_state_to_opc,
202
DisasContext dc;
720
203
translator_loop(cs, tb, max_insns, pc, host_pc, &nios2_tr_ops, &dc.base);
204
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
721
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
205
index XXXXXXX..XXXXXXX 100644
722
index XXXXXXX..XXXXXXX 100644
206
--- a/target/openrisc/translate.c
723
--- a/target/openrisc/translate.c
207
+++ b/target/openrisc/translate.c
724
+++ b/target/openrisc/translate.c
208
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps openrisc_tr_ops = {
725
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps openrisc_tr_ops = {
209
};
726
.tb_stop = openrisc_tr_tb_stop,
210
727
};
211
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
728
212
- target_ulong pc, void *host_pc)
729
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
213
+ vaddr pc, void *host_pc)
730
- vaddr pc, void *host_pc)
731
+void openrisc_translate_code(CPUState *cs, TranslationBlock *tb,
732
+ int *max_insns, vaddr pc, void *host_pc)
214
{
733
{
215
DisasContext ctx;
734
DisasContext ctx;
216
735
736
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
737
index XXXXXXX..XXXXXXX 100644
738
--- a/target/ppc/cpu_init.c
739
+++ b/target/ppc/cpu_init.c
740
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps ppc_sysemu_ops = {
741
742
static const TCGCPUOps ppc_tcg_ops = {
743
.initialize = ppc_translate_init,
744
+ .translate_code = ppc_translate_code,
745
.restore_state_to_opc = ppc_restore_state_to_opc,
746
747
#ifdef CONFIG_USER_ONLY
217
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
748
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
218
index XXXXXXX..XXXXXXX 100644
749
index XXXXXXX..XXXXXXX 100644
219
--- a/target/ppc/translate.c
750
--- a/target/ppc/translate.c
220
+++ b/target/ppc/translate.c
751
+++ b/target/ppc/translate.c
221
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps ppc_tr_ops = {
752
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps ppc_tr_ops = {
222
};
753
.tb_stop = ppc_tr_tb_stop,
223
754
};
224
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
755
225
- target_ulong pc, void *host_pc)
756
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
226
+ vaddr pc, void *host_pc)
757
- vaddr pc, void *host_pc)
758
+void ppc_translate_code(CPUState *cs, TranslationBlock *tb,
759
+ int *max_insns, vaddr pc, void *host_pc)
227
{
760
{
228
DisasContext ctx;
761
DisasContext ctx;
762
763
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
764
index XXXXXXX..XXXXXXX 100644
765
--- a/target/riscv/tcg/tcg-cpu.c
766
+++ b/target/riscv/tcg/tcg-cpu.c
767
@@ -XXX,XX +XXX,XX @@ static void riscv_restore_state_to_opc(CPUState *cs,
768
769
static const TCGCPUOps riscv_tcg_ops = {
770
.initialize = riscv_translate_init,
771
+ .translate_code = riscv_translate_code,
772
.synchronize_from_tb = riscv_cpu_synchronize_from_tb,
773
.restore_state_to_opc = riscv_restore_state_to_opc,
229
774
230
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
775
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
231
index XXXXXXX..XXXXXXX 100644
776
index XXXXXXX..XXXXXXX 100644
232
--- a/target/riscv/translate.c
777
--- a/target/riscv/translate.c
233
+++ b/target/riscv/translate.c
778
+++ b/target/riscv/translate.c
234
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps riscv_tr_ops = {
779
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps riscv_tr_ops = {
235
};
780
.tb_stop = riscv_tr_tb_stop,
236
781
};
237
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
782
238
- target_ulong pc, void *host_pc)
783
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
239
+ vaddr pc, void *host_pc)
784
- vaddr pc, void *host_pc)
785
+void riscv_translate_code(CPUState *cs, TranslationBlock *tb,
786
+ int *max_insns, vaddr pc, void *host_pc)
240
{
787
{
241
DisasContext ctx;
788
DisasContext ctx;
242
789
790
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
791
index XXXXXXX..XXXXXXX 100644
792
--- a/target/rx/cpu.c
793
+++ b/target/rx/cpu.c
794
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps rx_sysemu_ops = {
795
796
static const TCGCPUOps rx_tcg_ops = {
797
.initialize = rx_translate_init,
798
+ .translate_code = rx_translate_code,
799
.synchronize_from_tb = rx_cpu_synchronize_from_tb,
800
.restore_state_to_opc = rx_restore_state_to_opc,
801
.tlb_fill = rx_cpu_tlb_fill,
243
diff --git a/target/rx/translate.c b/target/rx/translate.c
802
diff --git a/target/rx/translate.c b/target/rx/translate.c
244
index XXXXXXX..XXXXXXX 100644
803
index XXXXXXX..XXXXXXX 100644
245
--- a/target/rx/translate.c
804
--- a/target/rx/translate.c
246
+++ b/target/rx/translate.c
805
+++ b/target/rx/translate.c
247
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps rx_tr_ops = {
806
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps rx_tr_ops = {
248
};
807
.tb_stop = rx_tr_tb_stop,
249
808
};
250
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
809
251
- target_ulong pc, void *host_pc)
810
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
252
+ vaddr pc, void *host_pc)
811
- vaddr pc, void *host_pc)
812
+void rx_translate_code(CPUState *cs, TranslationBlock *tb,
813
+ int *max_insns, vaddr pc, void *host_pc)
253
{
814
{
254
DisasContext dc;
815
DisasContext dc;
255
816
817
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
818
index XXXXXXX..XXXXXXX 100644
819
--- a/target/s390x/cpu.c
820
+++ b/target/s390x/cpu.c
821
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUS390XState *env, vaddr *pc,
822
823
static const TCGCPUOps s390_tcg_ops = {
824
.initialize = s390x_translate_init,
825
+ .translate_code = s390x_translate_code,
826
.restore_state_to_opc = s390x_restore_state_to_opc,
827
828
#ifdef CONFIG_USER_ONLY
256
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
829
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
257
index XXXXXXX..XXXXXXX 100644
830
index XXXXXXX..XXXXXXX 100644
258
--- a/target/s390x/tcg/translate.c
831
--- a/target/s390x/tcg/translate.c
259
+++ b/target/s390x/tcg/translate.c
832
+++ b/target/s390x/tcg/translate.c
260
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps s390x_tr_ops = {
833
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps s390x_tr_ops = {
261
};
834
.disas_log = s390x_tr_disas_log,
262
835
};
263
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
836
264
- target_ulong pc, void *host_pc)
837
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
265
+ vaddr pc, void *host_pc)
838
- vaddr pc, void *host_pc)
839
+void s390x_translate_code(CPUState *cs, TranslationBlock *tb,
840
+ int *max_insns, vaddr pc, void *host_pc)
266
{
841
{
267
DisasContext dc;
842
DisasContext dc;
843
844
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
845
index XXXXXXX..XXXXXXX 100644
846
--- a/target/sh4/cpu.c
847
+++ b/target/sh4/cpu.c
848
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps sh4_sysemu_ops = {
849
850
static const TCGCPUOps superh_tcg_ops = {
851
.initialize = sh4_translate_init,
852
+ .translate_code = sh4_translate_code,
853
.synchronize_from_tb = superh_cpu_synchronize_from_tb,
854
.restore_state_to_opc = superh_restore_state_to_opc,
268
855
269
diff --git a/target/sh4/translate.c b/target/sh4/translate.c
856
diff --git a/target/sh4/translate.c b/target/sh4/translate.c
270
index XXXXXXX..XXXXXXX 100644
857
index XXXXXXX..XXXXXXX 100644
271
--- a/target/sh4/translate.c
858
--- a/target/sh4/translate.c
272
+++ b/target/sh4/translate.c
859
+++ b/target/sh4/translate.c
273
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps sh4_tr_ops = {
860
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps sh4_tr_ops = {
274
};
861
.tb_stop = sh4_tr_tb_stop,
275
862
};
276
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
863
277
- target_ulong pc, void *host_pc)
864
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
278
+ vaddr pc, void *host_pc)
865
- vaddr pc, void *host_pc)
866
+void sh4_translate_code(CPUState *cs, TranslationBlock *tb,
867
+ int *max_insns, vaddr pc, void *host_pc)
279
{
868
{
280
DisasContext ctx;
869
DisasContext ctx;
870
871
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
872
index XXXXXXX..XXXXXXX 100644
873
--- a/target/sparc/cpu.c
874
+++ b/target/sparc/cpu.c
875
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps sparc_sysemu_ops = {
876
877
static const TCGCPUOps sparc_tcg_ops = {
878
.initialize = sparc_tcg_init,
879
+ .translate_code = sparc_translate_code,
880
.synchronize_from_tb = sparc_cpu_synchronize_from_tb,
881
.restore_state_to_opc = sparc_restore_state_to_opc,
281
882
282
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
883
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
283
index XXXXXXX..XXXXXXX 100644
884
index XXXXXXX..XXXXXXX 100644
284
--- a/target/sparc/translate.c
885
--- a/target/sparc/translate.c
285
+++ b/target/sparc/translate.c
886
+++ b/target/sparc/translate.c
286
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps sparc_tr_ops = {
887
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps sparc_tr_ops = {
287
};
888
.tb_stop = sparc_tr_tb_stop,
288
889
};
289
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
890
290
- target_ulong pc, void *host_pc)
891
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
291
+ vaddr pc, void *host_pc)
892
- vaddr pc, void *host_pc)
893
+void sparc_translate_code(CPUState *cs, TranslationBlock *tb,
894
+ int *max_insns, vaddr pc, void *host_pc)
292
{
895
{
293
DisasContext dc = {};
896
DisasContext dc = {};
294
897
898
diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c
899
index XXXXXXX..XXXXXXX 100644
900
--- a/target/tricore/cpu.c
901
+++ b/target/tricore/cpu.c
902
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps tricore_sysemu_ops = {
903
904
static const TCGCPUOps tricore_tcg_ops = {
905
.initialize = tricore_tcg_init,
906
+ .translate_code = tricore_translate_code,
907
.synchronize_from_tb = tricore_cpu_synchronize_from_tb,
908
.restore_state_to_opc = tricore_restore_state_to_opc,
909
.tlb_fill = tricore_cpu_tlb_fill,
295
diff --git a/target/tricore/translate.c b/target/tricore/translate.c
910
diff --git a/target/tricore/translate.c b/target/tricore/translate.c
296
index XXXXXXX..XXXXXXX 100644
911
index XXXXXXX..XXXXXXX 100644
297
--- a/target/tricore/translate.c
912
--- a/target/tricore/translate.c
298
+++ b/target/tricore/translate.c
913
+++ b/target/tricore/translate.c
299
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps tricore_tr_ops = {
914
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps tricore_tr_ops = {
300
915
.tb_stop = tricore_tr_tb_stop,
301
916
};
302
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
917
303
- target_ulong pc, void *host_pc)
918
-
304
+ vaddr pc, void *host_pc)
919
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
920
- vaddr pc, void *host_pc)
921
+void tricore_translate_code(CPUState *cs, TranslationBlock *tb,
922
+ int *max_insns, vaddr pc, void *host_pc)
305
{
923
{
306
DisasContext ctx;
924
DisasContext ctx;
307
translator_loop(cs, tb, max_insns, pc, host_pc,
925
translator_loop(cs, tb, max_insns, pc, host_pc,
926
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
927
index XXXXXXX..XXXXXXX 100644
928
--- a/target/xtensa/cpu.c
929
+++ b/target/xtensa/cpu.c
930
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps xtensa_sysemu_ops = {
931
932
static const TCGCPUOps xtensa_tcg_ops = {
933
.initialize = xtensa_translate_init,
934
+ .translate_code = xtensa_translate_code,
935
.debug_excp_handler = xtensa_breakpoint_handler,
936
.restore_state_to_opc = xtensa_restore_state_to_opc,
937
308
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
938
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
309
index XXXXXXX..XXXXXXX 100644
939
index XXXXXXX..XXXXXXX 100644
310
--- a/target/xtensa/translate.c
940
--- a/target/xtensa/translate.c
311
+++ b/target/xtensa/translate.c
941
+++ b/target/xtensa/translate.c
312
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps xtensa_translator_ops = {
942
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps xtensa_translator_ops = {
313
};
943
.tb_stop = xtensa_tr_tb_stop,
314
944
};
315
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
945
316
- target_ulong pc, void *host_pc)
946
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
317
+ vaddr pc, void *host_pc)
947
- vaddr pc, void *host_pc)
948
+void xtensa_translate_code(CPUState *cpu, TranslationBlock *tb,
949
+ int *max_insns, vaddr pc, void *host_pc)
318
{
950
{
319
DisasContext dc = {};
951
DisasContext dc = {};
320
translator_loop(cpu, tb, max_insns, pc, host_pc,
952
translator_loop(cpu, tb, max_insns, pc, host_pc,
321
--
953
--
322
2.34.1
954
2.43.0
955
956
diff view generated by jsdifflib