1
The following changes since commit 470dd6bd360782f5137f7e3376af6a44658eb1d3:
1
The following changes since commit aa3a285b5bc56a4208b3b57d4a55291e9c260107:
2
2
3
Merge remote-tracking branch 'remotes/stsquad/tags/pull-testing-060121-4' into staging (2021-01-06 22:18:36 +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-20210107
7
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20241224
8
8
9
for you to fetch changes up to e5e2e4c73926f6f3c1f5da24a350e4345d5ad232:
9
for you to fetch changes up to e4a8e093dc74be049f4829831dce76e5edab0003:
10
10
11
tcg: Constify TCGLabelQemuLdst.raddr (2021-01-07 05:09:42 -1000)
11
accel/tcg: Move gen_intermediate_code to TCGCPUOps.translate_core (2024-12-24 08:32:15 -0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Build fix for ppc64 centos7.
14
tcg/optimize: Remove in-flight mask data from OptContext
15
Reduce the use of scratch registers for tcg/i386.
15
fpu: Add float*_muladd_scalbn
16
Use _aligned_malloc for Win32.
16
fpu: Remove float_muladd_halve_result
17
Enable split w^x code gen buffers.
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
18
21
19
----------------------------------------------------------------
22
----------------------------------------------------------------
20
Philippe Mathieu-Daudé (1):
23
Ilya Leoshkevich (1):
21
util/oslib: Assert qemu_try_memalign() alignment is a power of 2
24
tests/tcg: Do not use inttypes.h in multiarch/system/memory.c
22
25
23
Richard Henderson (46):
26
Pierrick Bouvier (1):
24
linux-user: Conditionalize TUNSETVNETLE
27
plugins: optimize cpu_index code generation
25
tcg/i386: Adjust TCG_TARGET_HAS_MEMORY_BSWAP
26
tcg: Introduce INDEX_op_qemu_st8_i32
27
util/oslib-win32: Use _aligned_malloc for qemu_try_memalign
28
tcg: Do not flush icache for interpreter
29
util: Enhance flush_icache_range with separate data pointer
30
util: Specialize flush_idcache_range for aarch64
31
tcg: Move tcg prologue pointer out of TCGContext
32
tcg: Move tcg epilogue pointer out of TCGContext
33
tcg: Add in_code_gen_buffer
34
tcg: Introduce tcg_splitwx_to_{rx,rw}
35
tcg: Adjust TCGLabel for const
36
tcg: Adjust tcg_out_call for const
37
tcg: Adjust tcg_out_label for const
38
tcg: Adjust tcg_register_jit for const
39
tcg: Adjust tb_target_set_jmp_target for split-wx
40
tcg: Make DisasContextBase.tb const
41
tcg: Make tb arg to synchronize_from_tb const
42
tcg: Use Error with alloc_code_gen_buffer
43
tcg: Add --accel tcg,split-wx property
44
accel/tcg: Support split-wx for linux with memfd
45
accel/tcg: Support split-wx for darwin/iOS with vm_remap
46
tcg: Return the TB pointer from the rx region from exit_tb
47
tcg/i386: Support split-wx code generation
48
tcg/aarch64: Use B not BL for tcg_out_goto_long
49
tcg/aarch64: Support split-wx code generation
50
disas: Push const down through host disassembly
51
tcg/tci: Push const down through bytecode reading
52
tcg: Introduce tcg_tbrel_diff
53
tcg/ppc: Use tcg_tbrel_diff
54
tcg/ppc: Use tcg_out_mem_long to reset TCG_REG_TB
55
tcg/ppc: Support split-wx code generation
56
tcg/sparc: Use tcg_tbrel_diff
57
tcg/sparc: Support split-wx code generation
58
tcg/s390: Use tcg_tbrel_diff
59
tcg/s390: Support split-wx code generation
60
tcg/riscv: Fix branch range checks
61
tcg/riscv: Remove branch-over-branch fallback
62
tcg/riscv: Support split-wx code generation
63
accel/tcg: Add mips support to alloc_code_gen_buffer_splitwx_memfd
64
tcg/mips: Do not assert on relocation overflow
65
tcg/mips: Support split-wx code generation
66
tcg/arm: Support split-wx code generation
67
tcg: Remove TCG_TARGET_SUPPORT_MIRROR
68
tcg: Constify tcg_code_gen_epilogue
69
tcg: Constify TCGLabelQemuLdst.raddr
70
28
71
accel/tcg/tcg-runtime.h | 2 +-
29
Richard Henderson (70):
72
include/disas/dis-asm.h | 4 +-
30
tcg/optimize: Split out finish_bb, finish_ebb
73
include/disas/disas.h | 2 +-
31
tcg/optimize: Split out fold_affected_mask
74
include/exec/exec-all.h | 2 +-
32
tcg/optimize: Copy mask writeback to fold_masks
75
include/exec/gen-icount.h | 4 +-
33
tcg/optimize: Split out fold_masks_zs
76
include/exec/log.h | 2 +-
34
tcg/optimize: Augment s_mask from z_mask in fold_masks_zs
77
include/exec/translator.h | 2 +-
35
tcg/optimize: Change representation of s_mask
78
include/hw/core/cpu.h | 3 +-
36
tcg/optimize: Use finish_folding in fold_add, fold_add_vec, fold_addsub2
79
include/qemu/cacheflush.h | 15 ++-
37
tcg/optimize: Introduce const value accessors for TempOptInfo
80
include/sysemu/tcg.h | 3 +-
38
tcg/optimize: Use fold_masks_zs in fold_and
81
include/tcg/tcg-op.h | 2 +-
39
tcg/optimize: Use fold_masks_zs in fold_andc
82
include/tcg/tcg-opc.h | 5 +
40
tcg/optimize: Use fold_masks_zs in fold_bswap
83
include/tcg/tcg.h | 61 +++++++--
41
tcg/optimize: Use fold_masks_zs in fold_count_zeros
84
linux-user/ioctls.h | 2 +
42
tcg/optimize: Use fold_masks_z in fold_ctpop
85
tcg/aarch64/tcg-target.h | 3 +-
43
tcg/optimize: Use fold_and and fold_masks_z in fold_deposit
86
tcg/arm/tcg-target.h | 3 +-
44
tcg/optimize: Compute sign mask in fold_deposit
87
tcg/i386/tcg-target.h | 12 +-
45
tcg/optimize: Use finish_folding in fold_divide
88
tcg/mips/tcg-target.h | 3 +-
46
tcg/optimize: Use finish_folding in fold_dup, fold_dup2
89
tcg/ppc/tcg-target.h | 3 +-
47
tcg/optimize: Use fold_masks_s in fold_eqv
90
tcg/riscv/tcg-target.h | 3 +-
48
tcg/optimize: Use fold_masks_z in fold_extract
91
tcg/s390/tcg-target.h | 9 +-
49
tcg/optimize: Use finish_folding in fold_extract2
92
tcg/sparc/tcg-target.h | 3 +-
50
tcg/optimize: Use fold_masks_zs in fold_exts
93
tcg/tci/tcg-target.h | 7 +-
51
tcg/optimize: Use fold_masks_z in fold_extu
94
accel/tcg/cpu-exec.c | 41 +++---
52
tcg/optimize: Use fold_masks_zs in fold_movcond
95
accel/tcg/tcg-all.c | 26 +++-
53
tcg/optimize: Use finish_folding in fold_mul*
96
accel/tcg/tcg-runtime.c | 4 +-
54
tcg/optimize: Use fold_masks_s in fold_nand
97
accel/tcg/translate-all.c | 311 ++++++++++++++++++++++++++++++++++---------
55
tcg/optimize: Use fold_masks_z in fold_neg_no_const
98
accel/tcg/translator.c | 4 +-
56
tcg/optimize: Use fold_masks_s in fold_nor
99
bsd-user/main.c | 2 +-
57
tcg/optimize: Use fold_masks_s in fold_not
100
disas.c | 2 +-
58
tcg/optimize: Use fold_masks_zs in fold_or
101
disas/capstone.c | 2 +-
59
tcg/optimize: Use fold_masks_zs in fold_orc
102
linux-user/main.c | 2 +-
60
tcg/optimize: Use fold_masks_zs in fold_qemu_ld
103
softmmu/physmem.c | 2 +-
61
tcg/optimize: Return true from fold_qemu_st, fold_tcg_st
104
target/arm/cpu.c | 3 +-
62
tcg/optimize: Use finish_folding in fold_remainder
105
target/arm/translate-a64.c | 2 +-
63
tcg/optimize: Distinguish simplification in fold_setcond_zmask
106
target/avr/cpu.c | 3 +-
64
tcg/optimize: Use fold_masks_z in fold_setcond
107
target/hppa/cpu.c | 3 +-
65
tcg/optimize: Use fold_masks_s in fold_negsetcond
108
target/i386/tcg/tcg-cpu.c | 3 +-
66
tcg/optimize: Use fold_masks_z in fold_setcond2
109
target/microblaze/cpu.c | 3 +-
67
tcg/optimize: Use finish_folding in fold_cmp_vec
110
target/mips/cpu.c | 3 +-
68
tcg/optimize: Use finish_folding in fold_cmpsel_vec
111
target/riscv/cpu.c | 3 +-
69
tcg/optimize: Use fold_masks_zs in fold_sextract
112
target/rx/cpu.c | 3 +-
70
tcg/optimize: Use fold_masks_zs, fold_masks_s in fold_shift
113
target/sh4/cpu.c | 3 +-
71
tcg/optimize: Simplify sign bit test in fold_shift
114
target/sparc/cpu.c | 3 +-
72
tcg/optimize: Use finish_folding in fold_sub, fold_sub_vec
115
target/tricore/cpu.c | 2 +-
73
tcg/optimize: Use fold_masks_zs in fold_tcg_ld
116
tcg/optimize.c | 1 +
74
tcg/optimize: Use finish_folding in fold_tcg_ld_memcopy
117
tcg/tcg-op.c | 21 ++-
75
tcg/optimize: Use fold_masks_zs in fold_xor
118
tcg/tcg.c | 94 ++++++++++---
76
tcg/optimize: Use finish_folding in fold_bitsel_vec
119
tcg/tci.c | 62 +++++----
77
tcg/optimize: Use finish_folding as default in tcg_optimize
120
util/cacheflush.c | 107 ++++++++++++---
78
tcg/optimize: Remove z_mask, s_mask from OptContext
121
util/cacheinfo.c | 8 +-
79
tcg/optimize: Re-enable sign-mask optimizations
122
util/oslib-posix.c | 2 +
80
tcg/optimize: Move fold_bitsel_vec into alphabetic sort
123
util/oslib-win32.c | 12 +-
81
tcg/optimize: Move fold_cmp_vec, fold_cmpsel_vec into alphabetic sort
124
tcg/aarch64/tcg-target.c.inc | 75 ++++++-----
82
softfloat: Add float{16,32,64}_muladd_scalbn
125
tcg/arm/tcg-target.c.inc | 41 +++---
83
target/arm: Use float*_muladd_scalbn
126
tcg/i386/tcg-target.c.inc | 174 +++++++++++-------------
84
target/sparc: Use float*_muladd_scalbn
127
tcg/mips/tcg-target.c.inc | 97 ++++++--------
85
softfloat: Remove float_muladd_halve_result
128
tcg/ppc/tcg-target.c.inc | 88 ++++++------
86
softfloat: Add float_round_nearest_even_max
129
tcg/riscv/tcg-target.c.inc | 125 ++++++-----------
87
softfloat: Add float_muladd_suppress_add_product_zero
130
tcg/s390/tcg-target.c.inc | 91 ++++++-------
88
target/hexagon: Use float32_mul in helper_sfmpy
131
tcg/sparc/tcg-target.c.inc | 58 ++++----
89
target/hexagon: Use float32_muladd for helper_sffma
132
tcg/tcg-ldst.c.inc | 2 +-
90
target/hexagon: Use float32_muladd for helper_sffms
133
tcg/tcg-pool.c.inc | 6 +-
91
target/hexagon: Use float32_muladd_scalbn for helper_sffma_sc
134
tcg/tci/tcg-target.c.inc | 2 +-
92
target/hexagon: Use float32_muladd for helper_sffm[as]_lib
135
accel/tcg/trace-events | 2 +-
93
target/hexagon: Remove internal_fmafx
136
qemu-options.hx | 7 +
94
target/hexagon: Expand GEN_XF_ROUND
137
tcg/README | 5 +
95
target/hexagon: Remove Float
138
67 files changed, 1035 insertions(+), 630 deletions(-)
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
139
100
101
include/exec/translator.h | 14 -
102
include/fpu/softfloat-types.h | 2 +
103
include/fpu/softfloat.h | 14 +-
104
include/hw/core/tcg-cpu-ops.h | 13 +
105
target/alpha/cpu.h | 2 +
106
target/arm/internals.h | 2 +
107
target/avr/cpu.h | 2 +
108
target/hexagon/cpu.h | 2 +
109
target/hexagon/fma_emu.h | 3 -
110
target/hppa/cpu.h | 2 +
111
target/i386/tcg/helper-tcg.h | 2 +
112
target/loongarch/internals.h | 2 +
113
target/m68k/cpu.h | 2 +
114
target/microblaze/cpu.h | 2 +
115
target/mips/tcg/tcg-internal.h | 2 +
116
target/openrisc/cpu.h | 2 +
117
target/ppc/cpu.h | 2 +
118
target/riscv/cpu.h | 3 +
119
target/rx/cpu.h | 2 +
120
target/s390x/s390x-internal.h | 2 +
121
target/sh4/cpu.h | 2 +
122
target/sparc/cpu.h | 2 +
123
target/sparc/helper.h | 4 +-
124
target/tricore/cpu.h | 2 +
125
target/xtensa/cpu.h | 2 +
126
accel/tcg/cpu-exec.c | 8 +-
127
accel/tcg/plugin-gen.c | 9 +
128
accel/tcg/translate-all.c | 8 +-
129
fpu/softfloat.c | 63 +--
130
target/alpha/cpu.c | 1 +
131
target/alpha/translate.c | 4 +-
132
target/arm/cpu.c | 1 +
133
target/arm/tcg/cpu-v7m.c | 1 +
134
target/arm/tcg/helper-a64.c | 6 +-
135
target/arm/tcg/translate.c | 5 +-
136
target/avr/cpu.c | 1 +
137
target/avr/translate.c | 6 +-
138
target/hexagon/cpu.c | 1 +
139
target/hexagon/fma_emu.c | 496 ++++++---------------
140
target/hexagon/op_helper.c | 125 ++----
141
target/hexagon/translate.c | 4 +-
142
target/hppa/cpu.c | 1 +
143
target/hppa/translate.c | 4 +-
144
target/i386/tcg/tcg-cpu.c | 1 +
145
target/i386/tcg/translate.c | 5 +-
146
target/loongarch/cpu.c | 1 +
147
target/loongarch/tcg/translate.c | 4 +-
148
target/m68k/cpu.c | 1 +
149
target/m68k/translate.c | 4 +-
150
target/microblaze/cpu.c | 1 +
151
target/microblaze/translate.c | 4 +-
152
target/mips/cpu.c | 1 +
153
target/mips/tcg/translate.c | 4 +-
154
target/openrisc/cpu.c | 1 +
155
target/openrisc/translate.c | 4 +-
156
target/ppc/cpu_init.c | 1 +
157
target/ppc/translate.c | 4 +-
158
target/riscv/tcg/tcg-cpu.c | 1 +
159
target/riscv/translate.c | 4 +-
160
target/rx/cpu.c | 1 +
161
target/rx/translate.c | 4 +-
162
target/s390x/cpu.c | 1 +
163
target/s390x/tcg/translate.c | 4 +-
164
target/sh4/cpu.c | 1 +
165
target/sh4/translate.c | 4 +-
166
target/sparc/cpu.c | 1 +
167
target/sparc/fop_helper.c | 8 +-
168
target/sparc/translate.c | 84 ++--
169
target/tricore/cpu.c | 1 +
170
target/tricore/translate.c | 5 +-
171
target/xtensa/cpu.c | 1 +
172
target/xtensa/translate.c | 4 +-
173
tcg/optimize.c | 857 +++++++++++++++++++-----------------
174
tests/tcg/multiarch/system/memory.c | 9 +-
175
fpu/softfloat-parts.c.inc | 16 +-
176
75 files changed, 866 insertions(+), 1009 deletions(-)
diff view generated by jsdifflib
1
This is currently a no-op within tci/tcg-target.h, but
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
2
is about to be moved to a more generic location.
3
2
4
Reviewed-by: Joelle van Dyne <j@getutm.app>
3
make check-tcg fails on Fedora with the following error message:
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")
20
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
21
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
22
Message-ID: <20241010085906.226249-1-iii@linux.ibm.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
23
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
24
---
7
tcg/tcg.c | 4 ++++
25
tests/tcg/multiarch/system/memory.c | 9 ++++-----
8
1 file changed, 4 insertions(+)
26
1 file changed, 4 insertions(+), 5 deletions(-)
9
27
10
diff --git a/tcg/tcg.c b/tcg/tcg.c
28
diff --git a/tests/tcg/multiarch/system/memory.c b/tests/tcg/multiarch/system/memory.c
11
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/tcg.c
30
--- a/tests/tcg/multiarch/system/memory.c
13
+++ b/tcg/tcg.c
31
+++ b/tests/tcg/multiarch/system/memory.c
14
@@ -XXX,XX +XXX,XX @@ void tcg_prologue_init(TCGContext *s)
32
@@ -XXX,XX +XXX,XX @@
15
#endif
33
16
34
#include <stdint.h>
17
buf1 = s->code_ptr;
35
#include <stdbool.h>
18
+#ifndef CONFIG_TCG_INTERPRETER
36
-#include <inttypes.h>
19
flush_icache_range((uintptr_t)buf0, (uintptr_t)buf1);
37
#include <minilib.h>
20
+#endif
38
21
39
#ifndef CHECK_UNALIGNED
22
/* Deduct the prologue from the buffer. */
40
@@ -XXX,XX +XXX,XX @@ int main(void)
23
prologue_size = tcg_current_code_size(s);
41
int i;
24
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
42
bool ok = true;
25
return -2;
43
44
- ml_printf("Test data start: 0x%"PRIxPTR"\n", &test_data[0]);
45
- ml_printf("Test data end: 0x%"PRIxPTR"\n", &test_data[TEST_SIZE]);
46
+ ml_printf("Test data start: 0x%lx\n", (unsigned long)&test_data[0]);
47
+ ml_printf("Test data end: 0x%lx\n", (unsigned long)&test_data[TEST_SIZE]);
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);
26
}
53
}
27
54
28
+#ifndef CONFIG_TCG_INTERPRETER
55
- ml_printf("Test data read: %"PRId32"\n", test_read_count);
29
/* flush instruction cache */
56
- ml_printf("Test data write: %"PRId32"\n", test_write_count);
30
flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr);
57
+ ml_printf("Test data read: %lu\n", (unsigned long)test_read_count);
31
+#endif
58
+ ml_printf("Test data write: %lu\n", (unsigned long)test_write_count);
32
59
ml_printf("Test complete: %s\n", ok ? "PASSED" : "FAILED");
33
return tcg_current_code_size(s);
60
return ok ? 0 : -1;
34
}
61
}
35
--
62
--
36
2.25.1
63
2.43.0
37
38
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
Pass both rx and rw addresses to tb_target_set_jmp_target.
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
Reviewed-by: Joelle van Dyne <j@getutm.app>
5
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
7
---
6
tcg/aarch64/tcg-target.h | 2 +-
8
tcg/optimize.c | 47 +++++++++++++++++++++++++++++++----------------
7
tcg/arm/tcg-target.h | 2 +-
9
1 file changed, 31 insertions(+), 16 deletions(-)
8
tcg/i386/tcg-target.h | 6 +++---
9
tcg/mips/tcg-target.h | 2 +-
10
tcg/ppc/tcg-target.h | 2 +-
11
tcg/riscv/tcg-target.h | 2 +-
12
tcg/s390/tcg-target.h | 8 ++++----
13
tcg/sparc/tcg-target.h | 2 +-
14
tcg/tci/tcg-target.h | 6 +++---
15
accel/tcg/cpu-exec.c | 4 +++-
16
tcg/aarch64/tcg-target.c.inc | 12 ++++++------
17
tcg/mips/tcg-target.c.inc | 8 ++++----
18
tcg/ppc/tcg-target.c.inc | 16 ++++++++--------
19
tcg/sparc/tcg-target.c.inc | 14 +++++++-------
20
14 files changed, 44 insertions(+), 42 deletions(-)
21
10
22
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
11
diff --git a/tcg/optimize.c b/tcg/optimize.c
23
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
24
--- a/tcg/aarch64/tcg-target.h
13
--- a/tcg/optimize.c
25
+++ b/tcg/aarch64/tcg-target.h
14
+++ b/tcg/optimize.c
26
@@ -XXX,XX +XXX,XX @@ typedef enum {
15
@@ -XXX,XX +XXX,XX @@ static void copy_propagate(OptContext *ctx, TCGOp *op,
27
#define TCG_TARGET_DEFAULT_MO (0)
28
#define TCG_TARGET_HAS_MEMORY_BSWAP 1
29
30
-void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);
31
+void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
32
33
#ifdef CONFIG_SOFTMMU
34
#define TCG_TARGET_NEED_LDST_LABELS
35
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/tcg/arm/tcg-target.h
38
+++ b/tcg/arm/tcg-target.h
39
@@ -XXX,XX +XXX,XX @@ enum {
40
#define TCG_TARGET_HAS_MEMORY_BSWAP 1
41
42
/* not defined -- call should be eliminated at compile time */
43
-void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);
44
+void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
45
46
#ifdef CONFIG_SOFTMMU
47
#define TCG_TARGET_NEED_LDST_LABELS
48
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
49
index XXXXXXX..XXXXXXX 100644
50
--- a/tcg/i386/tcg-target.h
51
+++ b/tcg/i386/tcg-target.h
52
@@ -XXX,XX +XXX,XX @@ extern bool have_movbe;
53
#define TCG_TARGET_extract_i64_valid(ofs, len) \
54
(((ofs) == 8 && (len) == 8) || ((ofs) + (len)) == 32)
55
56
-static inline void tb_target_set_jmp_target(uintptr_t tc_ptr,
57
- uintptr_t jmp_addr, uintptr_t addr)
58
+static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
59
+ uintptr_t jmp_rw, uintptr_t addr)
60
{
61
/* patch the branch destination */
62
- qatomic_set((int32_t *)jmp_addr, addr - (jmp_addr + 4));
63
+ qatomic_set((int32_t *)jmp_rw, addr - (jmp_rx + 4));
64
/* no need to flush icache explicitly */
65
}
66
67
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
68
index XXXXXXX..XXXXXXX 100644
69
--- a/tcg/mips/tcg-target.h
70
+++ b/tcg/mips/tcg-target.h
71
@@ -XXX,XX +XXX,XX @@ extern bool use_mips32r2_instructions;
72
#define TCG_TARGET_DEFAULT_MO (0)
73
#define TCG_TARGET_HAS_MEMORY_BSWAP 1
74
75
-void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);
76
+void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
77
78
#ifdef CONFIG_SOFTMMU
79
#define TCG_TARGET_NEED_LDST_LABELS
80
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
81
index XXXXXXX..XXXXXXX 100644
82
--- a/tcg/ppc/tcg-target.h
83
+++ b/tcg/ppc/tcg-target.h
84
@@ -XXX,XX +XXX,XX @@ extern bool have_vsx;
85
#define TCG_TARGET_HAS_bitsel_vec have_vsx
86
#define TCG_TARGET_HAS_cmpsel_vec 0
87
88
-void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);
89
+void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
90
91
#define TCG_TARGET_DEFAULT_MO (0)
92
#define TCG_TARGET_HAS_MEMORY_BSWAP 1
93
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
94
index XXXXXXX..XXXXXXX 100644
95
--- a/tcg/riscv/tcg-target.h
96
+++ b/tcg/riscv/tcg-target.h
97
@@ -XXX,XX +XXX,XX @@ typedef enum {
98
#endif
99
100
/* not defined -- call should be eliminated at compile time */
101
-void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);
102
+void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
103
104
#define TCG_TARGET_DEFAULT_MO (0)
105
106
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
107
index XXXXXXX..XXXXXXX 100644
108
--- a/tcg/s390/tcg-target.h
109
+++ b/tcg/s390/tcg-target.h
110
@@ -XXX,XX +XXX,XX @@ enum {
111
TCG_AREG0 = TCG_REG_R10,
112
};
113
114
-static inline void tb_target_set_jmp_target(uintptr_t tc_ptr,
115
- uintptr_t jmp_addr, uintptr_t addr)
116
+static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
117
+ uintptr_t jmp_rw, uintptr_t addr)
118
{
119
/* patch the branch destination */
120
- intptr_t disp = addr - (jmp_addr - 2);
121
- qatomic_set((int32_t *)jmp_addr, disp / 2);
122
+ intptr_t disp = addr - (jmp_rx - 2);
123
+ qatomic_set((int32_t *)jmp_rw, disp / 2);
124
/* no need to flush icache explicitly */
125
}
126
127
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
128
index XXXXXXX..XXXXXXX 100644
129
--- a/tcg/sparc/tcg-target.h
130
+++ b/tcg/sparc/tcg-target.h
131
@@ -XXX,XX +XXX,XX @@ extern bool use_vis3_instructions;
132
#define TCG_TARGET_DEFAULT_MO (0)
133
#define TCG_TARGET_HAS_MEMORY_BSWAP 1
134
135
-void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);
136
+void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
137
138
#define TCG_TARGET_NEED_POOL_LABELS
139
140
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
141
index XXXXXXX..XXXXXXX 100644
142
--- a/tcg/tci/tcg-target.h
143
+++ b/tcg/tci/tcg-target.h
144
@@ -XXX,XX +XXX,XX @@ void tci_disas(uint8_t opc);
145
146
#define TCG_TARGET_HAS_MEMORY_BSWAP 1
147
148
-static inline void tb_target_set_jmp_target(uintptr_t tc_ptr,
149
- uintptr_t jmp_addr, uintptr_t addr)
150
+static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
151
+ uintptr_t jmp_rw, uintptr_t addr)
152
{
153
/* patch the branch destination */
154
- qatomic_set((int32_t *)jmp_addr, addr - (jmp_addr + 4));
155
+ qatomic_set((int32_t *)jmp_rw, addr - (jmp_rx + 4));
156
/* no need to flush icache explicitly */
157
}
158
159
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/accel/tcg/cpu-exec.c
162
+++ b/accel/tcg/cpu-exec.c
163
@@ -XXX,XX +XXX,XX @@ void tb_set_jmp_target(TranslationBlock *tb, int n, uintptr_t addr)
164
if (TCG_TARGET_HAS_direct_jump) {
165
uintptr_t offset = tb->jmp_target_arg[n];
166
uintptr_t tc_ptr = (uintptr_t)tb->tc.ptr;
167
- tb_target_set_jmp_target(tc_ptr, tc_ptr + offset, addr);
168
+ uintptr_t jmp_rx = tc_ptr + offset;
169
+ uintptr_t jmp_rw = jmp_rx - tcg_splitwx_diff;
170
+ tb_target_set_jmp_target(tc_ptr, jmp_rx, jmp_rw, addr);
171
} else {
172
tb->jmp_target_arg[n] = addr;
173
}
174
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
175
index XXXXXXX..XXXXXXX 100644
176
--- a/tcg/aarch64/tcg-target.c.inc
177
+++ b/tcg/aarch64/tcg-target.c.inc
178
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_call(TCGContext *s, const tcg_insn_unit *target)
179
}
16
}
180
}
17
}
181
18
182
-void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
19
+static void finish_bb(OptContext *ctx)
183
- uintptr_t addr)
20
+{
184
+void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
21
+ /* We only optimize memory barriers across basic blocks. */
185
+ uintptr_t jmp_rw, uintptr_t addr)
22
+ ctx->prev_mb = NULL;
23
+}
24
+
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)
186
{
34
{
187
tcg_insn_unit i1, i2;
35
const TCGOpDef *def = &tcg_op_defs[op->opc];
188
TCGType rt = TCG_TYPE_I64;
36
int i, nb_oargs;
189
TCGReg rd = TCG_REG_TMP;
37
190
uint64_t pair;
38
- /*
191
39
- * We only optimize extended basic blocks. If the opcode ends a BB
192
- ptrdiff_t offset = addr - jmp_addr;
40
- * and is not a conditional branch, reset all temp data.
193
+ ptrdiff_t offset = addr - jmp_rx;
41
- */
194
42
- if (def->flags & TCG_OPF_BB_END) {
195
if (offset == sextract64(offset, 0, 26)) {
43
- ctx->prev_mb = NULL;
196
i1 = I3206_B | ((offset >> 2) & 0x3ffffff);
44
- if (!(def->flags & TCG_OPF_COND_BRANCH)) {
197
i2 = NOP;
45
- memset(&ctx->temps_used, 0, sizeof(ctx->temps_used));
198
} else {
46
- remove_mem_copy_all(ctx);
199
- offset = (addr >> 12) - (jmp_addr >> 12);
47
- }
200
+ offset = (addr >> 12) - (jmp_rx >> 12);
48
- return;
201
49
- }
202
/* patch ADRP */
50
-
203
i1 = I3406_ADRP | (offset & 3) << 29 | (offset & 0x1ffffc) << (5 - 2) | rd;
51
nb_oargs = def->nb_oargs;
204
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
52
for (i = 0; i < nb_oargs; i++) {
205
i2 = I3401_ADDI | rt << 31 | (addr & 0xfff) << 10 | rd << 5 | rd;
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);
206
}
61
}
207
pair = (uint64_t)i2 << 32 | i1;
62
- return false;
208
- qatomic_set((uint64_t *)jmp_addr, pair);
63
+ return true;
209
- flush_idcache_range(jmp_addr, jmp_addr, 8);
210
+ qatomic_set((uint64_t *)jmp_rw, pair);
211
+ flush_idcache_range(jmp_rx, jmp_rw, 8);
212
}
64
}
213
65
214
static inline void tcg_out_goto_label(TCGContext *s, TCGLabel *l)
66
static bool fold_brcond2(OptContext *ctx, TCGOp *op)
215
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
67
@@ -XXX,XX +XXX,XX @@ static bool fold_brcond2(OptContext *ctx, TCGOp *op)
216
index XXXXXXX..XXXXXXX 100644
68
}
217
--- a/tcg/mips/tcg-target.c.inc
69
op->opc = INDEX_op_br;
218
+++ b/tcg/mips/tcg-target.c.inc
70
op->args[0] = label;
219
@@ -XXX,XX +XXX,XX @@ static void tcg_target_init(TCGContext *s)
71
- break;
220
tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP); /* global pointer */
72
+ finish_ebb(ctx);
73
+ return true;
74
}
75
- return false;
76
+
77
+ finish_bb(ctx);
78
+ return true;
221
}
79
}
222
80
223
-void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
81
static bool fold_bswap(OptContext *ctx, TCGOp *op)
224
- uintptr_t addr)
82
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s)
225
+void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
83
CASE_OP_32_64_VEC(xor):
226
+ uintptr_t jmp_rw, uintptr_t addr)
84
done = fold_xor(&ctx, op);
227
{
85
break;
228
- qatomic_set((uint32_t *)jmp_addr, deposit32(OPC_J, 0, 26, addr >> 2));
86
+ case INDEX_op_set_label:
229
- flush_idcache_range(jmp_addr, jmp_addr, 4);
87
+ case INDEX_op_br:
230
+ qatomic_set((uint32_t *)jmp_rw, deposit32(OPC_J, 0, 26, addr >> 2));
88
+ case INDEX_op_exit_tb:
231
+ flush_idcache_range(jmp_rx, jmp_rw, 4);
89
+ case INDEX_op_goto_tb:
232
}
90
+ case INDEX_op_goto_ptr:
233
91
+ finish_ebb(&ctx);
234
typedef struct {
92
+ done = true;
235
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
93
+ break;
236
index XXXXXXX..XXXXXXX 100644
94
default:
237
--- a/tcg/ppc/tcg-target.c.inc
95
break;
238
+++ b/tcg/ppc/tcg-target.c.inc
96
}
239
@@ -XXX,XX +XXX,XX @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
240
tcg_out32(s, insn);
241
}
242
243
-void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
244
- uintptr_t addr)
245
+void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
246
+ uintptr_t jmp_rw, uintptr_t addr)
247
{
248
if (TCG_TARGET_REG_BITS == 64) {
249
tcg_insn_unit i1, i2;
250
intptr_t tb_diff = addr - tc_ptr;
251
- intptr_t br_diff = addr - (jmp_addr + 4);
252
+ intptr_t br_diff = addr - (jmp_rx + 4);
253
uint64_t pair;
254
255
/* This does not exercise the range of the branch, but we do
256
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
257
258
/* As per the enclosing if, this is ppc64. Avoid the _Static_assert
259
within qatomic_set that would fail to build a ppc32 host. */
260
- qatomic_set__nocheck((uint64_t *)jmp_addr, pair);
261
- flush_idcache_range(jmp_addr, jmp_addr, 8);
262
+ qatomic_set__nocheck((uint64_t *)jmp_rw, pair);
263
+ flush_idcache_range(jmp_rx, jmp_rw, 8);
264
} else {
265
- intptr_t diff = addr - jmp_addr;
266
+ intptr_t diff = addr - jmp_rx;
267
tcg_debug_assert(in_range_b(diff));
268
- qatomic_set((uint32_t *)jmp_addr, B | (diff & 0x3fffffc));
269
- flush_idcache_range(jmp_addr, jmp_addr, 4);
270
+ qatomic_set((uint32_t *)jmp_rw, B | (diff & 0x3fffffc));
271
+ flush_idcache_range(jmp_rx, jmp_rw, 4);
272
}
273
}
274
275
diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc/tcg-target.c.inc
276
index XXXXXXX..XXXXXXX 100644
277
--- a/tcg/sparc/tcg-target.c.inc
278
+++ b/tcg/sparc/tcg-target.c.inc
279
@@ -XXX,XX +XXX,XX @@ void tcg_register_jit(const void *buf, size_t buf_size)
280
tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
281
}
282
283
-void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
284
- uintptr_t addr)
285
+void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
286
+ uintptr_t jmp_rw, uintptr_t addr)
287
{
288
intptr_t tb_disp = addr - tc_ptr;
289
- intptr_t br_disp = addr - jmp_addr;
290
+ intptr_t br_disp = addr - jmp_rx;
291
tcg_insn_unit i1, i2;
292
293
/* We can reach the entire address space for ILP32.
294
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
295
tcg_debug_assert(br_disp == (int32_t)br_disp);
296
297
if (!USE_REG_TB) {
298
- qatomic_set((uint32_t *)jmp_addr,
299
+ qatomic_set((uint32_t *)jmp_rw,
300
         deposit32(CALL, 0, 30, br_disp >> 2));
301
- flush_idcache_range(jmp_addr, jmp_addr, 4);
302
+ flush_idcache_range(jmp_rx, jmp_rw, 4);
303
return;
304
}
305
306
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
307
| INSN_IMM13((tb_disp & 0x3ff) | -0x400));
308
}
309
310
- qatomic_set((uint64_t *)jmp_addr, deposit64(i2, 32, 32, i1));
311
- flush_idcache_range(jmp_addr, jmp_addr, 8);
312
+ qatomic_set((uint64_t *)jmp_rw, deposit64(i2, 32, 32, i1));
313
+ flush_idcache_range(jmp_rx, jmp_rw, 8);
314
}
315
--
97
--
316
2.25.1
98
2.43.0
317
318
diff view generated by jsdifflib
1
We cannot use a real temp file, because we would need to find
1
There are only a few logical operations which can compute
2
a filesystem that does not have noexec enabled. However, a
2
an "affected" mask. Split out handling of this optimization
3
memfd is not associated with any filesystem.
3
to a separate function, only to be called when applicable.
4
4
5
Reviewed-by: Joelle van Dyne <j@getutm.app>
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>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
10
---
8
accel/tcg/translate-all.c | 84 +++++++++++++++++++++++++++++++++++----
11
tcg/optimize.c | 42 +++++++++++++++++++++++++++---------------
9
1 file changed, 76 insertions(+), 8 deletions(-)
12
1 file changed, 27 insertions(+), 15 deletions(-)
10
13
11
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
14
diff --git a/tcg/optimize.c b/tcg/optimize.c
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/accel/tcg/translate-all.c
16
--- a/tcg/optimize.c
14
+++ b/accel/tcg/translate-all.c
17
+++ b/tcg/optimize.c
15
@@ -XXX,XX +XXX,XX @@ static bool alloc_code_gen_buffer(size_t size, int splitwx, Error **errp)
18
@@ -XXX,XX +XXX,XX @@ typedef struct OptContext {
16
return true;
19
QSIMPLEQ_HEAD(, MemCopyInfo) mem_free;
17
}
20
18
#else
21
/* In flight values from optimization. */
19
-static bool alloc_code_gen_buffer(size_t size, int splitwx, Error **errp)
22
- uint64_t a_mask; /* mask bit is 0 iff value identical to first input */
20
+static bool alloc_code_gen_buffer_anon(size_t size, int prot,
23
uint64_t z_mask; /* mask bit is 0 iff value bit is 0 */
21
+ int flags, Error **errp)
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)
22
{
29
{
23
- int prot = PROT_WRITE | PROT_READ | PROT_EXEC;
30
- uint64_t a_mask = ctx->a_mask;
24
- int flags = MAP_PRIVATE | MAP_ANONYMOUS;
31
uint64_t z_mask = ctx->z_mask;
25
void *buf;
32
uint64_t s_mask = ctx->s_mask;
26
33
27
- if (splitwx > 0) {
34
@@ -XXX,XX +XXX,XX @@ static bool fold_masks(OptContext *ctx, TCGOp *op)
28
- error_setg(errp, "jit split-wx not supported");
35
* type changing opcodes.
29
- return false;
36
*/
30
- }
37
if (ctx->type == TCG_TYPE_I32) {
31
-
38
- a_mask = (int32_t)a_mask;
32
buf = mmap(NULL, size, prot, flags, -1, 0);
39
z_mask = (int32_t)z_mask;
33
if (buf == MAP_FAILED) {
40
s_mask |= MAKE_64BIT_MASK(32, 32);
34
error_setg_errno(errp, errno,
41
ctx->z_mask = z_mask;
35
@@ -XXX,XX +XXX,XX @@ static bool alloc_code_gen_buffer(size_t size, int splitwx, Error **errp)
42
@@ -XXX,XX +XXX,XX @@ static bool fold_masks(OptContext *ctx, TCGOp *op)
36
tcg_ctx->code_gen_buffer = buf;
43
if (z_mask == 0) {
37
return true;
44
return tcg_opt_gen_movi(ctx, op, op->args[0], 0);
38
}
45
}
39
+
40
+#ifdef CONFIG_POSIX
41
+#include "qemu/memfd.h"
42
+
43
+static bool alloc_code_gen_buffer_splitwx_memfd(size_t size, Error **errp)
44
+{
45
+ void *buf_rw, *buf_rx;
46
+ int fd = -1;
47
+
48
+ buf_rw = qemu_memfd_alloc("tcg-jit", size, 0, &fd, errp);
49
+ if (buf_rw == NULL) {
50
+ return false;
51
+ }
52
+
53
+ buf_rx = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0);
54
+ if (buf_rx == MAP_FAILED) {
55
+ error_setg_errno(errp, errno,
56
+ "failed to map shared memory for execute");
57
+ munmap(buf_rw, size);
58
+ close(fd);
59
+ return false;
60
+ }
61
+ close(fd);
62
+
63
+ tcg_ctx->code_gen_buffer = buf_rw;
64
+ tcg_ctx->code_gen_buffer_size = size;
65
+ tcg_splitwx_diff = buf_rx - buf_rw;
66
+
67
+ /* Request large pages for the buffer and the splitwx. */
68
+ qemu_madvise(buf_rw, size, QEMU_MADV_HUGEPAGE);
69
+ qemu_madvise(buf_rx, size, QEMU_MADV_HUGEPAGE);
70
+ return true;
71
+}
72
+#endif /* CONFIG_POSIX */
73
+
74
+static bool alloc_code_gen_buffer_splitwx(size_t size, Error **errp)
75
+{
76
+ if (TCG_TARGET_SUPPORT_MIRROR) {
77
+#ifdef CONFIG_POSIX
78
+ return alloc_code_gen_buffer_splitwx_memfd(size, errp);
79
+#endif
80
+ }
81
+ error_setg(errp, "jit split-wx not supported");
82
+ return false;
46
+ return false;
83
+}
47
+}
84
+
48
+
85
+static bool alloc_code_gen_buffer(size_t size, int splitwx, Error **errp)
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)
86
+{
55
+{
87
+ ERRP_GUARD();
56
+ if (ctx->type == TCG_TYPE_I32) {
88
+ int prot, flags;
57
+ a_mask = (uint32_t)a_mask;
89
+
58
+ }
90
+ if (splitwx) {
59
if (a_mask == 0) {
91
+ if (alloc_code_gen_buffer_splitwx(size, errp)) {
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)) {
92
+ return true;
80
+ return true;
93
+ }
81
+ }
94
+ /*
82
z1 &= z2;
95
+ * If splitwx force-on (1), fail;
83
}
96
+ * if splitwx default-on (-1), fall through to splitwx off.
84
ctx->z_mask = z1;
97
+ */
85
@@ -XXX,XX +XXX,XX @@ static bool fold_extract(OptContext *ctx, TCGOp *op)
98
+ if (splitwx > 0) {
86
99
+ return false;
87
z_mask_old = arg_info(op->args[1])->z_mask;
100
+ }
88
z_mask = extract64(z_mask_old, pos, len);
101
+ error_free_or_abort(errp);
89
- if (pos == 0) {
102
+ }
90
- ctx->a_mask = z_mask_old ^ z_mask;
103
+
91
+ if (pos == 0 && fold_affected_mask(ctx, op, z_mask_old ^ z_mask)) {
104
+ prot = PROT_READ | PROT_WRITE | PROT_EXEC;
92
+ return true;
105
+ flags = MAP_PRIVATE | MAP_ANONYMOUS;
93
}
106
+#ifdef CONFIG_TCG_INTERPRETER
94
ctx->z_mask = z_mask;
107
+ /* The tcg interpreter does not need execute permission. */
95
ctx->s_mask = smask_from_zmask(z_mask);
108
+ prot = PROT_READ | PROT_WRITE;
96
@@ -XXX,XX +XXX,XX @@ static bool fold_exts(OptContext *ctx, TCGOp *op)
109
+#endif
97
110
+
98
ctx->z_mask = z_mask;
111
+ return alloc_code_gen_buffer_anon(size, prot, flags, errp);
99
ctx->s_mask = s_mask;
112
+}
100
- if (!type_change) {
113
#endif /* USE_STATIC_CODE_GEN_BUFFER, WIN32, POSIX */
101
- ctx->a_mask = s_mask & ~s_mask_old;
114
102
+ if (!type_change && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
115
static bool tb_cmp(const void *ap, const void *bp)
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
116
--
137
--
117
2.25.1
138
2.43.0
118
119
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
Reviewed-by: Joelle van Dyne <j@getutm.app>
1
Consider the passed s_mask to be a minimum deduced from
2
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
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.
5
6
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
8
---
5
tcg/tci.c | 60 +++++++++++++++++++++++++++++++------------------------
9
tcg/optimize.c | 21 ++++++---------------
6
1 file changed, 34 insertions(+), 26 deletions(-)
10
1 file changed, 6 insertions(+), 15 deletions(-)
7
11
8
diff --git a/tcg/tci.c b/tcg/tci.c
12
diff --git a/tcg/optimize.c b/tcg/optimize.c
9
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
10
--- a/tcg/tci.c
14
--- a/tcg/optimize.c
11
+++ b/tcg/tci.c
15
+++ b/tcg/optimize.c
12
@@ -XXX,XX +XXX,XX @@ static uint64_t tci_uint64(uint32_t high, uint32_t low)
16
@@ -XXX,XX +XXX,XX @@ static bool fold_const2_commutative(OptContext *ctx, TCGOp *op)
13
#endif
17
* Record "zero" and "sign" masks for the single output of @op.
14
18
* See TempOptInfo definition of z_mask and s_mask.
15
/* Read constant (native size) from bytecode. */
19
* If z_mask allows, fold the output to constant zero.
16
-static tcg_target_ulong tci_read_i(uint8_t **tb_ptr)
20
+ * The passed s_mask may be augmented by z_mask.
17
+static tcg_target_ulong tci_read_i(const uint8_t **tb_ptr)
21
*/
18
{
22
static bool fold_masks_zs(OptContext *ctx, TCGOp *op,
19
- tcg_target_ulong value = *(tcg_target_ulong *)(*tb_ptr);
23
uint64_t z_mask, uint64_t s_mask)
20
+ tcg_target_ulong value = *(const tcg_target_ulong *)(*tb_ptr);
24
@@ -XXX,XX +XXX,XX @@ static bool fold_masks_zs(OptContext *ctx, TCGOp *op,
21
*tb_ptr += sizeof(value);
25
22
return value;
26
ti = ts_info(ts);
27
ti->z_mask = z_mask;
28
- ti->s_mask = s_mask;
29
+ ti->s_mask = s_mask | smask_from_zmask(z_mask);
30
return true;
23
}
31
}
24
32
25
/* Read unsigned constant (32 bit) from bytecode. */
33
@@ -XXX,XX +XXX,XX @@ static bool fold_bswap(OptContext *ctx, TCGOp *op)
26
-static uint32_t tci_read_i32(uint8_t **tb_ptr)
34
default:
27
+static uint32_t tci_read_i32(const uint8_t **tb_ptr)
35
g_assert_not_reached();
28
{
36
}
29
- uint32_t value = *(uint32_t *)(*tb_ptr);
37
- s_mask = smask_from_zmask(z_mask);
30
+ uint32_t value = *(const uint32_t *)(*tb_ptr);
38
31
*tb_ptr += sizeof(value);
39
+ s_mask = 0;
32
return value;
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;
33
}
57
}
34
58
35
/* Read signed constant (32 bit) from bytecode. */
59
@@ -XXX,XX +XXX,XX @@ static bool fold_ctpop(OptContext *ctx, TCGOp *op)
36
-static int32_t tci_read_s32(uint8_t **tb_ptr)
60
default:
37
+static int32_t tci_read_s32(const uint8_t **tb_ptr)
61
g_assert_not_reached();
38
{
62
}
39
- int32_t value = *(int32_t *)(*tb_ptr);
63
- ctx->s_mask = smask_from_zmask(ctx->z_mask);
40
+ int32_t value = *(const int32_t *)(*tb_ptr);
64
return false;
41
*tb_ptr += sizeof(value);
42
return value;
43
}
65
}
44
66
45
#if TCG_TARGET_REG_BITS == 64
67
@@ -XXX,XX +XXX,XX @@ static bool fold_extract(OptContext *ctx, TCGOp *op)
46
/* Read constant (64 bit) from bytecode. */
68
return true;
47
-static uint64_t tci_read_i64(uint8_t **tb_ptr)
69
}
48
+static uint64_t tci_read_i64(const uint8_t **tb_ptr)
70
ctx->z_mask = z_mask;
49
{
71
- ctx->s_mask = smask_from_zmask(z_mask);
50
- uint64_t value = *(uint64_t *)(*tb_ptr);
72
51
+ uint64_t value = *(const uint64_t *)(*tb_ptr);
73
return fold_masks(ctx, op);
52
*tb_ptr += sizeof(value);
53
return value;
54
}
74
}
55
@@ -XXX,XX +XXX,XX @@ static uint64_t tci_read_i64(uint8_t **tb_ptr)
75
@@ -XXX,XX +XXX,XX @@ static bool fold_extu(OptContext *ctx, TCGOp *op)
56
76
}
57
/* Read indexed register (native size) from bytecode. */
77
58
static tcg_target_ulong
78
ctx->z_mask = z_mask;
59
-tci_read_r(const tcg_target_ulong *regs, uint8_t **tb_ptr)
79
- ctx->s_mask = smask_from_zmask(z_mask);
60
+tci_read_r(const tcg_target_ulong *regs, const uint8_t **tb_ptr)
80
if (!type_change && fold_affected_mask(ctx, op, z_mask_old ^ z_mask)) {
61
{
81
return true;
62
tcg_target_ulong value = tci_read_reg(regs, **tb_ptr);
82
}
63
*tb_ptr += 1;
83
@@ -XXX,XX +XXX,XX @@ static bool fold_qemu_ld(OptContext *ctx, TCGOp *op)
64
@@ -XXX,XX +XXX,XX @@ tci_read_r(const tcg_target_ulong *regs, uint8_t **tb_ptr)
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;
94
}
95
}
96
97
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond(OptContext *ctx, TCGOp *op)
98
fold_setcond_tst_pow2(ctx, op, false);
99
100
ctx->z_mask = 1;
101
- ctx->s_mask = smask_from_zmask(1);
102
return false;
65
}
103
}
66
104
67
/* Read indexed register (8 bit) from bytecode. */
105
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond2(OptContext *ctx, TCGOp *op)
68
-static uint8_t tci_read_r8(const tcg_target_ulong *regs, uint8_t **tb_ptr)
106
}
69
+static uint8_t tci_read_r8(const tcg_target_ulong *regs, const uint8_t **tb_ptr)
107
70
{
108
ctx->z_mask = 1;
71
uint8_t value = tci_read_reg8(regs, **tb_ptr);
109
- ctx->s_mask = smask_from_zmask(1);
72
*tb_ptr += 1;
110
return false;
73
@@ -XXX,XX +XXX,XX @@ static uint8_t tci_read_r8(const tcg_target_ulong *regs, uint8_t **tb_ptr)
111
74
112
do_setcond_const:
75
#if TCG_TARGET_HAS_ext8s_i32 || TCG_TARGET_HAS_ext8s_i64
113
@@ -XXX,XX +XXX,XX @@ static bool fold_tcg_ld(OptContext *ctx, TCGOp *op)
76
/* Read indexed register (8 bit signed) from bytecode. */
114
break;
77
-static int8_t tci_read_r8s(const tcg_target_ulong *regs, uint8_t **tb_ptr)
115
CASE_OP_32_64(ld8u):
78
+static int8_t tci_read_r8s(const tcg_target_ulong *regs, const uint8_t **tb_ptr)
116
ctx->z_mask = MAKE_64BIT_MASK(0, 8);
79
{
117
- ctx->s_mask = MAKE_64BIT_MASK(9, 55);
80
int8_t value = tci_read_reg8s(regs, **tb_ptr);
118
break;
81
*tb_ptr += 1;
119
CASE_OP_32_64(ld16s):
82
@@ -XXX,XX +XXX,XX @@ static int8_t tci_read_r8s(const tcg_target_ulong *regs, uint8_t **tb_ptr)
120
ctx->s_mask = MAKE_64BIT_MASK(16, 48);
83
#endif
121
break;
84
122
CASE_OP_32_64(ld16u):
85
/* Read indexed register (16 bit) from bytecode. */
123
ctx->z_mask = MAKE_64BIT_MASK(0, 16);
86
-static uint16_t tci_read_r16(const tcg_target_ulong *regs, uint8_t **tb_ptr)
124
- ctx->s_mask = MAKE_64BIT_MASK(17, 47);
87
+static uint16_t tci_read_r16(const tcg_target_ulong *regs,
125
break;
88
+ const uint8_t **tb_ptr)
126
case INDEX_op_ld32s_i64:
89
{
127
ctx->s_mask = MAKE_64BIT_MASK(32, 32);
90
uint16_t value = tci_read_reg16(regs, **tb_ptr);
128
break;
91
*tb_ptr += 1;
129
case INDEX_op_ld32u_i64:
92
@@ -XXX,XX +XXX,XX @@ static uint16_t tci_read_r16(const tcg_target_ulong *regs, uint8_t **tb_ptr)
130
ctx->z_mask = MAKE_64BIT_MASK(0, 32);
93
131
- ctx->s_mask = MAKE_64BIT_MASK(33, 31);
94
#if TCG_TARGET_HAS_ext16s_i32 || TCG_TARGET_HAS_ext16s_i64
132
break;
95
/* Read indexed register (16 bit signed) from bytecode. */
133
default:
96
-static int16_t tci_read_r16s(const tcg_target_ulong *regs, uint8_t **tb_ptr)
134
g_assert_not_reached();
97
+static int16_t tci_read_r16s(const tcg_target_ulong *regs,
98
+ const uint8_t **tb_ptr)
99
{
100
int16_t value = tci_read_reg16s(regs, **tb_ptr);
101
*tb_ptr += 1;
102
@@ -XXX,XX +XXX,XX @@ static int16_t tci_read_r16s(const tcg_target_ulong *regs, uint8_t **tb_ptr)
103
#endif
104
105
/* Read indexed register (32 bit) from bytecode. */
106
-static uint32_t tci_read_r32(const tcg_target_ulong *regs, uint8_t **tb_ptr)
107
+static uint32_t tci_read_r32(const tcg_target_ulong *regs,
108
+ const uint8_t **tb_ptr)
109
{
110
uint32_t value = tci_read_reg32(regs, **tb_ptr);
111
*tb_ptr += 1;
112
@@ -XXX,XX +XXX,XX @@ static uint32_t tci_read_r32(const tcg_target_ulong *regs, uint8_t **tb_ptr)
113
114
#if TCG_TARGET_REG_BITS == 32
115
/* Read two indexed registers (2 * 32 bit) from bytecode. */
116
-static uint64_t tci_read_r64(const tcg_target_ulong *regs, uint8_t **tb_ptr)
117
+static uint64_t tci_read_r64(const tcg_target_ulong *regs,
118
+ const uint8_t **tb_ptr)
119
{
120
uint32_t low = tci_read_r32(regs, tb_ptr);
121
return tci_uint64(tci_read_r32(regs, tb_ptr), low);
122
}
123
#elif TCG_TARGET_REG_BITS == 64
124
/* Read indexed register (32 bit signed) from bytecode. */
125
-static int32_t tci_read_r32s(const tcg_target_ulong *regs, uint8_t **tb_ptr)
126
+static int32_t tci_read_r32s(const tcg_target_ulong *regs,
127
+ const uint8_t **tb_ptr)
128
{
129
int32_t value = tci_read_reg32s(regs, **tb_ptr);
130
*tb_ptr += 1;
131
@@ -XXX,XX +XXX,XX @@ static int32_t tci_read_r32s(const tcg_target_ulong *regs, uint8_t **tb_ptr)
132
}
133
134
/* Read indexed register (64 bit) from bytecode. */
135
-static uint64_t tci_read_r64(const tcg_target_ulong *regs, uint8_t **tb_ptr)
136
+static uint64_t tci_read_r64(const tcg_target_ulong *regs,
137
+ const uint8_t **tb_ptr)
138
{
139
uint64_t value = tci_read_reg64(regs, **tb_ptr);
140
*tb_ptr += 1;
141
@@ -XXX,XX +XXX,XX @@ static uint64_t tci_read_r64(const tcg_target_ulong *regs, uint8_t **tb_ptr)
142
143
/* Read indexed register(s) with target address from bytecode. */
144
static target_ulong
145
-tci_read_ulong(const tcg_target_ulong *regs, uint8_t **tb_ptr)
146
+tci_read_ulong(const tcg_target_ulong *regs, const uint8_t **tb_ptr)
147
{
148
target_ulong taddr = tci_read_r(regs, tb_ptr);
149
#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
150
@@ -XXX,XX +XXX,XX @@ tci_read_ulong(const tcg_target_ulong *regs, uint8_t **tb_ptr)
151
152
/* Read indexed register or constant (native size) from bytecode. */
153
static tcg_target_ulong
154
-tci_read_ri(const tcg_target_ulong *regs, uint8_t **tb_ptr)
155
+tci_read_ri(const tcg_target_ulong *regs, const uint8_t **tb_ptr)
156
{
157
tcg_target_ulong value;
158
TCGReg r = **tb_ptr;
159
@@ -XXX,XX +XXX,XX @@ tci_read_ri(const tcg_target_ulong *regs, uint8_t **tb_ptr)
160
}
161
162
/* Read indexed register or constant (32 bit) from bytecode. */
163
-static uint32_t tci_read_ri32(const tcg_target_ulong *regs, uint8_t **tb_ptr)
164
+static uint32_t tci_read_ri32(const tcg_target_ulong *regs,
165
+ const uint8_t **tb_ptr)
166
{
167
uint32_t value;
168
TCGReg r = **tb_ptr;
169
@@ -XXX,XX +XXX,XX @@ static uint32_t tci_read_ri32(const tcg_target_ulong *regs, uint8_t **tb_ptr)
170
171
#if TCG_TARGET_REG_BITS == 32
172
/* Read two indexed registers or constants (2 * 32 bit) from bytecode. */
173
-static uint64_t tci_read_ri64(const tcg_target_ulong *regs, uint8_t **tb_ptr)
174
+static uint64_t tci_read_ri64(const tcg_target_ulong *regs,
175
+ const uint8_t **tb_ptr)
176
{
177
uint32_t low = tci_read_ri32(regs, tb_ptr);
178
return tci_uint64(tci_read_ri32(regs, tb_ptr), low);
179
}
180
#elif TCG_TARGET_REG_BITS == 64
181
/* Read indexed register or constant (64 bit) from bytecode. */
182
-static uint64_t tci_read_ri64(const tcg_target_ulong *regs, uint8_t **tb_ptr)
183
+static uint64_t tci_read_ri64(const tcg_target_ulong *regs,
184
+ const uint8_t **tb_ptr)
185
{
186
uint64_t value;
187
TCGReg r = **tb_ptr;
188
@@ -XXX,XX +XXX,XX @@ static uint64_t tci_read_ri64(const tcg_target_ulong *regs, uint8_t **tb_ptr)
189
}
190
#endif
191
192
-static tcg_target_ulong tci_read_label(uint8_t **tb_ptr)
193
+static tcg_target_ulong tci_read_label(const uint8_t **tb_ptr)
194
{
195
tcg_target_ulong label = tci_read_i(tb_ptr);
196
tci_assert(label != 0);
197
@@ -XXX,XX +XXX,XX @@ static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
198
uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
199
const void *v_tb_ptr)
200
{
201
- /* TODO: Propagate const through this file. */
202
- uint8_t *tb_ptr = (uint8_t *)v_tb_ptr;
203
+ const uint8_t *tb_ptr = v_tb_ptr;
204
tcg_target_ulong regs[TCG_TARGET_NB_REGS];
205
long tcg_temps[CPU_TEMP_BUF_NLONGS];
206
uintptr_t sp_value = (uintptr_t)(tcg_temps + CPU_TEMP_BUF_NLONGS);
207
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
208
TCGOpcode opc = tb_ptr[0];
209
#if defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG)
210
uint8_t op_size = tb_ptr[1];
211
- uint8_t *old_code_ptr = tb_ptr;
212
+ const uint8_t *old_code_ptr = tb_ptr;
213
#endif
214
tcg_target_ulong t0;
215
tcg_target_ulong t1;
216
--
135
--
217
2.25.1
136
2.43.0
218
219
diff view generated by jsdifflib
1
Since 7ecd02a06f8, we are prepared to re-start code generation
1
Change the representation from sign bit repetitions to all bits equal
2
with a smaller TB if a relocation is out of range. We no longer
2
to the sign bit, including the sign bit itself.
3
need to leave a nop in the stream Just In Case.
4
3
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
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.
8
9
The new format, including the sign bit itself, means that the sign mask
10
can be manipulated in exactly the same way as the value, canonicalization
11
is easier.
12
13
Canonicalize the s_mask in fold_masks_zs, rather than requiring callers
14
to do so. Treat 0 as a non-canonical but typeless input for no sign
15
information, which will be reset as appropriate for the data type.
16
We can easily fold in the data from z_mask while canonicalizing.
17
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>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
22
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
23
---
8
tcg/riscv/tcg-target.c.inc | 56 ++++----------------------------------
24
tcg/optimize.c | 64 ++++++++++++--------------------------------------
9
1 file changed, 6 insertions(+), 50 deletions(-)
25
1 file changed, 15 insertions(+), 49 deletions(-)
10
26
11
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
27
diff --git a/tcg/optimize.c b/tcg/optimize.c
12
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
13
--- a/tcg/riscv/tcg-target.c.inc
29
--- a/tcg/optimize.c
14
+++ b/tcg/riscv/tcg-target.c.inc
30
+++ b/tcg/optimize.c
15
@@ -XXX,XX +XXX,XX @@ static bool reloc_call(tcg_insn_unit *code_ptr, const tcg_insn_unit *target)
31
@@ -XXX,XX +XXX,XX @@ typedef struct TempOptInfo {
16
static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
32
QSIMPLEQ_HEAD(, MemCopyInfo) mem_copy;
17
intptr_t value, intptr_t addend)
33
uint64_t val;
34
uint64_t z_mask; /* mask bit is 0 if and only if value bit is 0 */
35
- uint64_t s_mask; /* a left-aligned mask of clrsb(value) bits. */
36
+ uint64_t s_mask; /* mask bit is 1 if value bit matches msb */
37
} TempOptInfo;
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)
18
{
89
{
19
- uint32_t insn = *code_ptr;
90
return ts->state_ptr;
20
- intptr_t diff;
91
@@ -XXX,XX +XXX,XX @@ static void init_ts_info(OptContext *ctx, TCGTemp *ts)
21
- bool short_jmp;
92
ti->is_const = true;
22
-
93
ti->val = ts->val;
23
tcg_debug_assert(addend == 0);
94
ti->z_mask = ts->val;
24
-
95
- ti->s_mask = smask_from_value(ts->val);
25
switch (type) {
96
+ ti->s_mask = INT64_MIN >> clrsb64(ts->val);
26
case R_RISCV_BRANCH:
97
} else {
27
- diff = value - (uintptr_t)code_ptr;
98
ti->is_const = false;
28
- short_jmp = diff == sextreg(diff, 0, 12);
99
ti->z_mask = -1;
29
- if (short_jmp) {
100
@@ -XXX,XX +XXX,XX @@ static void finish_folding(OptContext *ctx, TCGOp *op)
30
- return reloc_sbimm12(code_ptr, (tcg_insn_unit *)value);
101
*/
31
- } else {
102
if (i == 0) {
32
- /* Invert the condition */
103
ts_info(ts)->z_mask = ctx->z_mask;
33
- insn = insn ^ (1 << 12);
104
- ts_info(ts)->s_mask = ctx->s_mask;
34
- /* Clear the offset */
105
}
35
- insn &= 0x01fff07f;
36
- /* Set the offset to the PC + 8 */
37
- insn |= encode_sbimm12(8);
38
-
39
- /* Move forward */
40
- code_ptr[0] = insn;
41
-
42
- /* Overwrite the NOP with jal x0,value */
43
- diff = value - (uintptr_t)(code_ptr + 1);
44
- insn = encode_uj(OPC_JAL, TCG_REG_ZERO, diff);
45
- code_ptr[1] = insn;
46
-
47
- return true;
48
- }
49
- break;
50
+ return reloc_sbimm12(code_ptr, (tcg_insn_unit *)value);
51
case R_RISCV_JAL:
52
return reloc_jimm20(code_ptr, (tcg_insn_unit *)value);
53
case R_RISCV_CALL:
54
return reloc_call(code_ptr, (tcg_insn_unit *)value);
55
default:
56
- tcg_abort();
57
+ g_assert_not_reached();
58
}
106
}
59
}
107
}
60
108
@@ -XXX,XX +XXX,XX @@ static bool fold_const2_commutative(OptContext *ctx, TCGOp *op)
61
@@ -XXX,XX +XXX,XX @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
109
* The passed s_mask may be augmented by z_mask.
62
arg2 = t;
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;
63
}
128
}
64
129
65
- if (l->has_value) {
130
if (z_mask == 0) {
66
- intptr_t diff = tcg_pcrel_diff(s, l->u.value_ptr);
131
@@ -XXX,XX +XXX,XX @@ static bool fold_masks_zs(OptContext *ctx, TCGOp *op,
67
- if (diff == sextreg(diff, 0, 12)) {
132
68
- tcg_out_opc_branch(s, op, arg1, arg2, diff);
133
ti = ts_info(ts);
69
- } else {
134
ti->z_mask = z_mask;
70
- /* Invert the conditional branch. */
135
- ti->s_mask = s_mask | smask_from_zmask(z_mask);
71
- tcg_out_opc_branch(s, op ^ (1 << 12), arg1, arg2, 8);
136
+
72
- tcg_out_opc_jump(s, OPC_JAL, TCG_REG_ZERO, diff - 4);
137
+ /* Canonicalize s_mask and incorporate data from z_mask. */
73
- }
138
+ rep = clz64(~s_mask);
74
- } else {
139
+ rep = MAX(rep, clz64(z_mask));
75
- tcg_out_reloc(s, s->code_ptr, R_RISCV_BRANCH, l, 0);
140
+ rep = MAX(rep - 1, 0);
76
- tcg_out_opc_branch(s, op, arg1, arg2, 0);
141
+ ti->s_mask = INT64_MIN >> rep;
77
- /* NOP to allow patching later */
142
+
78
- tcg_out_opc_imm(s, OPC_ADDI, TCG_REG_ZERO, TCG_REG_ZERO, 0);
143
return true;
79
- }
80
+ tcg_out_reloc(s, s->code_ptr, R_RISCV_BRANCH, l, 0);
81
+ tcg_out_opc_branch(s, op, arg1, arg2, 0);
82
}
144
}
83
145
84
static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
146
@@ -XXX,XX +XXX,XX @@ static bool fold_exts(OptContext *ctx, TCGOp *op)
85
@@ -XXX,XX +XXX,XX @@ static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
147
86
/* Compare masked address with the TLB entry. */
148
ctx->z_mask = z_mask;
87
label_ptr[0] = s->code_ptr;
149
ctx->s_mask = s_mask;
88
tcg_out_opc_branch(s, OPC_BNE, TCG_REG_TMP0, TCG_REG_TMP1, 0);
150
- if (!type_change && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
89
- /* NOP to allow patching later */
151
+ if (0 && !type_change && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
90
- tcg_out_opc_imm(s, OPC_ADDI, TCG_REG_ZERO, TCG_REG_ZERO, 0);
152
return true;
91
92
/* TLB Hit - translate address using addend. */
93
if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
94
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
95
}
153
}
96
154
97
/* resolve label address */
155
@@ -XXX,XX +XXX,XX @@ static bool fold_sextract(OptContext *ctx, TCGOp *op)
98
- if (!patch_reloc(l->label_ptr[0], R_RISCV_BRANCH,
156
s_mask |= MAKE_64BIT_MASK(len, 64 - len);
99
- (intptr_t) s->code_ptr, 0)) {
157
ctx->s_mask = s_mask;
100
+ if (!reloc_sbimm12(l->label_ptr[0], s->code_ptr)) {
158
101
return false;
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;
102
}
162
}
103
163
104
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
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);
105
}
171
}
106
107
/* resolve label address */
108
- if (!patch_reloc(l->label_ptr[0], R_RISCV_BRANCH,
109
- (intptr_t) s->code_ptr, 0)) {
110
+ if (!reloc_sbimm12(l->label_ptr[0], s->code_ptr)) {
111
return false;
112
}
113
114
--
172
--
115
2.25.1
173
2.43.0
116
117
diff view generated by jsdifflib
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
1
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
---
3
---
3
tcg/ppc/tcg-target.h | 2 +-
4
tcg/optimize.c | 9 +++++----
4
tcg/ppc/tcg-target.c.inc | 53 +++++++++++++++++++++++-----------------
5
1 file changed, 5 insertions(+), 4 deletions(-)
5
2 files changed, 31 insertions(+), 24 deletions(-)
6
6
7
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
8
index XXXXXXX..XXXXXXX 100644
8
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/ppc/tcg-target.h
9
--- a/tcg/optimize.c
10
+++ b/tcg/ppc/tcg-target.h
10
+++ b/tcg/optimize.c
11
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
11
@@ -XXX,XX +XXX,XX @@ static void finish_ebb(OptContext *ctx)
12
#define TCG_TARGET_NEED_LDST_LABELS
12
remove_mem_copy_all(ctx);
13
#endif
14
#define TCG_TARGET_NEED_POOL_LABELS
15
-#define TCG_TARGET_SUPPORT_MIRROR 0
16
+#define TCG_TARGET_SUPPORT_MIRROR 1
17
18
#endif
19
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
20
index XXXXXXX..XXXXXXX 100644
21
--- a/tcg/ppc/tcg-target.c.inc
22
+++ b/tcg/ppc/tcg-target.c.inc
23
@@ -XXX,XX +XXX,XX @@
24
#define TCG_CT_CONST_MONE 0x2000
25
#define TCG_CT_CONST_WSZ 0x4000
26
27
-static tcg_insn_unit *tb_ret_addr;
28
-
29
TCGPowerISA have_isa;
30
static bool have_isel;
31
bool have_altivec;
32
@@ -XXX,XX +XXX,XX @@ static inline bool in_range_b(tcg_target_long target)
33
return target == sextract64(target, 0, 26);
34
}
13
}
35
14
36
-static uint32_t reloc_pc24_val(tcg_insn_unit *pc, const tcg_insn_unit *target)
15
-static void finish_folding(OptContext *ctx, TCGOp *op)
37
+static uint32_t reloc_pc24_val(const tcg_insn_unit *pc,
16
+static bool finish_folding(OptContext *ctx, TCGOp *op)
38
+             const tcg_insn_unit *target)
39
{
17
{
40
ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
18
const TCGOpDef *def = &tcg_op_defs[op->opc];
41
tcg_debug_assert(in_range_b(disp));
19
int i, nb_oargs;
42
return disp & 0x3fffffc;
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;
43
}
25
}
44
26
45
-static bool reloc_pc24(tcg_insn_unit *pc, tcg_insn_unit *target)
27
/*
46
+static bool reloc_pc24(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
28
@@ -XXX,XX +XXX,XX @@ static bool fold_add(OptContext *ctx, TCGOp *op)
47
{
29
fold_xi_to_x(ctx, op, 0)) {
48
- ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
49
+ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
50
+ ptrdiff_t disp = tcg_ptr_byte_diff(target, src_rx);
51
+
52
if (in_range_b(disp)) {
53
- *pc = (*pc & ~0x3fffffc) | (disp & 0x3fffffc);
54
+ *src_rw = (*src_rw & ~0x3fffffc) | (disp & 0x3fffffc);
55
return true;
30
return true;
56
}
31
}
57
return false;
32
- return false;
33
+ return finish_folding(ctx, op);
58
}
34
}
59
35
60
-static uint16_t reloc_pc14_val(tcg_insn_unit *pc, const tcg_insn_unit *target)
36
/* We cannot as yet do_constant_folding with vectors. */
61
+static uint16_t reloc_pc14_val(const tcg_insn_unit *pc,
37
@@ -XXX,XX +XXX,XX @@ static bool fold_add_vec(OptContext *ctx, TCGOp *op)
62
+             const tcg_insn_unit *target)
38
fold_xi_to_x(ctx, op, 0)) {
63
{
64
ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
65
tcg_debug_assert(disp == (int16_t) disp);
66
return disp & 0xfffc;
67
}
68
69
-static bool reloc_pc14(tcg_insn_unit *pc, tcg_insn_unit *target)
70
+static bool reloc_pc14(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
71
{
72
- ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
73
+ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
74
+ ptrdiff_t disp = tcg_ptr_byte_diff(target, src_rx);
75
+
76
if (disp == (int16_t) disp) {
77
- *pc = (*pc & ~0xfffc) | (disp & 0xfffc);
78
+ *src_rw = (*src_rw & ~0xfffc) | (disp & 0xfffc);
79
return true;
39
return true;
80
}
40
}
81
return false;
41
- return false;
82
@@ -XXX,XX +XXX,XX @@ static const uint32_t tcg_to_isel[] = {
42
+ return finish_folding(ctx, op);
83
static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
43
}
84
intptr_t value, intptr_t addend)
44
85
{
45
static bool fold_addsub2(OptContext *ctx, TCGOp *op, bool add)
86
- tcg_insn_unit *target;
46
@@ -XXX,XX +XXX,XX @@ static bool fold_addsub2(OptContext *ctx, TCGOp *op, bool add)
87
+ const tcg_insn_unit *target;
47
op->args[4] = arg_new_constant(ctx, bl);
88
int16_t lo;
48
op->args[5] = arg_new_constant(ctx, bh);
89
int32_t hi;
90
91
value += addend;
92
- target = (tcg_insn_unit *)value;
93
+ target = (const tcg_insn_unit *)value;
94
95
switch (type) {
96
case R_PPC_REL14:
97
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
98
static void tcg_out_bc(TCGContext *s, int bc, TCGLabel *l)
99
{
100
if (l->has_value) {
101
- bc |= reloc_pc14_val(s->code_ptr, l->u.value_ptr);
102
+ bc |= reloc_pc14_val(tcg_splitwx_to_rx(s->code_ptr), l->u.value_ptr);
103
} else {
104
tcg_out_reloc(s, s->code_ptr, R_PPC_REL14, l, 0);
105
}
49
}
106
@@ -XXX,XX +XXX,XX @@ static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
50
- return false;
107
label->datahi_reg = datahi_reg;
51
+ return finish_folding(ctx, op);
108
label->addrlo_reg = addrlo_reg;
109
label->addrhi_reg = addrhi_reg;
110
- label->raddr = raddr;
111
+ /* TODO: Cast goes away when all hosts converted */
112
+ label->raddr = (void *)tcg_splitwx_to_rx(raddr);
113
label->label_ptr[0] = lptr;
114
}
52
}
115
53
116
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
54
static bool fold_add2(OptContext *ctx, TCGOp *op)
117
MemOp opc = get_memop(oi);
118
TCGReg hi, lo, arg = TCG_REG_R3;
119
120
- if (!reloc_pc14(lb->label_ptr[0], s->code_ptr)) {
121
+ if (!reloc_pc14(lb->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
122
return false;
123
}
124
125
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
126
MemOp s_bits = opc & MO_SIZE;
127
TCGReg hi, lo, arg = TCG_REG_R3;
128
129
- if (!reloc_pc14(lb->label_ptr[0], s->code_ptr)) {
130
+ if (!reloc_pc14(lb->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
131
return false;
132
}
133
134
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
135
int i;
136
137
#ifdef _CALL_AIX
138
- void **desc = (void **)s->code_ptr;
139
- desc[0] = desc + 2; /* entry point */
140
- desc[1] = 0; /* environment pointer */
141
- s->code_ptr = (void *)(desc + 2); /* skip over descriptor */
142
+ const void **desc = (const void **)s->code_ptr;
143
+ desc[0] = tcg_splitwx_to_rx(desc + 2); /* entry point */
144
+ desc[1] = 0; /* environment pointer */
145
+ s->code_ptr = (void *)(desc + 2); /* skip over descriptor */
146
#endif
147
148
tcg_set_frame(s, TCG_REG_CALL_STACK, REG_SAVE_BOT - CPU_TEMP_BUF_SIZE,
149
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
150
tcg_out32(s, BCCTR | BO_ALWAYS);
151
152
/* Epilogue */
153
- tcg_code_gen_epilogue = tb_ret_addr = s->code_ptr;
154
+ /* TODO: Cast goes away when all hosts converted */
155
+ tcg_code_gen_epilogue = (void *)tcg_splitwx_to_rx(s->code_ptr);
156
157
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_R1, FRAME_SIZE+LR_OFFSET);
158
for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i) {
159
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
160
switch (opc) {
161
case INDEX_op_exit_tb:
162
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R3, args[0]);
163
- tcg_out_b(s, 0, tb_ret_addr);
164
+ tcg_out_b(s, 0, tcg_code_gen_epilogue);
165
break;
166
case INDEX_op_goto_tb:
167
if (s->tb_jmp_insn_offset) {
168
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
169
uint32_t insn = B;
170
171
if (l->has_value) {
172
- insn |= reloc_pc24_val(s->code_ptr, l->u.value_ptr);
173
+ insn |= reloc_pc24_val(tcg_splitwx_to_rx(s->code_ptr),
174
+ l->u.value_ptr);
175
} else {
176
tcg_out_reloc(s, s->code_ptr, R_PPC_REL24, l, 0);
177
}
178
--
55
--
179
2.25.1
56
2.43.0
180
181
diff view generated by jsdifflib
1
Plumb the value through to alloc_code_gen_buffer. This is not
1
Introduce ti_is_const, ti_const_val, ti_is_const_val.
2
supported by any os or tcg backend, so for now enabling it will
3
result in an error.
4
2
5
Reviewed-by: Joelle van Dyne <j@getutm.app>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
4
---
8
include/sysemu/tcg.h | 3 ++-
5
tcg/optimize.c | 20 +++++++++++++++++---
9
tcg/aarch64/tcg-target.h | 1 +
6
1 file changed, 17 insertions(+), 3 deletions(-)
10
tcg/arm/tcg-target.h | 1 +
11
tcg/i386/tcg-target.h | 1 +
12
tcg/mips/tcg-target.h | 1 +
13
tcg/ppc/tcg-target.h | 1 +
14
tcg/riscv/tcg-target.h | 1 +
15
tcg/s390/tcg-target.h | 1 +
16
tcg/sparc/tcg-target.h | 1 +
17
tcg/tci/tcg-target.h | 1 +
18
accel/tcg/tcg-all.c | 26 +++++++++++++++++++++++++-
19
accel/tcg/translate-all.c | 35 +++++++++++++++++++++++++++--------
20
bsd-user/main.c | 2 +-
21
linux-user/main.c | 2 +-
22
qemu-options.hx | 7 +++++++
23
15 files changed, 72 insertions(+), 12 deletions(-)
24
7
25
diff --git a/include/sysemu/tcg.h b/include/sysemu/tcg.h
8
diff --git a/tcg/optimize.c b/tcg/optimize.c
26
index XXXXXXX..XXXXXXX 100644
9
index XXXXXXX..XXXXXXX 100644
27
--- a/include/sysemu/tcg.h
10
--- a/tcg/optimize.c
28
+++ b/include/sysemu/tcg.h
11
+++ b/tcg/optimize.c
29
@@ -XXX,XX +XXX,XX @@
12
@@ -XXX,XX +XXX,XX @@ static inline TempOptInfo *arg_info(TCGArg arg)
30
#ifndef SYSEMU_TCG_H
13
return ts_info(arg_temp(arg));
31
#define SYSEMU_TCG_H
32
33
-void tcg_exec_init(unsigned long tb_size);
34
+void tcg_exec_init(unsigned long tb_size, int splitwx);
35
+
36
#ifdef CONFIG_TCG
37
extern bool tcg_allowed;
38
#define tcg_enabled() (tcg_allowed)
39
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/tcg/aarch64/tcg-target.h
42
+++ b/tcg/aarch64/tcg-target.h
43
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
44
#define TCG_TARGET_NEED_LDST_LABELS
45
#endif
46
#define TCG_TARGET_NEED_POOL_LABELS
47
+#define TCG_TARGET_SUPPORT_MIRROR 0
48
49
#endif /* AARCH64_TCG_TARGET_H */
50
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
51
index XXXXXXX..XXXXXXX 100644
52
--- a/tcg/arm/tcg-target.h
53
+++ b/tcg/arm/tcg-target.h
54
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
55
#define TCG_TARGET_NEED_LDST_LABELS
56
#endif
57
#define TCG_TARGET_NEED_POOL_LABELS
58
+#define TCG_TARGET_SUPPORT_MIRROR 0
59
60
#endif
61
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
62
index XXXXXXX..XXXXXXX 100644
63
--- a/tcg/i386/tcg-target.h
64
+++ b/tcg/i386/tcg-target.h
65
@@ -XXX,XX +XXX,XX @@ static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
66
#define TCG_TARGET_NEED_LDST_LABELS
67
#endif
68
#define TCG_TARGET_NEED_POOL_LABELS
69
+#define TCG_TARGET_SUPPORT_MIRROR 0
70
71
#endif
72
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
73
index XXXXXXX..XXXXXXX 100644
74
--- a/tcg/mips/tcg-target.h
75
+++ b/tcg/mips/tcg-target.h
76
@@ -XXX,XX +XXX,XX @@ extern bool use_mips32r2_instructions;
77
78
#define TCG_TARGET_DEFAULT_MO (0)
79
#define TCG_TARGET_HAS_MEMORY_BSWAP 1
80
+#define TCG_TARGET_SUPPORT_MIRROR 0
81
82
void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
83
84
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
85
index XXXXXXX..XXXXXXX 100644
86
--- a/tcg/ppc/tcg-target.h
87
+++ b/tcg/ppc/tcg-target.h
88
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
89
#define TCG_TARGET_NEED_LDST_LABELS
90
#endif
91
#define TCG_TARGET_NEED_POOL_LABELS
92
+#define TCG_TARGET_SUPPORT_MIRROR 0
93
94
#endif
95
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
96
index XXXXXXX..XXXXXXX 100644
97
--- a/tcg/riscv/tcg-target.h
98
+++ b/tcg/riscv/tcg-target.h
99
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
100
#define TCG_TARGET_NEED_POOL_LABELS
101
102
#define TCG_TARGET_HAS_MEMORY_BSWAP 0
103
+#define TCG_TARGET_SUPPORT_MIRROR 0
104
105
#endif
106
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
107
index XXXXXXX..XXXXXXX 100644
108
--- a/tcg/s390/tcg-target.h
109
+++ b/tcg/s390/tcg-target.h
110
@@ -XXX,XX +XXX,XX @@ static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
111
#define TCG_TARGET_NEED_LDST_LABELS
112
#endif
113
#define TCG_TARGET_NEED_POOL_LABELS
114
+#define TCG_TARGET_SUPPORT_MIRROR 0
115
116
#endif
117
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
118
index XXXXXXX..XXXXXXX 100644
119
--- a/tcg/sparc/tcg-target.h
120
+++ b/tcg/sparc/tcg-target.h
121
@@ -XXX,XX +XXX,XX @@ extern bool use_vis3_instructions;
122
void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
123
124
#define TCG_TARGET_NEED_POOL_LABELS
125
+#define TCG_TARGET_SUPPORT_MIRROR 0
126
127
#endif
128
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
129
index XXXXXXX..XXXXXXX 100644
130
--- a/tcg/tci/tcg-target.h
131
+++ b/tcg/tci/tcg-target.h
132
@@ -XXX,XX +XXX,XX @@ void tci_disas(uint8_t opc);
133
#define TCG_TARGET_DEFAULT_MO (0)
134
135
#define TCG_TARGET_HAS_MEMORY_BSWAP 1
136
+#define TCG_TARGET_SUPPORT_MIRROR 0
137
138
static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
139
uintptr_t jmp_rw, uintptr_t addr)
140
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
141
index XXXXXXX..XXXXXXX 100644
142
--- a/accel/tcg/tcg-all.c
143
+++ b/accel/tcg/tcg-all.c
144
@@ -XXX,XX +XXX,XX @@ struct TCGState {
145
AccelState parent_obj;
146
147
bool mttcg_enabled;
148
+ int splitwx_enabled;
149
unsigned long tb_size;
150
};
151
typedef struct TCGState TCGState;
152
@@ -XXX,XX +XXX,XX @@ static void tcg_accel_instance_init(Object *obj)
153
TCGState *s = TCG_STATE(obj);
154
155
s->mttcg_enabled = default_mttcg_enabled();
156
+
157
+ /* If debugging enabled, default "auto on", otherwise off. */
158
+#ifdef CONFIG_DEBUG_TCG
159
+ s->splitwx_enabled = -1;
160
+#else
161
+ s->splitwx_enabled = 0;
162
+#endif
163
}
14
}
164
15
165
bool mttcg_enabled;
16
+static inline bool ti_is_const(TempOptInfo *ti)
166
@@ -XXX,XX +XXX,XX @@ static int tcg_init(MachineState *ms)
167
{
168
TCGState *s = TCG_STATE(current_accel());
169
170
- tcg_exec_init(s->tb_size * 1024 * 1024);
171
+ tcg_exec_init(s->tb_size * 1024 * 1024, s->splitwx_enabled);
172
mttcg_enabled = s->mttcg_enabled;
173
174
/*
175
@@ -XXX,XX +XXX,XX @@ static void tcg_set_tb_size(Object *obj, Visitor *v,
176
s->tb_size = value;
177
}
178
179
+static bool tcg_get_splitwx(Object *obj, Error **errp)
180
+{
17
+{
181
+ TCGState *s = TCG_STATE(obj);
18
+ return ti->is_const;
182
+ return s->splitwx_enabled;
183
+}
19
+}
184
+
20
+
185
+static void tcg_set_splitwx(Object *obj, bool value, Error **errp)
21
+static inline uint64_t ti_const_val(TempOptInfo *ti)
186
+{
22
+{
187
+ TCGState *s = TCG_STATE(obj);
23
+ return ti->val;
188
+ s->splitwx_enabled = value;
189
+}
24
+}
190
+
25
+
191
static void tcg_accel_class_init(ObjectClass *oc, void *data)
26
+static inline bool ti_is_const_val(TempOptInfo *ti, uint64_t val)
27
+{
28
+ return ti_is_const(ti) && ti_const_val(ti) == val;
29
+}
30
+
31
static inline bool ts_is_const(TCGTemp *ts)
192
{
32
{
193
AccelClass *ac = ACCEL_CLASS(oc);
33
- return ts_info(ts)->is_const;
194
@@ -XXX,XX +XXX,XX @@ static void tcg_accel_class_init(ObjectClass *oc, void *data)
34
+ return ti_is_const(ts_info(ts));
195
object_class_property_set_description(oc, "tb-size",
196
"TCG translation block cache size");
197
198
+ object_class_property_add_bool(oc, "split-wx",
199
+ tcg_get_splitwx, tcg_set_splitwx);
200
+ object_class_property_set_description(oc, "split-wx",
201
+ "Map jit pages into separate RW and RX regions");
202
}
35
}
203
36
204
static const TypeInfo tcg_accel_type = {
37
static inline bool ts_is_const_val(TCGTemp *ts, uint64_t val)
205
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
206
index XXXXXXX..XXXXXXX 100644
207
--- a/accel/tcg/translate-all.c
208
+++ b/accel/tcg/translate-all.c
209
@@ -XXX,XX +XXX,XX @@ static inline void *split_cross_256mb(void *buf1, size_t size1)
210
static uint8_t static_code_gen_buffer[DEFAULT_CODE_GEN_BUFFER_SIZE]
211
__attribute__((aligned(CODE_GEN_ALIGN)));
212
213
-static bool alloc_code_gen_buffer(size_t tb_size, Error **errp)
214
+static bool alloc_code_gen_buffer(size_t tb_size, int splitwx, Error **errp)
215
{
38
{
216
- void *buf = static_code_gen_buffer;
39
- TempOptInfo *ti = ts_info(ts);
217
- void *end = static_code_gen_buffer + sizeof(static_code_gen_buffer);
40
- return ti->is_const && ti->val == val;
218
+ void *buf, *end;
41
+ return ti_is_const_val(ts_info(ts), val);
219
size_t size;
220
221
+ if (splitwx > 0) {
222
+ error_setg(errp, "jit split-wx not supported");
223
+ return false;
224
+ }
225
+
226
/* page-align the beginning and end of the buffer */
227
+ buf = static_code_gen_buffer;
228
+ end = static_code_gen_buffer + sizeof(static_code_gen_buffer);
229
buf = QEMU_ALIGN_PTR_UP(buf, qemu_real_host_page_size);
230
end = QEMU_ALIGN_PTR_DOWN(end, qemu_real_host_page_size);
231
232
@@ -XXX,XX +XXX,XX @@ static bool alloc_code_gen_buffer(size_t tb_size, Error **errp)
233
return true;
234
}
42
}
235
#elif defined(_WIN32)
43
236
-static bool alloc_code_gen_buffer(size_t size, Error **errp)
44
static inline bool arg_is_const(TCGArg arg)
237
+static bool alloc_code_gen_buffer(size_t size, int splitwx, Error **errp)
238
{
239
- void *buf = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT,
240
+ void *buf;
241
+
242
+ if (splitwx > 0) {
243
+ error_setg(errp, "jit split-wx not supported");
244
+ return false;
245
+ }
246
+
247
+ buf = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT,
248
PAGE_EXECUTE_READWRITE);
249
if (buf == NULL) {
250
error_setg_win32(errp, GetLastError(),
251
@@ -XXX,XX +XXX,XX @@ static bool alloc_code_gen_buffer(size_t size, Error **errp)
252
return true;
253
}
254
#else
255
-static bool alloc_code_gen_buffer(size_t size, Error **errp)
256
+static bool alloc_code_gen_buffer(size_t size, int splitwx, Error **errp)
257
{
258
int prot = PROT_WRITE | PROT_READ | PROT_EXEC;
259
int flags = MAP_PRIVATE | MAP_ANONYMOUS;
260
void *buf;
261
262
+ if (splitwx > 0) {
263
+ error_setg(errp, "jit split-wx not supported");
264
+ return false;
265
+ }
266
+
267
buf = mmap(NULL, size, prot, flags, -1, 0);
268
if (buf == MAP_FAILED) {
269
error_setg_errno(errp, errno,
270
@@ -XXX,XX +XXX,XX @@ static void tb_htable_init(void)
271
/* Must be called before using the QEMU cpus. 'tb_size' is the size
272
(in bytes) allocated to the translation buffer. Zero means default
273
size. */
274
-void tcg_exec_init(unsigned long tb_size)
275
+void tcg_exec_init(unsigned long tb_size, int splitwx)
276
{
277
bool ok;
278
279
@@ -XXX,XX +XXX,XX @@ void tcg_exec_init(unsigned long tb_size)
280
page_init();
281
tb_htable_init();
282
283
- ok = alloc_code_gen_buffer(size_code_gen_buffer(tb_size), &error_fatal);
284
+ ok = alloc_code_gen_buffer(size_code_gen_buffer(tb_size),
285
+ splitwx, &error_fatal);
286
assert(ok);
287
288
#if defined(CONFIG_SOFTMMU)
289
diff --git a/bsd-user/main.c b/bsd-user/main.c
290
index XXXXXXX..XXXXXXX 100644
291
--- a/bsd-user/main.c
292
+++ b/bsd-user/main.c
293
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
294
}
295
296
/* init tcg before creating CPUs and to get qemu_host_page_size */
297
- tcg_exec_init(0);
298
+ tcg_exec_init(0, false);
299
300
cpu_type = parse_cpu_option(cpu_model);
301
cpu = cpu_create(cpu_type);
302
diff --git a/linux-user/main.c b/linux-user/main.c
303
index XXXXXXX..XXXXXXX 100644
304
--- a/linux-user/main.c
305
+++ b/linux-user/main.c
306
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
307
cpu_type = parse_cpu_option(cpu_model);
308
309
/* init tcg before creating CPUs and to get qemu_host_page_size */
310
- tcg_exec_init(0);
311
+ tcg_exec_init(0, false);
312
313
cpu = cpu_create(cpu_type);
314
env = cpu->env_ptr;
315
diff --git a/qemu-options.hx b/qemu-options.hx
316
index XXXXXXX..XXXXXXX 100644
317
--- a/qemu-options.hx
318
+++ b/qemu-options.hx
319
@@ -XXX,XX +XXX,XX @@ DEF("accel", HAS_ARG, QEMU_OPTION_accel,
320
" igd-passthru=on|off (enable Xen integrated Intel graphics passthrough, default=off)\n"
321
" kernel-irqchip=on|off|split controls accelerated irqchip support (default=on)\n"
322
" kvm-shadow-mem=size of KVM shadow MMU in bytes\n"
323
+ " split-wx=on|off (enable TCG split w^x mapping)\n"
324
" tb-size=n (TCG translation block cache size)\n"
325
" thread=single|multi (enable multi-threaded TCG)\n", QEMU_ARCH_ALL)
326
SRST
327
@@ -XXX,XX +XXX,XX @@ SRST
328
``kvm-shadow-mem=size``
329
Defines the size of the KVM shadow MMU.
330
331
+ ``split-wx=on|off``
332
+ Controls the use of split w^x mapping for the TCG code generation
333
+ buffer. Some operating systems require this to be enabled, and in
334
+ such a case this will default on. On other operating systems, this
335
+ will default off, but one may enable this for testing or debugging.
336
+
337
``tb-size=n``
338
Controls the size (in MiB) of the TCG translation block cache.
339
340
--
45
--
341
2.25.1
46
2.43.0
342
343
diff view generated by jsdifflib
1
The offset even checks were folded into the range check incorrectly.
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
2
By offsetting by 1, and not decrementing the width, we silently
2
Sink mask computation below fold_affected_mask early exit.
3
allowed out of range branches.
4
3
5
Assert that the offset is always even instead. Move tcg_out_goto
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
6
down into the CONFIG_SOFTMMU block so that it is not unused.
7
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
6
---
11
tcg/riscv/tcg-target.c.inc | 28 +++++++++++++++-------------
7
tcg/optimize.c | 30 ++++++++++++++++--------------
12
1 file changed, 15 insertions(+), 13 deletions(-)
8
1 file changed, 16 insertions(+), 14 deletions(-)
13
9
14
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
15
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
16
--- a/tcg/riscv/tcg-target.c.inc
12
--- a/tcg/optimize.c
17
+++ b/tcg/riscv/tcg-target.c.inc
13
+++ b/tcg/optimize.c
18
@@ -XXX,XX +XXX,XX @@ static bool reloc_sbimm12(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
14
@@ -XXX,XX +XXX,XX @@ static bool fold_add2(OptContext *ctx, TCGOp *op)
15
16
static bool fold_and(OptContext *ctx, TCGOp *op)
19
{
17
{
20
intptr_t offset = (intptr_t)target - (intptr_t)code_ptr;
18
- uint64_t z1, z2;
21
19
+ uint64_t z1, z2, z_mask, s_mask;
22
- if (offset == sextreg(offset, 1, 12) << 1) {
20
+ TempOptInfo *t1, *t2;
23
+ tcg_debug_assert((offset & 1) == 0);
21
24
+ if (offset == sextreg(offset, 0, 12)) {
22
if (fold_const2_commutative(ctx, op) ||
25
code_ptr[0] |= encode_sbimm12(offset);
23
fold_xi_to_i(ctx, op, 0) ||
24
@@ -XXX,XX +XXX,XX @@ static bool fold_and(OptContext *ctx, TCGOp *op)
26
return true;
25
return true;
27
}
26
}
28
@@ -XXX,XX +XXX,XX @@ static bool reloc_jimm20(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
27
29
{
28
- z1 = arg_info(op->args[1])->z_mask;
30
intptr_t offset = (intptr_t)target - (intptr_t)code_ptr;
29
- z2 = arg_info(op->args[2])->z_mask;
31
30
- ctx->z_mask = z1 & z2;
32
- if (offset == sextreg(offset, 1, 20) << 1) {
31
-
33
+ tcg_debug_assert((offset & 1) == 0);
32
- /*
34
+ if (offset == sextreg(offset, 0, 20)) {
33
- * Sign repetitions are perforce all identical, whether they are 1 or 0.
35
code_ptr[0] |= encode_ujimm20(offset);
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)) {
36
return true;
50
return true;
37
}
51
}
38
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
52
39
g_assert_not_reached();
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);
40
}
63
}
41
64
42
-static inline void tcg_out_goto(TCGContext *s, tcg_insn_unit *target)
65
static bool fold_andc(OptContext *ctx, TCGOp *op)
43
-{
44
- ptrdiff_t offset = tcg_pcrel_diff(s, target);
45
- tcg_debug_assert(offset == sextreg(offset, 1, 20) << 1);
46
- tcg_out_opc_jump(s, OPC_JAL, TCG_REG_ZERO, offset);
47
-}
48
-
49
static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail)
50
{
51
TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA;
52
ptrdiff_t offset = tcg_pcrel_diff(s, arg);
53
int ret;
54
55
- if (offset == sextreg(offset, 1, 20) << 1) {
56
+ tcg_debug_assert((offset & 1) == 0);
57
+ if (offset == sextreg(offset, 0, 20)) {
58
/* short jump: -2097150 to 2097152 */
59
tcg_out_opc_jump(s, OPC_JAL, link, offset);
60
- } else if (TCG_TARGET_REG_BITS == 32 ||
61
- offset == sextreg(offset, 1, 31) << 1) {
62
+ } else if (TCG_TARGET_REG_BITS == 32 || offset == (int32_t)offset) {
63
/* long jump: -2147483646 to 2147483648 */
64
tcg_out_opc_upper(s, OPC_AUIPC, TCG_REG_TMP0, 0);
65
tcg_out_opc_imm(s, OPC_JALR, link, TCG_REG_TMP0, 0);
66
- ret = reloc_call(s->code_ptr - 2, arg);\
67
+ ret = reloc_call(s->code_ptr - 2, arg);
68
tcg_debug_assert(ret == true);
69
} else if (TCG_TARGET_REG_BITS == 64) {
70
/* far jump: 64-bit */
71
@@ -XXX,XX +XXX,XX @@ QEMU_BUILD_BUG_ON(TCG_TARGET_REG_BITS < TARGET_LONG_BITS);
72
QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
73
QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 11));
74
75
+static void tcg_out_goto(TCGContext *s, tcg_insn_unit *target)
76
+{
77
+ tcg_out_opc_jump(s, OPC_JAL, TCG_REG_ZERO, 0);
78
+ bool ok = reloc_jimm20(s->code_ptr - 1, target);
79
+ tcg_debug_assert(ok);
80
+}
81
+
82
static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
83
TCGReg addrh, TCGMemOpIdx oi,
84
tcg_insn_unit **label_ptr, bool is_load)
85
--
66
--
86
2.25.1
67
2.43.0
87
88
diff view generated by jsdifflib
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
2
Avoid double inversion of the value of second const operand.
3
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
1
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
---
6
---
3
tcg/s390/tcg-target.h | 2 +-
7
tcg/optimize.c | 21 +++++++++++----------
4
tcg/s390/tcg-target.c.inc | 69 +++++++++++++++++----------------------
8
1 file changed, 11 insertions(+), 10 deletions(-)
5
2 files changed, 31 insertions(+), 40 deletions(-)
6
9
7
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
8
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/s390/tcg-target.h
12
--- a/tcg/optimize.c
10
+++ b/tcg/s390/tcg-target.h
13
+++ b/tcg/optimize.c
11
@@ -XXX,XX +XXX,XX @@ static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
14
@@ -XXX,XX +XXX,XX @@ static bool fold_and(OptContext *ctx, TCGOp *op)
12
#define TCG_TARGET_NEED_LDST_LABELS
15
13
#endif
16
static bool fold_andc(OptContext *ctx, TCGOp *op)
14
#define TCG_TARGET_NEED_POOL_LABELS
15
-#define TCG_TARGET_SUPPORT_MIRROR 0
16
+#define TCG_TARGET_SUPPORT_MIRROR 1
17
18
#endif
19
diff --git a/tcg/s390/tcg-target.c.inc b/tcg/s390/tcg-target.c.inc
20
index XXXXXXX..XXXXXXX 100644
21
--- a/tcg/s390/tcg-target.c.inc
22
+++ b/tcg/s390/tcg-target.c.inc
23
@@ -XXX,XX +XXX,XX @@ static void * const qemu_st_helpers[16] = {
24
};
25
#endif
26
27
-static tcg_insn_unit *tb_ret_addr;
28
+static const tcg_insn_unit *tb_ret_addr;
29
uint64_t s390_facilities;
30
31
-static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
32
+static bool patch_reloc(tcg_insn_unit *src_rw, int type,
33
intptr_t value, intptr_t addend)
34
{
17
{
35
+ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
18
- uint64_t z1;
36
intptr_t pcrel2;
19
+ uint64_t z_mask, s_mask;
37
uint32_t old;
20
+ TempOptInfo *t1, *t2;
38
21
39
value += addend;
22
if (fold_const2(ctx, op) ||
40
- pcrel2 = (tcg_insn_unit *)value - code_ptr;
23
fold_xx_to_i(ctx, op, 0) ||
41
+ pcrel2 = (tcg_insn_unit *)value - src_rx;
24
@@ -XXX,XX +XXX,XX @@ static bool fold_andc(OptContext *ctx, TCGOp *op)
42
25
return true;
43
switch (type) {
26
}
44
case R_390_PC16DBL:
27
45
if (pcrel2 == (int16_t)pcrel2) {
28
- z1 = arg_info(op->args[1])->z_mask;
46
- tcg_patch16(code_ptr, pcrel2);
29
+ t1 = arg_info(op->args[1]);
47
+ tcg_patch16(src_rw, pcrel2);
30
+ t2 = arg_info(op->args[2]);
31
+ z_mask = t1->z_mask;
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)) {
48
return true;
43
return true;
49
}
44
}
50
break;
45
- z1 &= z2;
51
case R_390_PC32DBL:
46
+ z_mask &= ~v2;
52
if (pcrel2 == (int32_t)pcrel2) {
47
}
53
- tcg_patch32(code_ptr, pcrel2);
48
- ctx->z_mask = z1;
54
+ tcg_patch32(src_rw, pcrel2);
49
55
return true;
50
- ctx->s_mask = arg_info(op->args[1])->s_mask
56
}
51
- & arg_info(op->args[2])->s_mask;
57
break;
52
- return fold_masks(ctx, op);
58
case R_390_20:
53
+ s_mask = t1->s_mask & t2->s_mask;
59
if (value == sextract64(value, 0, 20)) {
54
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
60
- old = *(uint32_t *)code_ptr & 0xf00000ff;
61
+ old = *(uint32_t *)src_rw & 0xf00000ff;
62
old |= ((value & 0xfff) << 16) | ((value & 0xff000) >> 4);
63
- tcg_patch32(code_ptr, old);
64
+ tcg_patch32(src_rw, old);
65
return true;
66
}
67
break;
68
@@ -XXX,XX +XXX,XX @@ static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
69
}
55
}
70
56
71
/* load data from an absolute host address */
57
static bool fold_brcond(OptContext *ctx, TCGOp *op)
72
-static void tcg_out_ld_abs(TCGContext *s, TCGType type, TCGReg dest, void *abs)
73
+static void tcg_out_ld_abs(TCGContext *s, TCGType type,
74
+ TCGReg dest, const void *abs)
75
{
76
intptr_t addr = (intptr_t)abs;
77
78
@@ -XXX,XX +XXX,XX @@ static void tgen_extract(TCGContext *s, TCGReg dest, TCGReg src,
79
80
static void tgen_gotoi(TCGContext *s, int cc, const tcg_insn_unit *dest)
81
{
82
- ptrdiff_t off = dest - s->code_ptr;
83
+ ptrdiff_t off = tcg_pcrel_diff(s, dest) >> 1;
84
if (off == (int16_t)off) {
85
tcg_out_insn(s, RI, BRC, cc, off);
86
} else if (off == (int32_t)off) {
87
@@ -XXX,XX +XXX,XX @@ static void tgen_branch(TCGContext *s, int cc, TCGLabel *l)
88
static void tgen_compare_branch(TCGContext *s, S390Opcode opc, int cc,
89
TCGReg r1, TCGReg r2, TCGLabel *l)
90
{
91
- intptr_t off = 0;
92
-
93
- if (l->has_value) {
94
- off = l->u.value_ptr - s->code_ptr;
95
- tcg_debug_assert(off == (int16_t)off);
96
- } else {
97
- tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, 2);
98
- }
99
-
100
+ tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, 2);
101
tcg_out16(s, (opc & 0xff00) | (r1 << 4) | r2);
102
- tcg_out16(s, off);
103
+ tcg_out16(s, 0);
104
tcg_out16(s, cc << 12 | (opc & 0xff));
105
}
106
107
static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,
108
TCGReg r1, int i2, TCGLabel *l)
109
{
110
- tcg_target_long off = 0;
111
-
112
- if (l->has_value) {
113
- off = l->u.value_ptr - s->code_ptr;
114
- tcg_debug_assert(off == (int16_t)off);
115
- } else {
116
- tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, 2);
117
- }
118
-
119
+ tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, 2);
120
tcg_out16(s, (opc & 0xff00) | (r1 << 4) | cc);
121
- tcg_out16(s, off);
122
+ tcg_out16(s, 0);
123
tcg_out16(s, (i2 << 8) | (opc & 0xff));
124
}
125
126
@@ -XXX,XX +XXX,XX @@ static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
127
128
static void tcg_out_call(TCGContext *s, const tcg_insn_unit *dest)
129
{
130
- ptrdiff_t off = dest - s->code_ptr;
131
+ ptrdiff_t off = tcg_pcrel_diff(s, dest) >> 1;
132
if (off == (int32_t)off) {
133
tcg_out_insn(s, RIL, BRASL, TCG_REG_R14, off);
134
} else {
135
@@ -XXX,XX +XXX,XX @@ static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
136
label->oi = oi;
137
label->datalo_reg = data;
138
label->addrlo_reg = addr;
139
- label->raddr = raddr;
140
+ /* TODO: Cast goes away when all hosts converted */
141
+ label->raddr = (void *)tcg_splitwx_to_rx(raddr);
142
label->label_ptr[0] = label_ptr;
143
}
144
145
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
146
MemOp opc = get_memop(oi);
147
148
if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
149
- (intptr_t)s->code_ptr, 2)) {
150
+ (intptr_t)tcg_splitwx_to_rx(s->code_ptr), 2)) {
151
return false;
152
}
153
154
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
155
MemOp opc = get_memop(oi);
156
157
if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
158
- (intptr_t)s->code_ptr, 2)) {
159
+ (intptr_t)tcg_splitwx_to_rx(s->code_ptr), 2)) {
160
return false;
161
}
162
163
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
164
case INDEX_op_goto_tb:
165
a0 = args[0];
166
if (s->tb_jmp_insn_offset) {
167
- /* branch displacement must be aligned for atomic patching;
168
+ /*
169
+ * branch displacement must be aligned for atomic patching;
170
* see if we need to add extra nop before branch
171
*/
172
if (!QEMU_PTR_IS_ALIGNED(s->code_ptr + 1, 4)) {
173
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
174
} else {
175
/* load address stored at s->tb_jmp_target_addr + a0 */
176
tcg_out_ld_abs(s, TCG_TYPE_PTR, TCG_REG_TB,
177
- s->tb_jmp_target_addr + a0);
178
+ tcg_splitwx_to_rx(s->tb_jmp_target_addr + a0));
179
/* and go there */
180
tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_TB);
181
}
182
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
183
TCG_REG_TB to the beginning of this TB. */
184
if (USE_REG_TB) {
185
int ofs = -tcg_current_code_size(s);
186
- assert(ofs == (int16_t)ofs);
187
- tcg_out_insn(s, RI, AGHI, TCG_REG_TB, ofs);
188
+ /* All TB are restricted to 64KiB by unwind info. */
189
+ tcg_debug_assert(ofs == sextract64(ofs, 0, 20));
190
+ tcg_out_insn(s, RXY, LAY, TCG_REG_TB,
191
+ TCG_REG_TB, TCG_REG_NONE, ofs);
192
}
193
break;
194
195
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
196
* Return path for goto_ptr. Set return value to 0, a-la exit_tb,
197
* and fall through to the rest of the epilogue.
198
*/
199
- tcg_code_gen_epilogue = s->code_ptr;
200
+ /* TODO: Cast goes away when all hosts converted */
201
+ tcg_code_gen_epilogue = (void *)tcg_splitwx_to_rx(s->code_ptr);
202
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, 0);
203
204
/* TB epilogue */
205
- tb_ret_addr = s->code_ptr;
206
+ tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr);
207
208
/* lmg %r6,%r15,fs+48(%r15) (restore registers) */
209
tcg_out_insn(s, RXY, LMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15,
210
--
58
--
211
2.25.1
59
2.43.0
212
213
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
Now that all native tcg hosts support splitwx, remove the define.
1
Add fold_masks_z as a trivial wrapper around fold_masks_zs.
2
Replace the one use with a test for CONFIG_TCG_INTERPRETER.
2
Avoid the use of the OptContext slots.
3
3
4
Reviewed-by: Joelle van Dyne <j@getutm.app>
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
6
---
7
tcg/aarch64/tcg-target.h | 1 -
7
tcg/optimize.c | 13 ++++++++++---
8
tcg/arm/tcg-target.h | 1 -
8
1 file changed, 10 insertions(+), 3 deletions(-)
9
tcg/i386/tcg-target.h | 1 -
10
tcg/mips/tcg-target.h | 1 -
11
tcg/ppc/tcg-target.h | 1 -
12
tcg/riscv/tcg-target.h | 1 -
13
tcg/s390/tcg-target.h | 1 -
14
tcg/sparc/tcg-target.h | 1 -
15
tcg/tci/tcg-target.h | 1 -
16
accel/tcg/translate-all.c | 16 +++++++++-------
17
10 files changed, 9 insertions(+), 16 deletions(-)
18
9
19
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
20
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
21
--- a/tcg/aarch64/tcg-target.h
12
--- a/tcg/optimize.c
22
+++ b/tcg/aarch64/tcg-target.h
13
+++ b/tcg/optimize.c
23
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
14
@@ -XXX,XX +XXX,XX @@ static bool fold_masks_zs(OptContext *ctx, TCGOp *op,
24
#define TCG_TARGET_NEED_LDST_LABELS
25
#endif
26
#define TCG_TARGET_NEED_POOL_LABELS
27
-#define TCG_TARGET_SUPPORT_MIRROR 1
28
29
#endif /* AARCH64_TCG_TARGET_H */
30
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/tcg/arm/tcg-target.h
33
+++ b/tcg/arm/tcg-target.h
34
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
35
#define TCG_TARGET_NEED_LDST_LABELS
36
#endif
37
#define TCG_TARGET_NEED_POOL_LABELS
38
-#define TCG_TARGET_SUPPORT_MIRROR 1
39
40
#endif
41
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
42
index XXXXXXX..XXXXXXX 100644
43
--- a/tcg/i386/tcg-target.h
44
+++ b/tcg/i386/tcg-target.h
45
@@ -XXX,XX +XXX,XX @@ static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
46
#define TCG_TARGET_NEED_LDST_LABELS
47
#endif
48
#define TCG_TARGET_NEED_POOL_LABELS
49
-#define TCG_TARGET_SUPPORT_MIRROR 1
50
51
#endif
52
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
53
index XXXXXXX..XXXXXXX 100644
54
--- a/tcg/mips/tcg-target.h
55
+++ b/tcg/mips/tcg-target.h
56
@@ -XXX,XX +XXX,XX @@ extern bool use_mips32r2_instructions;
57
58
#define TCG_TARGET_DEFAULT_MO (0)
59
#define TCG_TARGET_HAS_MEMORY_BSWAP 1
60
-#define TCG_TARGET_SUPPORT_MIRROR 1
61
62
void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
63
64
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
65
index XXXXXXX..XXXXXXX 100644
66
--- a/tcg/ppc/tcg-target.h
67
+++ b/tcg/ppc/tcg-target.h
68
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
69
#define TCG_TARGET_NEED_LDST_LABELS
70
#endif
71
#define TCG_TARGET_NEED_POOL_LABELS
72
-#define TCG_TARGET_SUPPORT_MIRROR 1
73
74
#endif
75
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
76
index XXXXXXX..XXXXXXX 100644
77
--- a/tcg/riscv/tcg-target.h
78
+++ b/tcg/riscv/tcg-target.h
79
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
80
#define TCG_TARGET_NEED_POOL_LABELS
81
82
#define TCG_TARGET_HAS_MEMORY_BSWAP 0
83
-#define TCG_TARGET_SUPPORT_MIRROR 1
84
85
#endif
86
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
87
index XXXXXXX..XXXXXXX 100644
88
--- a/tcg/s390/tcg-target.h
89
+++ b/tcg/s390/tcg-target.h
90
@@ -XXX,XX +XXX,XX @@ static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
91
#define TCG_TARGET_NEED_LDST_LABELS
92
#endif
93
#define TCG_TARGET_NEED_POOL_LABELS
94
-#define TCG_TARGET_SUPPORT_MIRROR 1
95
96
#endif
97
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
98
index XXXXXXX..XXXXXXX 100644
99
--- a/tcg/sparc/tcg-target.h
100
+++ b/tcg/sparc/tcg-target.h
101
@@ -XXX,XX +XXX,XX @@ extern bool use_vis3_instructions;
102
void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
103
104
#define TCG_TARGET_NEED_POOL_LABELS
105
-#define TCG_TARGET_SUPPORT_MIRROR 1
106
107
#endif
108
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
109
index XXXXXXX..XXXXXXX 100644
110
--- a/tcg/tci/tcg-target.h
111
+++ b/tcg/tci/tcg-target.h
112
@@ -XXX,XX +XXX,XX @@ void tci_disas(uint8_t opc);
113
#define TCG_TARGET_DEFAULT_MO (0)
114
115
#define TCG_TARGET_HAS_MEMORY_BSWAP 1
116
-#define TCG_TARGET_SUPPORT_MIRROR 0
117
118
static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
119
uintptr_t jmp_rw, uintptr_t addr)
120
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
121
index XXXXXXX..XXXXXXX 100644
122
--- a/accel/tcg/translate-all.c
123
+++ b/accel/tcg/translate-all.c
124
@@ -XXX,XX +XXX,XX @@ static bool alloc_code_gen_buffer_anon(size_t size, int prot,
125
return true;
15
return true;
126
}
16
}
127
17
128
+#ifndef CONFIG_TCG_INTERPRETER
18
+static bool fold_masks_z(OptContext *ctx, TCGOp *op, uint64_t z_mask)
129
#ifdef CONFIG_POSIX
19
+{
130
#include "qemu/memfd.h"
20
+ return fold_masks_zs(ctx, op, z_mask, 0);
131
21
+}
132
@@ -XXX,XX +XXX,XX @@ static bool alloc_code_gen_buffer_splitwx_vmremap(size_t size, Error **errp)
22
+
133
return true;
23
static bool fold_masks(OptContext *ctx, TCGOp *op)
24
{
25
return fold_masks_zs(ctx, op, ctx->z_mask, ctx->s_mask);
26
@@ -XXX,XX +XXX,XX @@ static bool fold_count_zeros(OptContext *ctx, TCGOp *op)
27
28
static bool fold_ctpop(OptContext *ctx, TCGOp *op)
29
{
30
+ uint64_t z_mask;
31
+
32
if (fold_const1(ctx, op)) {
33
return true;
34
}
35
36
switch (ctx->type) {
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);
134
}
50
}
135
#endif /* CONFIG_DARWIN */
51
136
+#endif /* CONFIG_TCG_INTERPRETER */
52
static bool fold_deposit(OptContext *ctx, TCGOp *op)
137
138
static bool alloc_code_gen_buffer_splitwx(size_t size, Error **errp)
139
{
140
- if (TCG_TARGET_SUPPORT_MIRROR) {
141
-#ifdef CONFIG_DARWIN
142
- return alloc_code_gen_buffer_splitwx_vmremap(size, errp);
143
+#ifndef CONFIG_TCG_INTERPRETER
144
+# ifdef CONFIG_DARWIN
145
+ return alloc_code_gen_buffer_splitwx_vmremap(size, errp);
146
+# endif
147
+# ifdef CONFIG_POSIX
148
+ return alloc_code_gen_buffer_splitwx_memfd(size, errp);
149
+# endif
150
#endif
151
-#ifdef CONFIG_POSIX
152
- return alloc_code_gen_buffer_splitwx_memfd(size, errp);
153
-#endif
154
- }
155
error_setg(errp, "jit split-wx not supported");
156
return false;
157
}
158
--
53
--
159
2.25.1
54
2.43.0
160
161
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
Cribbed from code posted by Joelle van Dyne <j@getutm.app>,
1
The input which overlaps the sign bit of the output can
2
and rearranged to a cleaner structure.
2
have its input s_mask propagated to the output s_mask.
3
3
4
Reviewed-by: Joelle van Dyne <j@getutm.app>
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
6
---
7
accel/tcg/translate-all.c | 67 +++++++++++++++++++++++++++++++++++++++
7
tcg/optimize.c | 14 ++++++++++++--
8
1 file changed, 67 insertions(+)
8
1 file changed, 12 insertions(+), 2 deletions(-)
9
9
10
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
11
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
12
--- a/accel/tcg/translate-all.c
12
--- a/tcg/optimize.c
13
+++ b/accel/tcg/translate-all.c
13
+++ b/tcg/optimize.c
14
@@ -XXX,XX +XXX,XX @@ static bool alloc_code_gen_buffer_splitwx_memfd(size_t size, Error **errp)
14
@@ -XXX,XX +XXX,XX @@ static bool fold_deposit(OptContext *ctx, TCGOp *op)
15
}
15
TempOptInfo *t2 = arg_info(op->args[2]);
16
#endif /* CONFIG_POSIX */
16
int ofs = op->args[3];
17
17
int len = op->args[4];
18
+#ifdef CONFIG_DARWIN
18
+ int width;
19
+#include <mach/mach.h>
19
TCGOpcode and_opc;
20
+
20
- uint64_t z_mask;
21
+extern kern_return_t mach_vm_remap(vm_map_t target_task,
21
+ uint64_t z_mask, s_mask;
22
+ mach_vm_address_t *target_address,
22
23
+ mach_vm_size_t size,
23
if (ti_is_const(t1) && ti_is_const(t2)) {
24
+ mach_vm_offset_t mask,
24
return tcg_opt_gen_movi(ctx, op, op->args[0],
25
+ int flags,
25
@@ -XXX,XX +XXX,XX @@ static bool fold_deposit(OptContext *ctx, TCGOp *op)
26
+ vm_map_t src_task,
26
switch (ctx->type) {
27
+ mach_vm_address_t src_address,
27
case TCG_TYPE_I32:
28
+ boolean_t copy,
28
and_opc = INDEX_op_and_i32;
29
+ vm_prot_t *cur_protection,
29
+ width = 32;
30
+ vm_prot_t *max_protection,
30
break;
31
+ vm_inherit_t inheritance);
31
case TCG_TYPE_I64:
32
+
32
and_opc = INDEX_op_and_i64;
33
+static bool alloc_code_gen_buffer_splitwx_vmremap(size_t size, Error **errp)
33
+ width = 64;
34
+{
34
break;
35
+ kern_return_t ret;
35
default:
36
+ mach_vm_address_t buf_rw, buf_rx;
36
g_assert_not_reached();
37
+ vm_prot_t cur_prot, max_prot;
37
@@ -XXX,XX +XXX,XX @@ static bool fold_deposit(OptContext *ctx, TCGOp *op)
38
+
38
return fold_and(ctx, op);
39
+ /* Map the read-write portion via normal anon memory. */
39
}
40
+ if (!alloc_code_gen_buffer_anon(size, PROT_READ | PROT_WRITE,
40
41
+ MAP_PRIVATE | MAP_ANONYMOUS, errp)) {
41
+ /* The s_mask from the top portion of the deposit is still valid. */
42
+ return false;
42
+ if (ofs + len == width) {
43
+ s_mask = t2->s_mask << ofs;
44
+ } else {
45
+ s_mask = t1->s_mask & ~MAKE_64BIT_MASK(0, ofs + len);
43
+ }
46
+ }
44
+
47
+
45
+ buf_rw = (mach_vm_address_t)tcg_ctx->code_gen_buffer;
48
z_mask = deposit64(t1->z_mask, ofs, len, t2->z_mask);
46
+ buf_rx = 0;
49
- return fold_masks_z(ctx, op, z_mask);
47
+ ret = mach_vm_remap(mach_task_self(),
50
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
48
+ &buf_rx,
51
}
49
+ size,
52
50
+ 0,
53
static bool fold_divide(OptContext *ctx, TCGOp *op)
51
+ VM_FLAGS_ANYWHERE,
52
+ mach_task_self(),
53
+ buf_rw,
54
+ false,
55
+ &cur_prot,
56
+ &max_prot,
57
+ VM_INHERIT_NONE);
58
+ if (ret != KERN_SUCCESS) {
59
+ /* TODO: Convert "ret" to a human readable error message. */
60
+ error_setg(errp, "vm_remap for jit splitwx failed");
61
+ munmap((void *)buf_rw, size);
62
+ return false;
63
+ }
64
+
65
+ if (mprotect((void *)buf_rx, size, PROT_READ | PROT_EXEC) != 0) {
66
+ error_setg_errno(errp, errno, "mprotect for jit splitwx");
67
+ munmap((void *)buf_rx, size);
68
+ munmap((void *)buf_rw, size);
69
+ return false;
70
+ }
71
+
72
+ tcg_splitwx_diff = buf_rx - buf_rw;
73
+ return true;
74
+}
75
+#endif /* CONFIG_DARWIN */
76
+
77
static bool alloc_code_gen_buffer_splitwx(size_t size, Error **errp)
78
{
79
if (TCG_TARGET_SUPPORT_MIRROR) {
80
+#ifdef CONFIG_DARWIN
81
+ return alloc_code_gen_buffer_splitwx_vmremap(size, errp);
82
+#endif
83
#ifdef CONFIG_POSIX
84
return alloc_code_gen_buffer_splitwx_memfd(size, errp);
85
#endif
86
@@ -XXX,XX +XXX,XX @@ static bool alloc_code_gen_buffer(size_t size, int splitwx, Error **errp)
87
#ifdef CONFIG_TCG_INTERPRETER
88
/* The tcg interpreter does not need execute permission. */
89
prot = PROT_READ | PROT_WRITE;
90
+#elif defined(CONFIG_DARWIN)
91
+ /* Applicable to both iOS and macOS (Apple Silicon). */
92
+ if (!splitwx) {
93
+ flags |= MAP_JIT;
94
+ }
95
#endif
96
97
return alloc_code_gen_buffer_anon(size, prot, flags, errp);
98
--
54
--
99
2.25.1
55
2.43.0
100
101
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
1
Reviewed-by: Joelle van Dyne <j@getutm.app>
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
3
---
5
include/disas/dis-asm.h | 4 ++--
4
tcg/optimize.c | 4 ++--
6
disas.c | 4 +---
5
1 file changed, 2 insertions(+), 2 deletions(-)
7
disas/capstone.c | 2 +-
8
3 files changed, 4 insertions(+), 6 deletions(-)
9
6
10
diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
11
index XXXXXXX..XXXXXXX 100644
8
index XXXXXXX..XXXXXXX 100644
12
--- a/include/disas/dis-asm.h
9
--- a/tcg/optimize.c
13
+++ b/include/disas/dis-asm.h
10
+++ b/tcg/optimize.c
14
@@ -XXX,XX +XXX,XX @@ typedef struct disassemble_info {
11
@@ -XXX,XX +XXX,XX @@ static bool fold_dup(OptContext *ctx, TCGOp *op)
15
(bfd_vma addr, struct disassemble_info * info);
12
t = dup_const(TCGOP_VECE(op), t);
16
13
return tcg_opt_gen_movi(ctx, op, op->args[0], t);
17
/* These are for buffer_read_memory. */
14
}
18
- bfd_byte *buffer;
15
- return false;
19
+ const bfd_byte *buffer;
16
+ return finish_folding(ctx, op);
20
bfd_vma buffer_vma;
21
int buffer_length;
22
23
@@ -XXX,XX +XXX,XX @@ int print_insn_rx(bfd_vma, disassemble_info *);
24
25
#ifdef CONFIG_CAPSTONE
26
bool cap_disas_target(disassemble_info *info, uint64_t pc, size_t size);
27
-bool cap_disas_host(disassemble_info *info, void *code, size_t size);
28
+bool cap_disas_host(disassemble_info *info, const void *code, size_t size);
29
bool cap_disas_monitor(disassemble_info *info, uint64_t pc, int count);
30
bool cap_disas_plugin(disassemble_info *info, uint64_t pc, size_t size);
31
#else
32
diff --git a/disas.c b/disas.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/disas.c
35
+++ b/disas.c
36
@@ -XXX,XX +XXX,XX @@ char *plugin_disas(CPUState *cpu, uint64_t addr, size_t size)
37
}
17
}
38
18
39
/* Disassemble this for me please... (debugging). */
19
static bool fold_dup2(OptContext *ctx, TCGOp *op)
40
-void disas(FILE *out, const void *ccode, unsigned long size)
20
@@ -XXX,XX +XXX,XX @@ static bool fold_dup2(OptContext *ctx, TCGOp *op)
41
+void disas(FILE *out, const void *code, unsigned long size)
21
op->opc = INDEX_op_dup_vec;
42
{
22
TCGOP_VECE(op) = MO_32;
43
- /* TODO: Push constness through the disas backends. */
23
}
44
- void *code = (void *)ccode;
24
- return false;
45
uintptr_t pc;
25
+ return finish_folding(ctx, op);
46
int count;
47
CPUDebug s;
48
diff --git a/disas/capstone.c b/disas/capstone.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/disas/capstone.c
51
+++ b/disas/capstone.c
52
@@ -XXX,XX +XXX,XX @@ bool cap_disas_target(disassemble_info *info, uint64_t pc, size_t size)
53
}
26
}
54
27
55
/* Disassemble SIZE bytes at CODE for the host. */
28
static bool fold_eqv(OptContext *ctx, TCGOp *op)
56
-bool cap_disas_host(disassemble_info *info, void *code, size_t size)
57
+bool cap_disas_host(disassemble_info *info, const void *code, size_t size)
58
{
59
csh handle;
60
const uint8_t *cbuf;
61
--
29
--
62
2.25.1
30
2.43.0
63
64
diff view generated by jsdifflib
1
Add fold_masks_s as a trivial wrapper around fold_masks_zs.
2
Avoid the use of the OptContext slots.
3
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
1
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
---
6
---
3
tcg/sparc/tcg-target.c.inc | 15 +++++++--------
7
tcg/optimize.c | 13 ++++++++++---
4
1 file changed, 7 insertions(+), 8 deletions(-)
8
1 file changed, 10 insertions(+), 3 deletions(-)
5
9
6
diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc/tcg-target.c.inc
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
7
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
8
--- a/tcg/sparc/tcg-target.c.inc
12
--- a/tcg/optimize.c
9
+++ b/tcg/sparc/tcg-target.c.inc
13
+++ b/tcg/optimize.c
10
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret,
14
@@ -XXX,XX +XXX,XX @@ static bool fold_masks_z(OptContext *ctx, TCGOp *op, uint64_t z_mask)
11
15
return fold_masks_zs(ctx, op, z_mask, 0);
12
/* A 13-bit constant relative to the TB. */
13
if (!in_prologue && USE_REG_TB) {
14
- test = arg - (uintptr_t)s->code_gen_ptr;
15
+ test = tcg_tbrel_diff(s, (void *)arg);
16
if (check_fit_ptr(test, 13)) {
17
tcg_out_arithi(s, ret, TCG_REG_TB, test, ARITH_ADD);
18
return;
19
@@ -XXX,XX +XXX,XX @@ static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
20
return false;
21
}
16
}
22
17
23
-static void tcg_out_ld_ptr(TCGContext *s, TCGReg ret, uintptr_t arg)
18
+static bool fold_masks_s(OptContext *ctx, TCGOp *op, uint64_t s_mask)
24
+static void tcg_out_ld_ptr(TCGContext *s, TCGReg ret, const void *arg)
19
+{
20
+ return fold_masks_zs(ctx, op, -1, s_mask);
21
+}
22
+
23
static bool fold_masks(OptContext *ctx, TCGOp *op)
25
{
24
{
26
- intptr_t diff = arg - (uintptr_t)s->code_gen_ptr;
25
return fold_masks_zs(ctx, op, ctx->z_mask, ctx->s_mask);
27
+ intptr_t diff = tcg_tbrel_diff(s, arg);
26
@@ -XXX,XX +XXX,XX @@ static bool fold_dup2(OptContext *ctx, TCGOp *op)
28
if (USE_REG_TB && check_fit_ptr(diff, 13)) {
27
29
tcg_out_ld(s, TCG_TYPE_PTR, ret, TCG_REG_TB, diff);
28
static bool fold_eqv(OptContext *ctx, TCGOp *op)
30
return;
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;
31
}
36
}
32
- tcg_out_movi(s, TCG_TYPE_PTR, ret, arg & ~0x3ff);
37
33
- tcg_out_ld(s, TCG_TYPE_PTR, ret, ret, arg & 0x3ff);
38
- ctx->s_mask = arg_info(op->args[1])->s_mask
34
+ tcg_out_movi(s, TCG_TYPE_PTR, ret, (uintptr_t)arg & ~0x3ff);
39
- & arg_info(op->args[2])->s_mask;
35
+ tcg_out_ld(s, TCG_TYPE_PTR, ret, ret, (uintptr_t)arg & 0x3ff);
40
- return false;
41
+ s_mask = arg_info(op->args[1])->s_mask
42
+ & arg_info(op->args[2])->s_mask;
43
+ return fold_masks_s(ctx, op, s_mask);
36
}
44
}
37
45
38
static inline void tcg_out_sety(TCGContext *s, TCGReg rs)
46
static bool fold_extract(OptContext *ctx, TCGOp *op)
39
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
40
tcg_out_movi_imm13(s, TCG_REG_O0, a0);
41
break;
42
} else if (USE_REG_TB) {
43
- intptr_t tb_diff = a0 - (uintptr_t)s->code_gen_ptr;
44
+ intptr_t tb_diff = tcg_tbrel_diff(s, (void *)a0);
45
if (check_fit_ptr(tb_diff, 13)) {
46
tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, RETURN);
47
/* Note that TCG_REG_TB has been unwound to O1. */
48
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
49
}
50
} else {
51
/* indirect jump method */
52
- tcg_out_ld_ptr(s, TCG_REG_TB,
53
- (uintptr_t)(s->tb_jmp_target_addr + a0));
54
+ tcg_out_ld_ptr(s, TCG_REG_TB, s->tb_jmp_target_addr + a0);
55
tcg_out_arithi(s, TCG_REG_G0, TCG_REG_TB, 0, JMPL);
56
tcg_out_nop(s);
57
}
58
--
47
--
59
2.25.1
48
2.43.0
60
61
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
1
Reviewed-by: Joelle van Dyne <j@getutm.app>
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
2
Explicitly sign-extend z_mask instead of doing that manually.
3
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
6
---
4
tcg/aarch64/tcg-target.h | 2 +-
7
tcg/optimize.c | 29 ++++++++++++-----------------
5
tcg/aarch64/tcg-target.c.inc | 57 ++++++++++++++++++++----------------
8
1 file changed, 12 insertions(+), 17 deletions(-)
6
2 files changed, 33 insertions(+), 26 deletions(-)
7
9
8
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
9
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
10
--- a/tcg/aarch64/tcg-target.h
12
--- a/tcg/optimize.c
11
+++ b/tcg/aarch64/tcg-target.h
13
+++ b/tcg/optimize.c
12
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
14
@@ -XXX,XX +XXX,XX @@ static bool fold_extract2(OptContext *ctx, TCGOp *op)
13
#define TCG_TARGET_NEED_LDST_LABELS
15
14
#endif
16
static bool fold_exts(OptContext *ctx, TCGOp *op)
15
#define TCG_TARGET_NEED_POOL_LABELS
16
-#define TCG_TARGET_SUPPORT_MIRROR 0
17
+#define TCG_TARGET_SUPPORT_MIRROR 1
18
19
#endif /* AARCH64_TCG_TARGET_H */
20
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
21
index XXXXXXX..XXXXXXX 100644
22
--- a/tcg/aarch64/tcg-target.c.inc
23
+++ b/tcg/aarch64/tcg-target.c.inc
24
@@ -XXX,XX +XXX,XX @@ static const int tcg_target_call_oarg_regs[1] = {
25
#define TCG_REG_GUEST_BASE TCG_REG_X28
26
#endif
27
28
-static inline bool reloc_pc26(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
29
+static bool reloc_pc26(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
30
{
17
{
31
- ptrdiff_t offset = target - code_ptr;
18
- uint64_t s_mask_old, s_mask, z_mask, sign;
32
+ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
19
+ uint64_t s_mask_old, s_mask, z_mask;
33
+ ptrdiff_t offset = target - src_rx;
20
bool type_change = false;
34
+
21
+ TempOptInfo *t1;
35
if (offset == sextract64(offset, 0, 26)) {
22
36
/* read instruction, mask away previous PC_REL26 parameter contents,
23
if (fold_const1(ctx, op)) {
37
set the proper offset, then write back the instruction. */
38
- *code_ptr = deposit32(*code_ptr, 0, 26, offset);
39
+ *src_rw = deposit32(*src_rw, 0, 26, offset);
40
return true;
24
return true;
41
}
25
}
42
return false;
26
43
}
27
- z_mask = arg_info(op->args[1])->z_mask;
44
28
- s_mask = arg_info(op->args[1])->s_mask;
45
-static inline bool reloc_pc19(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
29
+ t1 = arg_info(op->args[1]);
46
+static bool reloc_pc19(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
30
+ z_mask = t1->z_mask;
47
{
31
+ s_mask = t1->s_mask;
48
- ptrdiff_t offset = target - code_ptr;
32
s_mask_old = s_mask;
49
+ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
33
50
+ ptrdiff_t offset = target - src_rx;
34
switch (op->opc) {
51
+
35
CASE_OP_32_64(ext8s):
52
if (offset == sextract64(offset, 0, 19)) {
36
- sign = INT8_MIN;
53
- *code_ptr = deposit32(*code_ptr, 5, 19, offset);
37
- z_mask = (uint8_t)z_mask;
54
+ *src_rw = deposit32(*src_rw, 5, 19, offset);
38
+ s_mask |= INT8_MIN;
55
return true;
39
+ z_mask = (int8_t)z_mask;
56
}
40
break;
57
return false;
41
CASE_OP_32_64(ext16s):
58
}
42
- sign = INT16_MIN;
59
43
- z_mask = (uint16_t)z_mask;
60
-static inline bool patch_reloc(tcg_insn_unit *code_ptr, int type,
44
+ s_mask |= INT16_MIN;
61
- intptr_t value, intptr_t addend)
45
+ z_mask = (int16_t)z_mask;
62
+static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
46
break;
63
+ intptr_t value, intptr_t addend)
47
case INDEX_op_ext_i32_i64:
64
{
48
type_change = true;
65
tcg_debug_assert(addend == 0);
49
QEMU_FALLTHROUGH;
66
switch (type) {
50
case INDEX_op_ext32s_i64:
67
case R_AARCH64_JUMP26:
51
- sign = INT32_MIN;
68
case R_AARCH64_CALL26:
52
- z_mask = (uint32_t)z_mask;
69
- return reloc_pc26(code_ptr, (tcg_insn_unit *)value);
53
+ s_mask |= INT32_MIN;
70
+ return reloc_pc26(code_ptr, (const tcg_insn_unit *)value);
54
+ z_mask = (int32_t)z_mask;
71
case R_AARCH64_CONDBR19:
55
break;
72
- return reloc_pc19(code_ptr, (tcg_insn_unit *)value);
73
+ return reloc_pc19(code_ptr, (const tcg_insn_unit *)value);
74
default:
56
default:
75
g_assert_not_reached();
57
g_assert_not_reached();
76
}
58
}
77
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
59
78
/* Look for host pointer values within 4G of the PC. This happens
60
- if (z_mask & sign) {
79
often when loading pointers to QEMU's own data structures. */
61
- z_mask |= sign;
80
if (type == TCG_TYPE_I64) {
62
- }
81
- tcg_target_long disp = value - (intptr_t)s->code_ptr;
63
- s_mask |= sign << 1;
82
+ intptr_t src_rx = (intptr_t)tcg_splitwx_to_rx(s->code_ptr);
64
-
83
+ tcg_target_long disp = value - src_rx;
65
- ctx->z_mask = z_mask;
84
if (disp == sextract64(disp, 0, 21)) {
66
- ctx->s_mask = s_mask;
85
tcg_out_insn(s, 3406, ADR, rd, disp);
67
if (0 && !type_change && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
86
return;
68
return true;
87
}
69
}
88
- disp = (value >> 12) - ((intptr_t)s->code_ptr >> 12);
70
89
+ disp = (value >> 12) - (src_rx >> 12);
71
- return fold_masks(ctx, op);
90
if (disp == sextract64(disp, 0, 21)) {
72
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
91
tcg_out_insn(s, 3406, ADRP, rd, disp);
92
if (value & 0xfff) {
93
@@ -XXX,XX +XXX,XX @@ static void tcg_out_cmp(TCGContext *s, TCGType ext, TCGReg a,
94
95
static void tcg_out_goto(TCGContext *s, const tcg_insn_unit *target)
96
{
97
- ptrdiff_t offset = target - s->code_ptr;
98
+ ptrdiff_t offset = tcg_pcrel_diff(s, target) >> 2;
99
tcg_debug_assert(offset == sextract64(offset, 0, 26));
100
tcg_out_insn(s, 3206, B, offset);
101
}
73
}
102
74
103
-static inline void tcg_out_goto_long(TCGContext *s, tcg_insn_unit *target)
75
static bool fold_extu(OptContext *ctx, TCGOp *op)
104
+static void tcg_out_goto_long(TCGContext *s, const tcg_insn_unit *target)
105
{
106
- ptrdiff_t offset = target - s->code_ptr;
107
+ ptrdiff_t offset = tcg_pcrel_diff(s, target) >> 2;
108
if (offset == sextract64(offset, 0, 26)) {
109
tcg_out_insn(s, 3206, B, offset);
110
} else {
111
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_callr(TCGContext *s, TCGReg reg)
112
tcg_out_insn(s, 3207, BLR, reg);
113
}
114
115
-static inline void tcg_out_call(TCGContext *s, const tcg_insn_unit *target)
116
+static void tcg_out_call(TCGContext *s, const tcg_insn_unit *target)
117
{
118
- ptrdiff_t offset = target - s->code_ptr;
119
+ ptrdiff_t offset = tcg_pcrel_diff(s, target) >> 2;
120
if (offset == sextract64(offset, 0, 26)) {
121
tcg_out_insn(s, 3206, BL, offset);
122
} else {
123
@@ -XXX,XX +XXX,XX @@ static void tcg_out_brcond(TCGContext *s, TCGType ext, TCGCond c, TCGArg a,
124
tcg_out_reloc(s, s->code_ptr, R_AARCH64_CONDBR19, l, 0);
125
offset = tcg_in32(s) >> 5;
126
} else {
127
- offset = l->u.value_ptr - s->code_ptr;
128
+ offset = tcg_pcrel_diff(s, l->u.value_ptr) >> 2;
129
tcg_debug_assert(offset == sextract64(offset, 0, 19));
130
}
131
132
@@ -XXX,XX +XXX,XX @@ static void * const qemu_st_helpers[16] = {
133
[MO_BEQ] = helper_be_stq_mmu,
134
};
135
136
-static inline void tcg_out_adr(TCGContext *s, TCGReg rd, void *target)
137
+static inline void tcg_out_adr(TCGContext *s, TCGReg rd, const void *target)
138
{
139
ptrdiff_t offset = tcg_pcrel_diff(s, target);
140
tcg_debug_assert(offset == sextract64(offset, 0, 21));
141
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
142
MemOp opc = get_memop(oi);
143
MemOp size = opc & MO_SIZE;
144
145
- if (!reloc_pc19(lb->label_ptr[0], s->code_ptr)) {
146
+ if (!reloc_pc19(lb->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
147
return false;
148
}
149
150
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
151
MemOp opc = get_memop(oi);
152
MemOp size = opc & MO_SIZE;
153
154
- if (!reloc_pc19(lb->label_ptr[0], s->code_ptr)) {
155
+ if (!reloc_pc19(lb->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
156
return false;
157
}
158
159
@@ -XXX,XX +XXX,XX @@ static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
160
label->type = ext;
161
label->datalo_reg = data_reg;
162
label->addrlo_reg = addr_reg;
163
- label->raddr = raddr;
164
+ /* TODO: Cast goes away when all hosts converted */
165
+ label->raddr = (void *)tcg_splitwx_to_rx(raddr);
166
label->label_ptr[0] = label_ptr;
167
}
168
169
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data_reg, TCGReg addr_reg,
170
#endif /* CONFIG_SOFTMMU */
171
}
172
173
-static tcg_insn_unit *tb_ret_addr;
174
+static const tcg_insn_unit *tb_ret_addr;
175
176
static void tcg_out_op(TCGContext *s, TCGOpcode opc,
177
const TCGArg args[TCG_MAX_OP_ARGS],
178
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
179
* Return path for goto_ptr. Set return value to 0, a-la exit_tb,
180
* and fall through to the rest of the epilogue.
181
*/
182
- tcg_code_gen_epilogue = s->code_ptr;
183
+ /* TODO: Cast goes away when all hosts converted */
184
+ tcg_code_gen_epilogue = (void *)tcg_splitwx_to_rx(s->code_ptr);
185
tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_X0, 0);
186
187
/* TB epilogue */
188
- tb_ret_addr = s->code_ptr;
189
+ tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr);
190
191
/* Remove TCG locals stack space. */
192
tcg_out_insn(s, 3401, ADDI, TCG_TYPE_I64, TCG_REG_SP, TCG_REG_SP,
193
--
76
--
194
2.25.1
77
2.43.0
195
196
diff view generated by jsdifflib
1
Avoid the use of the OptContext slots.
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
1
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
---
5
---
3
tcg/sparc/tcg-target.h | 2 +-
6
tcg/optimize.c | 4 ++--
4
tcg/sparc/tcg-target.c.inc | 24 +++++++++++++-----------
7
1 file changed, 2 insertions(+), 2 deletions(-)
5
2 files changed, 14 insertions(+), 12 deletions(-)
6
8
7
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
8
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/sparc/tcg-target.h
11
--- a/tcg/optimize.c
10
+++ b/tcg/sparc/tcg-target.h
12
+++ b/tcg/optimize.c
11
@@ -XXX,XX +XXX,XX @@ extern bool use_vis3_instructions;
13
@@ -XXX,XX +XXX,XX @@ static bool fold_extu(OptContext *ctx, TCGOp *op)
12
void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
13
14
#define TCG_TARGET_NEED_POOL_LABELS
15
-#define TCG_TARGET_SUPPORT_MIRROR 0
16
+#define TCG_TARGET_SUPPORT_MIRROR 1
17
18
#endif
19
diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc/tcg-target.c.inc
20
index XXXXXXX..XXXXXXX 100644
21
--- a/tcg/sparc/tcg-target.c.inc
22
+++ b/tcg/sparc/tcg-target.c.inc
23
@@ -XXX,XX +XXX,XX @@ static inline int check_fit_i32(int32_t val, unsigned int bits)
24
# define check_fit_ptr check_fit_i32
25
#endif
26
27
-static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
28
+static bool patch_reloc(tcg_insn_unit *src_rw, int type,
29
intptr_t value, intptr_t addend)
30
{
31
- uint32_t insn = *code_ptr;
32
+ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
33
+ uint32_t insn = *src_rw;
34
intptr_t pcrel;
35
36
value += addend;
37
- pcrel = tcg_ptr_byte_diff((tcg_insn_unit *)value, code_ptr);
38
+ pcrel = tcg_ptr_byte_diff((tcg_insn_unit *)value, src_rx);
39
40
switch (type) {
41
case R_SPARC_WDISP16:
42
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
43
g_assert_not_reached();
14
g_assert_not_reached();
44
}
15
}
45
16
46
- *code_ptr = insn;
17
- ctx->z_mask = z_mask;
47
+ *src_rw = insn;
18
if (!type_change && fold_affected_mask(ctx, op, z_mask_old ^ z_mask)) {
48
return true;
19
return true;
20
}
21
- return fold_masks(ctx, op);
22
+
23
+ return fold_masks_z(ctx, op, z_mask);
49
}
24
}
50
25
51
@@ -XXX,XX +XXX,XX @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
26
static bool fold_mb(OptContext *ctx, TCGOp *op)
52
}
53
54
#ifdef CONFIG_SOFTMMU
55
-static tcg_insn_unit *qemu_ld_trampoline[16];
56
-static tcg_insn_unit *qemu_st_trampoline[16];
57
+static const tcg_insn_unit *qemu_ld_trampoline[16];
58
+static const tcg_insn_unit *qemu_st_trampoline[16];
59
60
static void emit_extend(TCGContext *s, TCGReg r, int op)
61
{
62
@@ -XXX,XX +XXX,XX @@ static void build_trampolines(TCGContext *s)
63
while ((uintptr_t)s->code_ptr & 15) {
64
tcg_out_nop(s);
65
}
66
- qemu_ld_trampoline[i] = s->code_ptr;
67
+ qemu_ld_trampoline[i] = tcg_splitwx_to_rx(s->code_ptr);
68
69
if (SPARC64 || TARGET_LONG_BITS == 32) {
70
ra = TCG_REG_O3;
71
@@ -XXX,XX +XXX,XX @@ static void build_trampolines(TCGContext *s)
72
while ((uintptr_t)s->code_ptr & 15) {
73
tcg_out_nop(s);
74
}
75
- qemu_st_trampoline[i] = s->code_ptr;
76
+ qemu_st_trampoline[i] = tcg_splitwx_to_rx(s->code_ptr);
77
78
if (SPARC64) {
79
emit_extend(s, TCG_REG_O2, i);
80
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
81
tcg_out_nop(s);
82
83
/* Epilogue for goto_ptr. */
84
- tcg_code_gen_epilogue = s->code_ptr;
85
+ /* TODO: Cast goes away when all hosts converted */
86
+ tcg_code_gen_epilogue = (void *)tcg_splitwx_to_rx(s->code_ptr);
87
tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, RETURN);
88
/* delay slot */
89
tcg_out_movi_imm13(s, TCG_REG_O0, 0);
90
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr,
91
#ifdef CONFIG_SOFTMMU
92
unsigned memi = get_mmuidx(oi);
93
TCGReg addrz, param;
94
- tcg_insn_unit *func;
95
+ const tcg_insn_unit *func;
96
tcg_insn_unit *label_ptr;
97
98
addrz = tcg_out_tlb_load(s, addr, memi, memop,
99
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr,
100
#ifdef CONFIG_SOFTMMU
101
unsigned memi = get_mmuidx(oi);
102
TCGReg addrz, param;
103
- tcg_insn_unit *func;
104
+ const tcg_insn_unit *func;
105
tcg_insn_unit *label_ptr;
106
107
addrz = tcg_out_tlb_load(s, addr, memi, memop,
108
--
27
--
109
2.25.1
28
2.43.0
110
111
diff view generated by jsdifflib
1
Add two helper functions, using a global variable to hold
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
2
the displacement. The displacement is currently always 0,
3
so no change in behaviour.
4
2
5
Begin using the functions in tcg common code only.
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
6
7
Reviewed-by: Joelle van Dyne <j@getutm.app>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
5
---
10
accel/tcg/tcg-runtime.h | 2 +-
6
tcg/optimize.c | 19 +++++++++++--------
11
include/disas/disas.h | 2 +-
7
1 file changed, 11 insertions(+), 8 deletions(-)
12
include/exec/exec-all.h | 2 +-
13
include/exec/log.h | 2 +-
14
include/tcg/tcg.h | 26 ++++++++++++++----
15
accel/tcg/cpu-exec.c | 2 +-
16
accel/tcg/tcg-runtime.c | 2 +-
17
accel/tcg/translate-all.c | 33 +++++++++++------------
18
disas.c | 4 ++-
19
tcg/tcg.c | 56 ++++++++++++++++++++++++++++++++++-----
20
tcg/tci.c | 6 +++--
21
tcg/tcg-pool.c.inc | 6 ++++-
22
accel/tcg/trace-events | 2 +-
23
13 files changed, 105 insertions(+), 40 deletions(-)
24
8
25
diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime.h
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
26
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
27
--- a/accel/tcg/tcg-runtime.h
11
--- a/tcg/optimize.c
28
+++ b/accel/tcg/tcg-runtime.h
12
+++ b/tcg/optimize.c
29
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_1(clrsb_i64, TCG_CALL_NO_RWG_SE, i64, i64)
13
@@ -XXX,XX +XXX,XX @@ static bool fold_mov(OptContext *ctx, TCGOp *op)
30
DEF_HELPER_FLAGS_1(ctpop_i32, TCG_CALL_NO_RWG_SE, i32, i32)
14
31
DEF_HELPER_FLAGS_1(ctpop_i64, TCG_CALL_NO_RWG_SE, i64, i64)
15
static bool fold_movcond(OptContext *ctx, TCGOp *op)
32
33
-DEF_HELPER_FLAGS_1(lookup_tb_ptr, TCG_CALL_NO_WG_SE, ptr, env)
34
+DEF_HELPER_FLAGS_1(lookup_tb_ptr, TCG_CALL_NO_WG_SE, cptr, env)
35
36
DEF_HELPER_FLAGS_1(exit_atomic, TCG_CALL_NO_WG, noreturn, env)
37
38
diff --git a/include/disas/disas.h b/include/disas/disas.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/include/disas/disas.h
41
+++ b/include/disas/disas.h
42
@@ -XXX,XX +XXX,XX @@
43
#include "cpu.h"
44
45
/* Disassemble this for me please... (debugging). */
46
-void disas(FILE *out, void *code, unsigned long size);
47
+void disas(FILE *out, const void *code, unsigned long size);
48
void target_disas(FILE *out, CPUState *cpu, target_ulong code,
49
target_ulong size);
50
51
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
52
index XXXXXXX..XXXXXXX 100644
53
--- a/include/exec/exec-all.h
54
+++ b/include/exec/exec-all.h
55
@@ -XXX,XX +XXX,XX @@ int probe_access_flags(CPUArchState *env, target_ulong addr,
56
* Note: the address of search data can be obtained by adding @size to @ptr.
57
*/
58
struct tb_tc {
59
- void *ptr; /* pointer to the translated code */
60
+ const void *ptr; /* pointer to the translated code */
61
size_t size;
62
};
63
64
diff --git a/include/exec/log.h b/include/exec/log.h
65
index XXXXXXX..XXXXXXX 100644
66
--- a/include/exec/log.h
67
+++ b/include/exec/log.h
68
@@ -XXX,XX +XXX,XX @@ static inline void log_target_disas(CPUState *cpu, target_ulong start,
69
rcu_read_unlock();
70
}
71
72
-static inline void log_disas(void *code, unsigned long size)
73
+static inline void log_disas(const void *code, unsigned long size)
74
{
16
{
75
QemuLogFile *logfile;
17
+ uint64_t z_mask, s_mask;
76
rcu_read_lock();
18
+ TempOptInfo *tt, *ft;
77
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
19
int i;
78
index XXXXXXX..XXXXXXX 100644
20
79
--- a/include/tcg/tcg.h
21
/* If true and false values are the same, eliminate the cmp. */
80
+++ b/include/tcg/tcg.h
22
@@ -XXX,XX +XXX,XX @@ static bool fold_movcond(OptContext *ctx, TCGOp *op)
81
@@ -XXX,XX +XXX,XX @@ struct TCGContext {
23
return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[4 - i]);
82
extern TCGContext tcg_init_ctx;
83
extern __thread TCGContext *tcg_ctx;
84
extern void *tcg_code_gen_epilogue;
85
+extern uintptr_t tcg_splitwx_diff;
86
extern TCGv_env cpu_env;
87
88
static inline bool in_code_gen_buffer(const void *p)
89
@@ -XXX,XX +XXX,XX @@ static inline bool in_code_gen_buffer(const void *p)
90
return (size_t)(p - s->code_gen_buffer) <= s->code_gen_buffer_size;
91
}
92
93
+#ifdef CONFIG_DEBUG_TCG
94
+const void *tcg_splitwx_to_rx(void *rw);
95
+void *tcg_splitwx_to_rw(const void *rx);
96
+#else
97
+static inline const void *tcg_splitwx_to_rx(void *rw)
98
+{
99
+ return rw ? rw + tcg_splitwx_diff : NULL;
100
+}
101
+
102
+static inline void *tcg_splitwx_to_rw(const void *rx)
103
+{
104
+ return rx ? (void *)rx - tcg_splitwx_diff : NULL;
105
+}
106
+#endif
107
+
108
static inline size_t temp_idx(TCGTemp *ts)
109
{
110
ptrdiff_t n = ts - tcg_ctx->temps;
111
@@ -XXX,XX +XXX,XX @@ static inline TCGLabel *arg_label(TCGArg i)
112
* correct result.
113
*/
114
115
-static inline ptrdiff_t tcg_ptr_byte_diff(void *a, void *b)
116
+static inline ptrdiff_t tcg_ptr_byte_diff(const void *a, const void *b)
117
{
118
return a - b;
119
}
120
@@ -XXX,XX +XXX,XX @@ static inline ptrdiff_t tcg_ptr_byte_diff(void *a, void *b)
121
* to the destination address.
122
*/
123
124
-static inline ptrdiff_t tcg_pcrel_diff(TCGContext *s, void *target)
125
+static inline ptrdiff_t tcg_pcrel_diff(TCGContext *s, const void *target)
126
{
127
- return tcg_ptr_byte_diff(target, s->code_ptr);
128
+ return tcg_ptr_byte_diff(target, tcg_splitwx_to_rx(s->code_ptr));
129
}
130
131
/**
132
@@ -XXX,XX +XXX,XX @@ static inline unsigned get_mmuidx(TCGMemOpIdx oi)
133
#define TB_EXIT_REQUESTED 3
134
135
#ifdef CONFIG_TCG_INTERPRETER
136
-uintptr_t tcg_qemu_tb_exec(CPUArchState *env, void *tb_ptr);
137
+uintptr_t tcg_qemu_tb_exec(CPUArchState *env, const void *tb_ptr);
138
#else
139
-typedef uintptr_t tcg_prologue_fn(CPUArchState *env, void *tb_ptr);
140
+typedef uintptr_t tcg_prologue_fn(CPUArchState *env, const void *tb_ptr);
141
extern tcg_prologue_fn *tcg_qemu_tb_exec;
142
#endif
143
144
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
145
index XXXXXXX..XXXXXXX 100644
146
--- a/accel/tcg/cpu-exec.c
147
+++ b/accel/tcg/cpu-exec.c
148
@@ -XXX,XX +XXX,XX @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb)
149
uintptr_t ret;
150
TranslationBlock *last_tb;
151
int tb_exit;
152
- uint8_t *tb_ptr = itb->tc.ptr;
153
+ const void *tb_ptr = itb->tc.ptr;
154
155
qemu_log_mask_and_addr(CPU_LOG_EXEC, itb->pc,
156
"Trace %d: %p ["
157
diff --git a/accel/tcg/tcg-runtime.c b/accel/tcg/tcg-runtime.c
158
index XXXXXXX..XXXXXXX 100644
159
--- a/accel/tcg/tcg-runtime.c
160
+++ b/accel/tcg/tcg-runtime.c
161
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(ctpop_i64)(uint64_t arg)
162
return ctpop64(arg);
163
}
164
165
-void *HELPER(lookup_tb_ptr)(CPUArchState *env)
166
+const void *HELPER(lookup_tb_ptr)(CPUArchState *env)
167
{
168
CPUState *cpu = env_cpu(env);
169
TranslationBlock *tb;
170
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
171
index XXXXXXX..XXXXXXX 100644
172
--- a/accel/tcg/translate-all.c
173
+++ b/accel/tcg/translate-all.c
174
@@ -XXX,XX +XXX,XX @@ static uint8_t *encode_sleb128(uint8_t *p, target_long val)
175
176
/* Decode a signed leb128 sequence at *PP; increment *PP past the
177
decoded value. Return the decoded value. */
178
-static target_long decode_sleb128(uint8_t **pp)
179
+static target_long decode_sleb128(const uint8_t **pp)
180
{
181
- uint8_t *p = *pp;
182
+ const uint8_t *p = *pp;
183
target_long val = 0;
184
int byte, shift = 0;
185
186
@@ -XXX,XX +XXX,XX @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
187
target_ulong data[TARGET_INSN_START_WORDS] = { tb->pc };
188
uintptr_t host_pc = (uintptr_t)tb->tc.ptr;
189
CPUArchState *env = cpu->env_ptr;
190
- uint8_t *p = tb->tc.ptr + tb->tc.size;
191
+ const uint8_t *p = tb->tc.ptr + tb->tc.size;
192
int i, j, num_insns = tb->icount;
193
#ifdef CONFIG_PROFILER
194
TCGProfile *prof = &tcg_ctx->prof;
195
@@ -XXX,XX +XXX,XX @@ void tb_destroy(TranslationBlock *tb)
196
bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit)
197
{
198
/*
199
- * The host_pc has to be in the region of the code buffer.
200
+ * The host_pc has to be in the rx region of the code buffer.
201
* If it is not we will not be able to resolve it here.
202
* The two cases where host_pc will not be correct are:
203
*
204
@@ -XXX,XX +XXX,XX @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit)
205
*
206
* Either way we need return early as we can't resolve it here.
207
*/
208
- if (in_code_gen_buffer((const void *)host_pc)) {
209
+ if (in_code_gen_buffer((const void *)(host_pc - tcg_splitwx_diff))) {
210
TranslationBlock *tb = tcg_tb_lookup(host_pc);
211
if (tb) {
212
cpu_restore_state_from_tb(cpu, tb, host_pc, will_exit);
213
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
214
}
24
}
215
25
216
gen_code_buf = tcg_ctx->code_gen_ptr;
26
- ctx->z_mask = arg_info(op->args[3])->z_mask
217
- tb->tc.ptr = gen_code_buf;
27
- | arg_info(op->args[4])->z_mask;
218
+ tb->tc.ptr = tcg_splitwx_to_rx(gen_code_buf);
28
- ctx->s_mask = arg_info(op->args[3])->s_mask
219
tb->pc = pc;
29
- & arg_info(op->args[4])->s_mask;
220
tb->cs_base = cs_base;
30
+ tt = arg_info(op->args[3]);
221
tb->flags = flags;
31
+ ft = arg_info(op->args[4]);
222
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
32
+ z_mask = tt->z_mask | ft->z_mask;
223
if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM) &&
33
+ s_mask = tt->s_mask & ft->s_mask;
224
qemu_log_in_addr_range(tb->pc)) {
34
225
FILE *logfile = qemu_log_lock();
35
- if (arg_is_const(op->args[3]) && arg_is_const(op->args[4])) {
226
- int code_size, data_size = 0;
36
- uint64_t tv = arg_info(op->args[3])->val;
227
+ int code_size, data_size;
37
- uint64_t fv = arg_info(op->args[4])->val;
228
+ const tcg_target_ulong *rx_data_gen_ptr;
38
+ if (ti_is_const(tt) && ti_is_const(ft)) {
229
size_t chunk_start;
39
+ uint64_t tv = ti_const_val(tt);
230
int insn = 0;
40
+ uint64_t fv = ti_const_val(ft);
231
41
TCGOpcode opc, negopc = 0;
232
if (tcg_ctx->data_gen_ptr) {
42
TCGCond cond = op->args[5];
233
- code_size = tcg_ctx->data_gen_ptr - tb->tc.ptr;
43
234
+ rx_data_gen_ptr = tcg_splitwx_to_rx(tcg_ctx->data_gen_ptr);
44
@@ -XXX,XX +XXX,XX @@ static bool fold_movcond(OptContext *ctx, TCGOp *op)
235
+ code_size = (const void *)rx_data_gen_ptr - tb->tc.ptr;
236
data_size = gen_code_size - code_size;
237
} else {
238
+ rx_data_gen_ptr = 0;
239
code_size = gen_code_size;
240
+ data_size = 0;
241
}
242
243
/* Dump header and the first instruction */
244
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
245
if (data_size) {
246
int i;
247
qemu_log(" data: [size=%d]\n", data_size);
248
- for (i = 0; i < data_size; i += sizeof(tcg_target_ulong)) {
249
- if (sizeof(tcg_target_ulong) == 8) {
250
- qemu_log("0x%08" PRIxPTR ": .quad 0x%016" PRIx64 "\n",
251
- (uintptr_t)tcg_ctx->data_gen_ptr + i,
252
- *(uint64_t *)(tcg_ctx->data_gen_ptr + i));
253
- } else {
254
- qemu_log("0x%08" PRIxPTR ": .long 0x%08x\n",
255
- (uintptr_t)tcg_ctx->data_gen_ptr + i,
256
- *(uint32_t *)(tcg_ctx->data_gen_ptr + i));
257
- }
258
+ for (i = 0; i < data_size / sizeof(tcg_target_ulong); i++) {
259
+ qemu_log("0x%08" PRIxPTR ": .quad 0x%" TCG_PRIlx "\n",
260
+ (uintptr_t)&rx_data_gen_ptr[i], rx_data_gen_ptr[i]);
261
}
45
}
262
}
46
}
263
qemu_log("\n");
47
}
264
diff --git a/disas.c b/disas.c
48
- return false;
265
index XXXXXXX..XXXXXXX 100644
49
+
266
--- a/disas.c
50
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
267
+++ b/disas.c
268
@@ -XXX,XX +XXX,XX @@ char *plugin_disas(CPUState *cpu, uint64_t addr, size_t size)
269
}
51
}
270
52
271
/* Disassemble this for me please... (debugging). */
53
static bool fold_mul(OptContext *ctx, TCGOp *op)
272
-void disas(FILE *out, void *code, unsigned long size)
273
+void disas(FILE *out, const void *ccode, unsigned long size)
274
{
275
+ /* TODO: Push constness through the disas backends. */
276
+ void *code = (void *)ccode;
277
uintptr_t pc;
278
int count;
279
CPUDebug s;
280
diff --git a/tcg/tcg.c b/tcg/tcg.c
281
index XXXXXXX..XXXXXXX 100644
282
--- a/tcg/tcg.c
283
+++ b/tcg/tcg.c
284
@@ -XXX,XX +XXX,XX @@ static TCGContext **tcg_ctxs;
285
static unsigned int n_tcg_ctxs;
286
TCGv_env cpu_env = 0;
287
void *tcg_code_gen_epilogue;
288
+uintptr_t tcg_splitwx_diff;
289
290
#ifndef CONFIG_TCG_INTERPRETER
291
tcg_prologue_fn *tcg_qemu_tb_exec;
292
@@ -XXX,XX +XXX,XX @@ static void tcg_region_trees_init(void)
293
}
294
}
295
296
-static struct tcg_region_tree *tc_ptr_to_region_tree(void *p)
297
+static struct tcg_region_tree *tc_ptr_to_region_tree(const void *cp)
298
{
299
+ void *p = tcg_splitwx_to_rw(cp);
300
size_t region_idx;
301
302
if (p < region.start_aligned) {
303
@@ -XXX,XX +XXX,XX @@ void tcg_region_init(void)
304
size_t region_size;
305
size_t n_regions;
306
size_t i;
307
+ uintptr_t splitwx_diff;
308
309
n_regions = tcg_n_regions();
310
311
@@ -XXX,XX +XXX,XX @@ void tcg_region_init(void)
312
region.end -= page_size;
313
314
/* set guard pages */
315
+ splitwx_diff = tcg_splitwx_diff;
316
for (i = 0; i < region.n; i++) {
317
void *start, *end;
318
int rc;
319
@@ -XXX,XX +XXX,XX @@ void tcg_region_init(void)
320
tcg_region_bounds(i, &start, &end);
321
rc = qemu_mprotect_none(end, page_size);
322
g_assert(!rc);
323
+ if (splitwx_diff) {
324
+ rc = qemu_mprotect_none(end + splitwx_diff, page_size);
325
+ g_assert(!rc);
326
+ }
327
}
328
329
tcg_region_trees_init();
330
@@ -XXX,XX +XXX,XX @@ void tcg_region_init(void)
331
#endif
332
}
333
334
+#ifdef CONFIG_DEBUG_TCG
335
+const void *tcg_splitwx_to_rx(void *rw)
336
+{
337
+ /* Pass NULL pointers unchanged. */
338
+ if (rw) {
339
+ g_assert(in_code_gen_buffer(rw));
340
+ rw += tcg_splitwx_diff;
341
+ }
342
+ return rw;
343
+}
344
+
345
+void *tcg_splitwx_to_rw(const void *rx)
346
+{
347
+ /* Pass NULL pointers unchanged. */
348
+ if (rx) {
349
+ rx -= tcg_splitwx_diff;
350
+ /* Assert that we end with a pointer in the rw region. */
351
+ g_assert(in_code_gen_buffer(rx));
352
+ }
353
+ return (void *)rx;
354
+}
355
+#endif /* CONFIG_DEBUG_TCG */
356
+
357
static void alloc_tcg_plugin_context(TCGContext *s)
358
{
359
#ifdef CONFIG_PLUGIN
360
@@ -XXX,XX +XXX,XX @@ void tcg_prologue_init(TCGContext *s)
361
s->code_buf = buf0;
362
s->data_gen_ptr = NULL;
363
364
+ /*
365
+ * The region trees are not yet configured, but tcg_splitwx_to_rx
366
+ * needs the bounds for an assert.
367
+ */
368
+ region.start = buf0;
369
+ region.end = buf0 + total_size;
370
+
371
#ifndef CONFIG_TCG_INTERPRETER
372
- tcg_qemu_tb_exec = (tcg_prologue_fn *)buf0;
373
+ tcg_qemu_tb_exec = (tcg_prologue_fn *)tcg_splitwx_to_rx(buf0);
374
#endif
375
376
/* Compute a high-water mark, at which we voluntarily flush the buffer
377
@@ -XXX,XX +XXX,XX @@ void tcg_prologue_init(TCGContext *s)
378
379
buf1 = s->code_ptr;
380
#ifndef CONFIG_TCG_INTERPRETER
381
- flush_idcache_range((uintptr_t)buf0, (uintptr_t)buf0,
382
+ flush_idcache_range((uintptr_t)tcg_splitwx_to_rx(buf0), (uintptr_t)buf0,
383
tcg_ptr_byte_diff(buf1, buf0));
384
#endif
385
386
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
387
388
tcg_reg_alloc_start(s);
389
390
- s->code_buf = tb->tc.ptr;
391
- s->code_ptr = tb->tc.ptr;
392
+ /*
393
+ * Reset the buffer pointers when restarting after overflow.
394
+ * TODO: Move this into translate-all.c with the rest of the
395
+ * buffer management. Having only this done here is confusing.
396
+ */
397
+ s->code_buf = tcg_splitwx_to_rw(tb->tc.ptr);
398
+ s->code_ptr = s->code_buf;
399
400
#ifdef TCG_TARGET_NEED_LDST_LABELS
401
QSIMPLEQ_INIT(&s->ldst_labels);
402
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
403
404
#ifndef CONFIG_TCG_INTERPRETER
405
/* flush instruction cache */
406
- flush_idcache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_buf,
407
+ flush_idcache_range((uintptr_t)tcg_splitwx_to_rx(s->code_buf),
408
+ (uintptr_t)s->code_buf,
409
tcg_ptr_byte_diff(s->code_ptr, s->code_buf));
410
#endif
411
412
diff --git a/tcg/tci.c b/tcg/tci.c
413
index XXXXXXX..XXXXXXX 100644
414
--- a/tcg/tci.c
415
+++ b/tcg/tci.c
416
@@ -XXX,XX +XXX,XX @@ static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
417
* One possible operation in the pseudo code is a call to binary code.
418
* Therefore, disable CFI checks in the interpreter function
419
*/
420
-uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env, void *v_tb_ptr)
421
+uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
422
+ const void *v_tb_ptr)
423
{
424
- uint8_t *tb_ptr = v_tb_ptr;
425
+ /* TODO: Propagate const through this file. */
426
+ uint8_t *tb_ptr = (uint8_t *)v_tb_ptr;
427
tcg_target_ulong regs[TCG_TARGET_NB_REGS];
428
long tcg_temps[CPU_TEMP_BUF_NLONGS];
429
uintptr_t sp_value = (uintptr_t)(tcg_temps + CPU_TEMP_BUF_NLONGS);
430
diff --git a/tcg/tcg-pool.c.inc b/tcg/tcg-pool.c.inc
431
index XXXXXXX..XXXXXXX 100644
432
--- a/tcg/tcg-pool.c.inc
433
+++ b/tcg/tcg-pool.c.inc
434
@@ -XXX,XX +XXX,XX @@ static int tcg_out_pool_finalize(TCGContext *s)
435
436
for (; p != NULL; p = p->next) {
437
size_t size = sizeof(tcg_target_ulong) * p->nlong;
438
+ uintptr_t value;
439
+
440
if (!l || l->nlong != p->nlong || memcmp(l->data, p->data, size)) {
441
if (unlikely(a > s->code_gen_highwater)) {
442
return -1;
443
@@ -XXX,XX +XXX,XX @@ static int tcg_out_pool_finalize(TCGContext *s)
444
a += size;
445
l = p;
446
}
447
- if (!patch_reloc(p->label, p->rtype, (intptr_t)a - size, p->addend)) {
448
+
449
+ value = (uintptr_t)tcg_splitwx_to_rx(a) - size;
450
+ if (!patch_reloc(p->label, p->rtype, value, p->addend)) {
451
return -2;
452
}
453
}
454
diff --git a/accel/tcg/trace-events b/accel/tcg/trace-events
455
index XXXXXXX..XXXXXXX 100644
456
--- a/accel/tcg/trace-events
457
+++ b/accel/tcg/trace-events
458
@@ -XXX,XX +XXX,XX @@ exec_tb_nocache(void *tb, uintptr_t pc) "tb:%p pc=0x%"PRIxPTR
459
exec_tb_exit(void *last_tb, unsigned int flags) "tb:%p flags=0x%x"
460
461
# translate-all.c
462
-translate_block(void *tb, uintptr_t pc, uint8_t *tb_code) "tb:%p, pc:0x%"PRIxPTR", tb_code:%p"
463
+translate_block(void *tb, uintptr_t pc, const void *tb_code) "tb:%p, pc:0x%"PRIxPTR", tb_code:%p"
464
--
54
--
465
2.25.1
55
2.43.0
466
467
diff view generated by jsdifflib
1
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
3
---
4
tcg/riscv/tcg-target.h | 2 +-
4
tcg/optimize.c | 6 +++---
5
tcg/riscv/tcg-target.c.inc | 41 +++++++++++++++++++++-----------------
5
1 file changed, 3 insertions(+), 3 deletions(-)
6
2 files changed, 24 insertions(+), 19 deletions(-)
7
6
8
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
9
index XXXXXXX..XXXXXXX 100644
8
index XXXXXXX..XXXXXXX 100644
10
--- a/tcg/riscv/tcg-target.h
9
--- a/tcg/optimize.c
11
+++ b/tcg/riscv/tcg-target.h
10
+++ b/tcg/optimize.c
12
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
11
@@ -XXX,XX +XXX,XX @@ static bool fold_mul(OptContext *ctx, TCGOp *op)
13
#define TCG_TARGET_NEED_POOL_LABELS
12
fold_xi_to_x(ctx, op, 1)) {
14
15
#define TCG_TARGET_HAS_MEMORY_BSWAP 0
16
-#define TCG_TARGET_SUPPORT_MIRROR 0
17
+#define TCG_TARGET_SUPPORT_MIRROR 1
18
19
#endif
20
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
21
index XXXXXXX..XXXXXXX 100644
22
--- a/tcg/riscv/tcg-target.c.inc
23
+++ b/tcg/riscv/tcg-target.c.inc
24
@@ -XXX,XX +XXX,XX @@ static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
25
* Relocations
26
*/
27
28
-static bool reloc_sbimm12(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
29
+static bool reloc_sbimm12(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
30
{
31
- intptr_t offset = (intptr_t)target - (intptr_t)code_ptr;
32
+ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
33
+ intptr_t offset = (intptr_t)target - (intptr_t)src_rx;
34
35
tcg_debug_assert((offset & 1) == 0);
36
if (offset == sextreg(offset, 0, 12)) {
37
- code_ptr[0] |= encode_sbimm12(offset);
38
+ *src_rw |= encode_sbimm12(offset);
39
return true;
13
return true;
40
}
14
}
41
15
- return false;
42
return false;
16
+ return finish_folding(ctx, op);
43
}
17
}
44
18
45
-static bool reloc_jimm20(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
19
static bool fold_mul_highpart(OptContext *ctx, TCGOp *op)
46
+static bool reloc_jimm20(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
20
@@ -XXX,XX +XXX,XX @@ static bool fold_mul_highpart(OptContext *ctx, TCGOp *op)
47
{
21
fold_xi_to_i(ctx, op, 0)) {
48
- intptr_t offset = (intptr_t)target - (intptr_t)code_ptr;
49
+ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
50
+ intptr_t offset = (intptr_t)target - (intptr_t)src_rx;
51
52
tcg_debug_assert((offset & 1) == 0);
53
if (offset == sextreg(offset, 0, 20)) {
54
- code_ptr[0] |= encode_ujimm20(offset);
55
+ *src_rw |= encode_ujimm20(offset);
56
return true;
22
return true;
57
}
23
}
58
24
- return false;
59
return false;
25
+ return finish_folding(ctx, op);
60
}
26
}
61
27
62
-static bool reloc_call(tcg_insn_unit *code_ptr, const tcg_insn_unit *target)
28
static bool fold_multiply2(OptContext *ctx, TCGOp *op)
63
+static bool reloc_call(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
29
@@ -XXX,XX +XXX,XX @@ static bool fold_multiply2(OptContext *ctx, TCGOp *op)
64
{
30
tcg_opt_gen_movi(ctx, op2, rh, h);
65
- intptr_t offset = (intptr_t)target - (intptr_t)code_ptr;
66
+ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
67
+ intptr_t offset = (intptr_t)target - (intptr_t)src_rx;
68
int32_t lo = sextreg(offset, 0, 12);
69
int32_t hi = offset - lo;
70
71
if (offset == hi + lo) {
72
- code_ptr[0] |= encode_uimm20(hi);
73
- code_ptr[1] |= encode_imm12(lo);
74
+ src_rw[0] |= encode_uimm20(hi);
75
+ src_rw[1] |= encode_imm12(lo);
76
return true;
31
return true;
77
}
32
}
78
33
- return false;
79
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
34
+ return finish_folding(ctx, op);
80
if (tmp == (int32_t)tmp) {
81
tcg_out_opc_upper(s, OPC_AUIPC, rd, 0);
82
tcg_out_opc_imm(s, OPC_ADDI, rd, rd, 0);
83
- ret = reloc_call(s->code_ptr - 2, (tcg_insn_unit *)val);
84
+ ret = reloc_call(s->code_ptr - 2, (const tcg_insn_unit *)val);
85
tcg_debug_assert(ret == true);
86
return;
87
}
88
@@ -XXX,XX +XXX,XX @@ QEMU_BUILD_BUG_ON(TCG_TARGET_REG_BITS < TARGET_LONG_BITS);
89
QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
90
QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 11));
91
92
-static void tcg_out_goto(TCGContext *s, tcg_insn_unit *target)
93
+static void tcg_out_goto(TCGContext *s, const tcg_insn_unit *target)
94
{
95
tcg_out_opc_jump(s, OPC_JAL, TCG_REG_ZERO, 0);
96
bool ok = reloc_jimm20(s->code_ptr - 1, target);
97
@@ -XXX,XX +XXX,XX @@ static void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOpIdx oi,
98
label->datahi_reg = datahi;
99
label->addrlo_reg = addrlo;
100
label->addrhi_reg = addrhi;
101
- label->raddr = raddr;
102
+ /* TODO: Cast goes away when all hosts converted */
103
+ label->raddr = (void *)tcg_splitwx_to_rx(raddr);
104
label->label_ptr[0] = label_ptr[0];
105
}
35
}
106
36
107
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
37
static bool fold_nand(OptContext *ctx, TCGOp *op)
108
}
109
110
/* resolve label address */
111
- if (!reloc_sbimm12(l->label_ptr[0], s->code_ptr)) {
112
+ if (!reloc_sbimm12(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
113
return false;
114
}
115
116
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
117
}
118
119
/* resolve label address */
120
- if (!reloc_sbimm12(l->label_ptr[0], s->code_ptr)) {
121
+ if (!reloc_sbimm12(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
122
return false;
123
}
124
125
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64)
126
#endif
127
}
128
129
-static tcg_insn_unit *tb_ret_addr;
130
+static const tcg_insn_unit *tb_ret_addr;
131
132
static void tcg_out_op(TCGContext *s, TCGOpcode opc,
133
const TCGArg *args, const int *const_args)
134
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
135
tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, tcg_target_call_iarg_regs[1], 0);
136
137
/* Return path for goto_ptr. Set return value to 0 */
138
- tcg_code_gen_epilogue = s->code_ptr;
139
+ /* TODO: Cast goes away when all hosts converted */
140
+ tcg_code_gen_epilogue = (void *)tcg_splitwx_to_rx(s->code_ptr);
141
tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_A0, TCG_REG_ZERO);
142
143
/* TB epilogue */
144
- tb_ret_addr = s->code_ptr;
145
+ tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr);
146
for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
147
tcg_out_ld(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
148
TCG_REG_SP, SAVE_OFS + i * REG_SIZE);
149
--
38
--
150
2.25.1
39
2.43.0
151
152
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
1
Create a function to determine if a pointer is within the buffer.
1
Avoid the use of the OptContext slots.
2
2
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@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/tcg/tcg.h | 11 +++++++++++
6
tcg/optimize.c | 7 +------
7
accel/tcg/translate-all.c | 26 ++++++++------------------
7
1 file changed, 1 insertion(+), 6 deletions(-)
8
2 files changed, 19 insertions(+), 18 deletions(-)
9
8
10
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
11
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
12
--- a/include/tcg/tcg.h
11
--- a/tcg/optimize.c
13
+++ b/include/tcg/tcg.h
12
+++ b/tcg/optimize.c
14
@@ -XXX,XX +XXX,XX @@ extern __thread TCGContext *tcg_ctx;
13
@@ -XXX,XX +XXX,XX @@ static bool fold_not(OptContext *ctx, TCGOp *op)
15
extern void *tcg_code_gen_epilogue;
14
if (fold_const1(ctx, op)) {
16
extern TCGv_env cpu_env;
15
return true;
17
18
+static inline bool in_code_gen_buffer(const void *p)
19
+{
20
+ const TCGContext *s = &tcg_init_ctx;
21
+ /*
22
+ * Much like it is valid to have a pointer to the byte past the
23
+ * end of an array (so long as you don't dereference it), allow
24
+ * a pointer to the byte past the end of the code gen buffer.
25
+ */
26
+ return (size_t)(p - s->code_gen_buffer) <= s->code_gen_buffer_size;
27
+}
28
+
29
static inline size_t temp_idx(TCGTemp *ts)
30
{
31
ptrdiff_t n = ts - tcg_ctx->temps;
32
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/accel/tcg/translate-all.c
35
+++ b/accel/tcg/translate-all.c
36
@@ -XXX,XX +XXX,XX @@ void tb_destroy(TranslationBlock *tb)
37
38
bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit)
39
{
40
- TranslationBlock *tb;
41
- bool r = false;
42
- uintptr_t check_offset;
43
-
44
- /* The host_pc has to be in the region of current code buffer. If
45
- * it is not we will not be able to resolve it here. The two cases
46
- * where host_pc will not be correct are:
47
+ /*
48
+ * The host_pc has to be in the region of the code buffer.
49
+ * If it is not we will not be able to resolve it here.
50
+ * The two cases where host_pc will not be correct are:
51
*
52
* - fault during translation (instruction fetch)
53
* - fault from helper (not using GETPC() macro)
54
*
55
* Either way we need return early as we can't resolve it here.
56
- *
57
- * We are using unsigned arithmetic so if host_pc <
58
- * tcg_init_ctx.code_gen_buffer check_offset will wrap to way
59
- * above the code_gen_buffer_size
60
*/
61
- check_offset = host_pc - (uintptr_t) tcg_init_ctx.code_gen_buffer;
62
-
63
- if (check_offset < tcg_init_ctx.code_gen_buffer_size) {
64
- tb = tcg_tb_lookup(host_pc);
65
+ if (in_code_gen_buffer((const void *)host_pc)) {
66
+ TranslationBlock *tb = tcg_tb_lookup(host_pc);
67
if (tb) {
68
cpu_restore_state_from_tb(cpu, tb, host_pc, will_exit);
69
if (tb_cflags(tb) & CF_NOCACHE) {
70
@@ -XXX,XX +XXX,XX @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit)
71
tcg_tb_remove(tb);
72
tb_destroy(tb);
73
}
74
- r = true;
75
+ return true;
76
}
77
}
16
}
78
-
17
-
79
- return r;
18
- ctx->s_mask = arg_info(op->args[1])->s_mask;
80
+ return false;
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);
81
}
24
}
82
25
83
static void page_init(void)
26
static bool fold_or(OptContext *ctx, TCGOp *op)
84
--
27
--
85
2.25.1
28
2.43.0
86
87
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
1
Reviewed-by: Joelle van Dyne <j@getutm.app>
1
Avoid the use of the OptContext slots.
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>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
9
---
4
include/tcg/tcg.h | 13 +++++++++++++
10
tcg/optimize.c | 26 +++++++++++++++++++++-----
5
1 file changed, 13 insertions(+)
11
1 file changed, 21 insertions(+), 5 deletions(-)
6
12
7
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
13
diff --git a/tcg/optimize.c b/tcg/optimize.c
8
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
9
--- a/include/tcg/tcg.h
15
--- a/tcg/optimize.c
10
+++ b/include/tcg/tcg.h
16
+++ b/tcg/optimize.c
11
@@ -XXX,XX +XXX,XX @@ static inline ptrdiff_t tcg_pcrel_diff(TCGContext *s, const void *target)
17
@@ -XXX,XX +XXX,XX @@ static bool fold_orc(OptContext *ctx, TCGOp *op)
12
return tcg_ptr_byte_diff(target, tcg_splitwx_to_rx(s->code_ptr));
18
return fold_masks_s(ctx, op, s_mask);
13
}
19
}
14
20
15
+/**
21
-static bool fold_qemu_ld(OptContext *ctx, TCGOp *op)
16
+ * tcg_tbrel_diff
22
+static bool fold_qemu_ld_1reg(OptContext *ctx, TCGOp *op)
17
+ * @s: the tcg context
23
{
18
+ * @target: address of the target
24
const TCGOpDef *def = &tcg_op_defs[op->opc];
19
+ *
25
MemOpIdx oi = op->args[def->nb_oargs + def->nb_iargs];
20
+ * Produce a difference, from the beginning of the current TB code
26
MemOp mop = get_memop(oi);
21
+ * to the destination address.
27
int width = 8 * memop_size(mop);
22
+ */
28
+ uint64_t z_mask = -1, s_mask = 0;
23
+static inline ptrdiff_t tcg_tbrel_diff(TCGContext *s, const void *target)
29
24
+{
30
if (width < 64) {
25
+ return tcg_ptr_byte_diff(target, tcg_splitwx_to_rx(s->code_buf));
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);
26
+}
45
+}
27
+
46
+
28
/**
47
+static bool fold_qemu_ld_2reg(OptContext *ctx, TCGOp *op)
29
* tcg_current_code_size
48
+{
30
* @s: the tcg context
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:
31
--
75
--
32
2.25.1
76
2.43.0
33
34
diff view generated by jsdifflib
1
Report better error messages than just "could not allocate".
1
Stores have no output operands, and so need no further work.
2
Let alloc_code_gen_buffer set ctx->code_gen_buffer_size
3
and ctx->code_gen_buffer, and simply return bool.
4
2
5
Reviewed-by: Joelle van Dyne <j@getutm.app>
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
5
---
9
accel/tcg/translate-all.c | 60 ++++++++++++++++++++++-----------------
6
tcg/optimize.c | 11 +++++------
10
1 file changed, 34 insertions(+), 26 deletions(-)
7
1 file changed, 5 insertions(+), 6 deletions(-)
11
8
12
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
13
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
14
--- a/accel/tcg/translate-all.c
11
--- a/tcg/optimize.c
15
+++ b/accel/tcg/translate-all.c
12
+++ b/tcg/optimize.c
16
@@ -XXX,XX +XXX,XX @@
13
@@ -XXX,XX +XXX,XX @@ static bool fold_qemu_st(OptContext *ctx, TCGOp *op)
17
#include "sysemu/cpus.h"
18
#include "sysemu/cpu-timers.h"
19
#include "sysemu/tcg.h"
20
+#include "qapi/error.h"
21
22
/* #define DEBUG_TB_INVALIDATE */
23
/* #define DEBUG_TB_FLUSH */
24
@@ -XXX,XX +XXX,XX @@ static void page_lock_pair(PageDesc **ret_p1, tb_page_addr_t phys1,
25
(DEFAULT_CODE_GEN_BUFFER_SIZE_1 < MAX_CODE_GEN_BUFFER_SIZE \
26
? DEFAULT_CODE_GEN_BUFFER_SIZE_1 : MAX_CODE_GEN_BUFFER_SIZE)
27
28
-static inline size_t size_code_gen_buffer(size_t tb_size)
29
+static size_t size_code_gen_buffer(size_t tb_size)
30
{
14
{
31
/* Size the buffer. */
15
/* Opcodes that touch guest memory stop the mb optimization. */
32
if (tb_size == 0) {
16
ctx->prev_mb = NULL;
33
@@ -XXX,XX +XXX,XX @@ static inline void *split_cross_256mb(void *buf1, size_t size1)
17
- return false;
34
static uint8_t static_code_gen_buffer[DEFAULT_CODE_GEN_BUFFER_SIZE]
35
__attribute__((aligned(CODE_GEN_ALIGN)));
36
37
-static inline void *alloc_code_gen_buffer(void)
38
+static bool alloc_code_gen_buffer(size_t tb_size, Error **errp)
39
{
40
void *buf = static_code_gen_buffer;
41
void *end = static_code_gen_buffer + sizeof(static_code_gen_buffer);
42
@@ -XXX,XX +XXX,XX @@ static inline void *alloc_code_gen_buffer(void)
43
size = end - buf;
44
45
/* Honor a command-line option limiting the size of the buffer. */
46
- if (size > tcg_ctx->code_gen_buffer_size) {
47
- size = QEMU_ALIGN_DOWN(tcg_ctx->code_gen_buffer_size,
48
- qemu_real_host_page_size);
49
+ if (size > tb_size) {
50
+ size = QEMU_ALIGN_DOWN(tb_size, qemu_real_host_page_size);
51
}
52
tcg_ctx->code_gen_buffer_size = size;
53
54
@@ -XXX,XX +XXX,XX @@ static inline void *alloc_code_gen_buffer(void)
55
#endif
56
57
if (qemu_mprotect_rwx(buf, size)) {
58
- abort();
59
+ error_setg_errno(errp, errno, "mprotect of jit buffer");
60
+ return false;
61
}
62
qemu_madvise(buf, size, QEMU_MADV_HUGEPAGE);
63
64
- return buf;
65
+ tcg_ctx->code_gen_buffer = buf;
66
+ return true;
18
+ return true;
67
}
19
}
68
#elif defined(_WIN32)
20
69
-static inline void *alloc_code_gen_buffer(void)
21
static bool fold_remainder(OptContext *ctx, TCGOp *op)
70
+static bool alloc_code_gen_buffer(size_t size, Error **errp)
22
@@ -XXX,XX +XXX,XX @@ static bool fold_tcg_st(OptContext *ctx, TCGOp *op)
71
{
23
72
- size_t size = tcg_ctx->code_gen_buffer_size;
24
if (op->args[1] != tcgv_ptr_arg(tcg_env)) {
73
- return VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT,
25
remove_mem_copy_all(ctx);
74
- PAGE_EXECUTE_READWRITE);
26
- return false;
75
+ void *buf = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT,
27
+ return true;
76
+ PAGE_EXECUTE_READWRITE);
28
}
77
+ if (buf == NULL) {
29
78
+ error_setg_win32(errp, GetLastError(),
30
switch (op->opc) {
79
+ "allocate %zu bytes for jit buffer", size);
31
@@ -XXX,XX +XXX,XX @@ static bool fold_tcg_st(OptContext *ctx, TCGOp *op)
80
+ return false;
32
g_assert_not_reached();
81
+ }
33
}
82
+
34
remove_mem_copy_in(ctx, ofs, ofs + lm1);
83
+ tcg_ctx->code_gen_buffer = buf;
35
- return false;
84
+ tcg_ctx->code_gen_buffer_size = size;
85
+ return true;
36
+ return true;
86
}
37
}
87
#else
38
88
-static inline void *alloc_code_gen_buffer(void)
39
static bool fold_tcg_st_memcopy(OptContext *ctx, TCGOp *op)
89
+static bool alloc_code_gen_buffer(size_t size, Error **errp)
40
@@ -XXX,XX +XXX,XX @@ static bool fold_tcg_st_memcopy(OptContext *ctx, TCGOp *op)
90
{
41
TCGType type;
91
int prot = PROT_WRITE | PROT_READ | PROT_EXEC;
42
92
int flags = MAP_PRIVATE | MAP_ANONYMOUS;
43
if (op->args[1] != tcgv_ptr_arg(tcg_env)) {
93
- size_t size = tcg_ctx->code_gen_buffer_size;
44
- fold_tcg_st(ctx, op);
94
void *buf;
45
- return false;
95
46
+ return fold_tcg_st(ctx, op);
96
buf = mmap(NULL, size, prot, flags, -1, 0);
97
if (buf == MAP_FAILED) {
98
- return NULL;
99
+ error_setg_errno(errp, errno,
100
+ "allocate %zu bytes for jit buffer", size);
101
+ return false;
102
}
47
}
103
+ tcg_ctx->code_gen_buffer_size = size;
48
104
49
src = arg_temp(op->args[0]);
105
#ifdef __mips__
50
@@ -XXX,XX +XXX,XX @@ static bool fold_tcg_st_memcopy(OptContext *ctx, TCGOp *op)
106
if (cross_256mb(buf, size)) {
51
last = ofs + tcg_type_size(type) - 1;
107
@@ -XXX,XX +XXX,XX @@ static inline void *alloc_code_gen_buffer(void)
52
remove_mem_copy_in(ctx, ofs, last);
108
/* Request large pages for the buffer. */
53
record_mem_copy(ctx, type, src, ofs, last);
109
qemu_madvise(buf, size, QEMU_MADV_HUGEPAGE);
54
- return false;
110
111
- return buf;
112
+ tcg_ctx->code_gen_buffer = buf;
113
+ return true;
55
+ return true;
114
}
56
}
115
#endif /* USE_STATIC_CODE_GEN_BUFFER, WIN32, POSIX */
57
116
58
static bool fold_xor(OptContext *ctx, TCGOp *op)
117
-static inline void code_gen_alloc(size_t tb_size)
118
-{
119
- tcg_ctx->code_gen_buffer_size = size_code_gen_buffer(tb_size);
120
- tcg_ctx->code_gen_buffer = alloc_code_gen_buffer();
121
- if (tcg_ctx->code_gen_buffer == NULL) {
122
- fprintf(stderr, "Could not allocate dynamic translator buffer\n");
123
- exit(1);
124
- }
125
-}
126
-
127
static bool tb_cmp(const void *ap, const void *bp)
128
{
129
const TranslationBlock *a = ap;
130
@@ -XXX,XX +XXX,XX @@ static void tb_htable_init(void)
131
size. */
132
void tcg_exec_init(unsigned long tb_size)
133
{
134
+ bool ok;
135
+
136
tcg_allowed = true;
137
cpu_gen_init();
138
page_init();
139
tb_htable_init();
140
- code_gen_alloc(tb_size);
141
+
142
+ ok = alloc_code_gen_buffer(size_code_gen_buffer(tb_size), &error_fatal);
143
+ assert(ok);
144
+
145
#if defined(CONFIG_SOFTMMU)
146
/* There's no guest base to take into account, so go ahead and
147
initialize the prologue now. */
148
--
59
--
149
2.25.1
60
2.43.0
150
151
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
1
There is nothing within the translators that ought to be
1
Change return from bool to int; distinguish between
2
changing the TranslationBlock data, so make it const.
2
complete folding, simplification, and no change.
3
3
4
This does not actually use the read-only copy of the
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
5
data structure that exists within the rx region.
6
7
Reviewed-by: Joelle van Dyne <j@getutm.app>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.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/gen-icount.h | 4 ++--
7
tcg/optimize.c | 22 ++++++++++++++--------
12
include/exec/translator.h | 2 +-
8
1 file changed, 14 insertions(+), 8 deletions(-)
13
include/tcg/tcg-op.h | 2 +-
14
accel/tcg/translator.c | 4 ++--
15
target/arm/translate-a64.c | 2 +-
16
tcg/tcg-op.c | 2 +-
17
6 files changed, 8 insertions(+), 8 deletions(-)
18
9
19
diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
20
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
21
--- a/include/exec/gen-icount.h
12
--- a/tcg/optimize.c
22
+++ b/include/exec/gen-icount.h
13
+++ b/tcg/optimize.c
23
@@ -XXX,XX +XXX,XX @@ static inline void gen_io_end(void)
14
@@ -XXX,XX +XXX,XX @@ static bool fold_remainder(OptContext *ctx, TCGOp *op)
24
tcg_temp_free_i32(tmp);
15
return finish_folding(ctx, op);
25
}
16
}
26
17
27
-static inline void gen_tb_start(TranslationBlock *tb)
18
-static bool fold_setcond_zmask(OptContext *ctx, TCGOp *op, bool neg)
28
+static inline void gen_tb_start(const TranslationBlock *tb)
19
+/* Return 1 if finished, -1 if simplified, 0 if unchanged. */
20
+static int fold_setcond_zmask(OptContext *ctx, TCGOp *op, bool neg)
29
{
21
{
30
TCGv_i32 count, imm;
22
uint64_t a_zmask, b_val;
31
23
TCGCond cond;
32
@@ -XXX,XX +XXX,XX @@ static inline void gen_tb_start(TranslationBlock *tb)
24
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond_zmask(OptContext *ctx, TCGOp *op, bool neg)
33
tcg_temp_free_i32(count);
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;
34
}
35
}
35
36
36
-static inline void gen_tb_end(TranslationBlock *tb, int num_insns)
37
static void fold_setcond_tst_pow2(OptContext *ctx, TCGOp *op, bool neg)
37
+static inline void gen_tb_end(const TranslationBlock *tb, int num_insns)
38
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond(OptContext *ctx, TCGOp *op)
38
{
39
return tcg_opt_gen_movi(ctx, op, op->args[0], i);
39
if (tb_cflags(tb) & CF_USE_ICOUNT) {
40
/* Update the num_insn immediate parameter now that we know
41
diff --git a/include/exec/translator.h b/include/exec/translator.h
42
index XXXXXXX..XXXXXXX 100644
43
--- a/include/exec/translator.h
44
+++ b/include/exec/translator.h
45
@@ -XXX,XX +XXX,XX @@ typedef enum DisasJumpType {
46
* Architecture-agnostic disassembly context.
47
*/
48
typedef struct DisasContextBase {
49
- TranslationBlock *tb;
50
+ const TranslationBlock *tb;
51
target_ulong pc_first;
52
target_ulong pc_next;
53
DisasJumpType is_jmp;
54
diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
55
index XXXXXXX..XXXXXXX 100644
56
--- a/include/tcg/tcg-op.h
57
+++ b/include/tcg/tcg-op.h
58
@@ -XXX,XX +XXX,XX @@ static inline void tcg_gen_insn_start(target_ulong pc, target_ulong a1,
59
* be NULL and @idx should be 0. Otherwise, @tb should be valid and
60
* @idx should be one of the TB_EXIT_ values.
61
*/
62
-void tcg_gen_exit_tb(TranslationBlock *tb, unsigned idx);
63
+void tcg_gen_exit_tb(const TranslationBlock *tb, unsigned idx);
64
65
/**
66
* tcg_gen_goto_tb() - output goto_tb TCG operation
67
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/accel/tcg/translator.c
70
+++ b/accel/tcg/translator.c
71
@@ -XXX,XX +XXX,XX @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
72
}
40
}
73
41
74
/* The disas_log hook may use these values rather than recompute. */
42
- if (fold_setcond_zmask(ctx, op, false)) {
75
- db->tb->size = db->pc_next - db->pc_first;
43
+ i = fold_setcond_zmask(ctx, op, false);
76
- db->tb->icount = db->num_insns;
44
+ if (i > 0) {
77
+ tb->size = db->pc_next - db->pc_first;
45
return true;
78
+ tb->icount = db->num_insns;
46
}
79
47
- fold_setcond_tst_pow2(ctx, op, false);
80
#ifdef DEBUG_DISAS
48
+ if (i == 0) {
81
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
49
+ fold_setcond_tst_pow2(ctx, op, false);
82
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
50
+ }
83
index XXXXXXX..XXXXXXX 100644
51
84
--- a/target/arm/translate-a64.c
52
ctx->z_mask = 1;
85
+++ b/target/arm/translate-a64.c
53
return false;
86
@@ -XXX,XX +XXX,XX @@ static inline bool use_goto_tb(DisasContext *s, int n, uint64_t dest)
54
@@ -XXX,XX +XXX,XX @@ static bool fold_negsetcond(OptContext *ctx, TCGOp *op)
87
55
return tcg_opt_gen_movi(ctx, op, op->args[0], -i);
88
static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
56
}
89
{
57
90
- TranslationBlock *tb;
58
- if (fold_setcond_zmask(ctx, op, true)) {
91
+ const TranslationBlock *tb;
59
+ i = fold_setcond_zmask(ctx, op, true);
92
60
+ if (i > 0) {
93
tb = s->base.tb;
61
return true;
94
if (use_goto_tb(s, n, dest)) {
62
}
95
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
63
- fold_setcond_tst_pow2(ctx, op, true);
96
index XXXXXXX..XXXXXXX 100644
64
+ if (i == 0) {
97
--- a/tcg/tcg-op.c
65
+ fold_setcond_tst_pow2(ctx, op, true);
98
+++ b/tcg/tcg-op.c
66
+ }
99
@@ -XXX,XX +XXX,XX @@ void tcg_gen_extr32_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg)
67
100
68
/* Value is {0,-1} so all bits are repetitions of the sign. */
101
/* QEMU specific operations. */
69
ctx->s_mask = -1;
102
103
-void tcg_gen_exit_tb(TranslationBlock *tb, unsigned idx)
104
+void tcg_gen_exit_tb(const TranslationBlock *tb, unsigned idx)
105
{
106
uintptr_t val = (uintptr_t)tb + idx;
107
108
--
70
--
109
2.25.1
71
2.43.0
110
111
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
1
Reviewed-by: Joelle van Dyne <j@getutm.app>
1
Avoid the use of the OptContext slots.
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
5
---
4
tcg/i386/tcg-target.h | 2 +-
6
tcg/optimize.c | 3 +--
5
tcg/i386/tcg-target.c.inc | 20 +++++++++++---------
7
1 file changed, 1 insertion(+), 2 deletions(-)
6
2 files changed, 12 insertions(+), 10 deletions(-)
7
8
8
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
9
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
10
--- a/tcg/i386/tcg-target.h
11
--- a/tcg/optimize.c
11
+++ b/tcg/i386/tcg-target.h
12
+++ b/tcg/optimize.c
12
@@ -XXX,XX +XXX,XX @@ static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
13
@@ -XXX,XX +XXX,XX @@ static bool fold_negsetcond(OptContext *ctx, TCGOp *op)
13
#define TCG_TARGET_NEED_LDST_LABELS
14
#endif
15
#define TCG_TARGET_NEED_POOL_LABELS
16
-#define TCG_TARGET_SUPPORT_MIRROR 0
17
+#define TCG_TARGET_SUPPORT_MIRROR 1
18
19
#endif
20
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
21
index XXXXXXX..XXXXXXX 100644
22
--- a/tcg/i386/tcg-target.c.inc
23
+++ b/tcg/i386/tcg-target.c.inc
24
@@ -XXX,XX +XXX,XX @@ static bool have_lzcnt;
25
# define have_lzcnt 0
26
#endif
27
28
-static tcg_insn_unit *tb_ret_addr;
29
+static const tcg_insn_unit *tb_ret_addr;
30
31
static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
32
intptr_t value, intptr_t addend)
33
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
34
value += addend;
35
switch(type) {
36
case R_386_PC32:
37
- value -= (uintptr_t)code_ptr;
38
+ value -= (uintptr_t)tcg_splitwx_to_rx(code_ptr);
39
if (value != (int32_t)value) {
40
return false;
41
}
42
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
43
tcg_patch32(code_ptr, value);
44
break;
45
case R_386_PC8:
46
- value -= (uintptr_t)code_ptr;
47
+ value -= (uintptr_t)tcg_splitwx_to_rx(code_ptr);
48
if (value != (int8_t)value) {
49
return false;
50
}
51
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi(TCGContext *s, TCGType type,
52
}
14
}
53
15
54
/* Try a 7 byte pc-relative lea before the 10 byte movq. */
16
/* Value is {0,-1} so all bits are repetitions of the sign. */
55
- diff = arg - ((uintptr_t)s->code_ptr + 7);
17
- ctx->s_mask = -1;
56
+ diff = tcg_pcrel_diff(s, (const void *)arg) - 7;
18
- return false;
57
if (diff == (int32_t)diff) {
19
+ return fold_masks_s(ctx, op, -1);
58
tcg_out_opc(s, OPC_LEA | P_REXW, ret, 0, 0);
59
tcg_out8(s, (LOWREGMASK(ret) << 3) | 5);
60
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_call(TCGContext *s, const tcg_insn_unit *dest)
61
tcg_out_branch(s, 1, dest);
62
}
20
}
63
21
64
-static void tcg_out_jmp(TCGContext *s, tcg_insn_unit *dest)
22
static bool fold_setcond2(OptContext *ctx, TCGOp *op)
65
+static void tcg_out_jmp(TCGContext *s, const tcg_insn_unit *dest)
66
{
67
tcg_out_branch(s, 0, dest);
68
}
69
@@ -XXX,XX +XXX,XX @@ static void add_qemu_ldst_label(TCGContext *s, bool is_ld, bool is_64,
70
label->datahi_reg = datahi;
71
label->addrlo_reg = addrlo;
72
label->addrhi_reg = addrhi;
73
- label->raddr = raddr;
74
+ /* TODO: Cast goes away when all hosts converted */
75
+ label->raddr = (void *)tcg_splitwx_to_rx(raddr);
76
label->label_ptr[0] = label_ptr[0];
77
if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
78
label->label_ptr[1] = label_ptr[1];
79
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
80
/* jump displacement must be aligned for atomic patching;
81
* see if we need to add extra nops before jump
82
*/
83
- gap = tcg_pcrel_diff(s, QEMU_ALIGN_PTR_UP(s->code_ptr + 1, 4));
84
+ gap = QEMU_ALIGN_PTR_UP(s->code_ptr + 1, 4) - s->code_ptr;
85
if (gap != 1) {
86
tcg_out_nopn(s, gap - 1);
87
}
88
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
89
* Return path for goto_ptr. Set return value to 0, a-la exit_tb,
90
* and fall through to the rest of the epilogue.
91
*/
92
- tcg_code_gen_epilogue = s->code_ptr;
93
+ /* TODO: Cast goes away when all hosts converted */
94
+ tcg_code_gen_epilogue = (void *)tcg_splitwx_to_rx(s->code_ptr);
95
tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_EAX, 0);
96
97
/* TB epilogue */
98
- tb_ret_addr = s->code_ptr;
99
+ tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr);
100
101
tcg_out_addi(s, TCG_REG_CALL_STACK, stack_addend);
102
103
--
23
--
104
2.25.1
24
2.43.0
105
106
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
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
1
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
---
5
---
3
tcg/mips/tcg-target.h | 2 +-
6
tcg/optimize.c | 24 +++++++++---------------
4
tcg/mips/tcg-target.c.inc | 43 ++++++++++++++++++++++-----------------
7
1 file changed, 9 insertions(+), 15 deletions(-)
5
2 files changed, 25 insertions(+), 20 deletions(-)
6
8
7
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
8
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/mips/tcg-target.h
11
--- a/tcg/optimize.c
10
+++ b/tcg/mips/tcg-target.h
12
+++ b/tcg/optimize.c
11
@@ -XXX,XX +XXX,XX @@ extern bool use_mips32r2_instructions;
13
@@ -XXX,XX +XXX,XX @@ static bool fold_cmpsel_vec(OptContext *ctx, TCGOp *op)
12
14
static bool fold_sextract(OptContext *ctx, TCGOp *op)
13
#define TCG_TARGET_DEFAULT_MO (0)
14
#define TCG_TARGET_HAS_MEMORY_BSWAP 1
15
-#define TCG_TARGET_SUPPORT_MIRROR 0
16
+#define TCG_TARGET_SUPPORT_MIRROR 1
17
18
void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
19
20
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
21
index XXXXXXX..XXXXXXX 100644
22
--- a/tcg/mips/tcg-target.c.inc
23
+++ b/tcg/mips/tcg-target.c.inc
24
@@ -XXX,XX +XXX,XX @@ static const TCGReg tcg_target_call_oarg_regs[2] = {
25
TCG_REG_V1
26
};
27
28
-static tcg_insn_unit *tb_ret_addr;
29
-static tcg_insn_unit *bswap32_addr;
30
-static tcg_insn_unit *bswap32u_addr;
31
-static tcg_insn_unit *bswap64_addr;
32
+static const tcg_insn_unit *tb_ret_addr;
33
+static const tcg_insn_unit *bswap32_addr;
34
+static const tcg_insn_unit *bswap32u_addr;
35
+static const tcg_insn_unit *bswap64_addr;
36
37
-static bool reloc_pc16(tcg_insn_unit *pc, const tcg_insn_unit *target)
38
+static bool reloc_pc16(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
39
{
15
{
40
/* Let the compiler perform the right-shift as part of the arithmetic. */
16
uint64_t z_mask, s_mask, s_mask_old;
41
- ptrdiff_t disp = target - (pc + 1);
17
+ TempOptInfo *t1 = arg_info(op->args[1]);
42
+ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
18
int pos = op->args[2];
43
+ ptrdiff_t disp = target - (src_rx + 1);
19
int len = op->args[3];
44
if (disp == (int16_t)disp) {
20
45
- *pc = deposit32(*pc, 0, 16, disp);
21
- if (arg_is_const(op->args[1])) {
46
+ *src_rw = deposit32(*src_rw, 0, 16, disp);
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)) {
47
return true;
45
return true;
48
}
46
}
49
return false;
47
50
@@ -XXX,XX +XXX,XX @@ static void tcg_out_opc_sa64(TCGContext *s, MIPSInsn opc1, MIPSInsn opc2,
48
- return fold_masks(ctx, op);
51
static bool tcg_out_opc_jmp(TCGContext *s, MIPSInsn opc, const void *target)
49
+ z_mask = sextract64(t1->z_mask, pos, len);
52
{
50
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
53
uintptr_t dest = (uintptr_t)target;
54
- uintptr_t from = (uintptr_t)s->code_ptr + 4;
55
+ uintptr_t from = (uintptr_t)tcg_splitwx_to_rx(s->code_ptr) + 4;
56
int32_t inst;
57
58
/* The pc-region branch happens within the 256MB region of
59
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg)
60
}
61
}
51
}
62
52
63
-static void tcg_out_bswap_subr(TCGContext *s, tcg_insn_unit *sub)
53
static bool fold_shift(OptContext *ctx, TCGOp *op)
64
+static void tcg_out_bswap_subr(TCGContext *s, const tcg_insn_unit *sub)
65
{
66
bool ok = tcg_out_opc_jmp(s, OPC_JAL, sub);
67
tcg_debug_assert(ok);
68
@@ -XXX,XX +XXX,XX @@ static void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOpIdx oi,
69
label->datahi_reg = datahi;
70
label->addrlo_reg = addrlo;
71
label->addrhi_reg = addrhi;
72
- label->raddr = raddr;
73
+ /* TODO: Cast goes away when all hosts converted */
74
+ label->raddr = (void *)tcg_splitwx_to_rx(raddr);
75
label->label_ptr[0] = label_ptr[0];
76
if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
77
label->label_ptr[1] = label_ptr[1];
78
@@ -XXX,XX +XXX,XX @@ static void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOpIdx oi,
79
80
static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
81
{
82
+ const tcg_insn_unit *tgt_rx = tcg_splitwx_to_rx(s->code_ptr);
83
TCGMemOpIdx oi = l->oi;
84
MemOp opc = get_memop(oi);
85
TCGReg v0;
86
int i;
87
88
/* resolve label address */
89
- if (!reloc_pc16(l->label_ptr[0], s->code_ptr)
90
+ if (!reloc_pc16(l->label_ptr[0], tgt_rx)
91
|| (TCG_TARGET_REG_BITS < TARGET_LONG_BITS
92
- && !reloc_pc16(l->label_ptr[1], s->code_ptr))) {
93
+ && !reloc_pc16(l->label_ptr[1], tgt_rx))) {
94
return false;
95
}
96
97
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
98
99
static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
100
{
101
+ const tcg_insn_unit *tgt_rx = tcg_splitwx_to_rx(s->code_ptr);
102
TCGMemOpIdx oi = l->oi;
103
MemOp opc = get_memop(oi);
104
MemOp s_bits = opc & MO_SIZE;
105
int i;
106
107
/* resolve label address */
108
- if (!reloc_pc16(l->label_ptr[0], s->code_ptr)
109
+ if (!reloc_pc16(l->label_ptr[0], tgt_rx)
110
|| (TCG_TARGET_REG_BITS < TARGET_LONG_BITS
111
- && !reloc_pc16(l->label_ptr[1], s->code_ptr))) {
112
+ && !reloc_pc16(l->label_ptr[1], tgt_rx))) {
113
return false;
114
}
115
116
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
117
* Return path for goto_ptr. Set return value to 0, a-la exit_tb,
118
* and fall through to the rest of the epilogue.
119
*/
120
- tcg_code_gen_epilogue = s->code_ptr;
121
+ /* TODO: Cast goes away when all hosts converted */
122
+ tcg_code_gen_epilogue = (void *)tcg_splitwx_to_rx(s->code_ptr);
123
tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_V0, TCG_REG_ZERO);
124
125
/* TB epilogue */
126
- tb_ret_addr = s->code_ptr;
127
+ tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr);
128
for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
129
tcg_out_ld(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
130
TCG_REG_SP, SAVE_OFS + i * REG_SIZE);
131
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
132
/*
133
* bswap32 -- 32-bit swap (signed result for mips64). a0 = abcd.
134
*/
135
- bswap32_addr = align_code_ptr(s);
136
+ bswap32_addr = tcg_splitwx_to_rx(align_code_ptr(s));
137
/* t3 = (ssss)d000 */
138
tcg_out_opc_sa(s, OPC_SLL, TCG_TMP3, TCG_TMP0, 24);
139
/* t1 = 000a */
140
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
141
/*
142
* bswap32u -- unsigned 32-bit swap. a0 = ....abcd.
143
*/
144
- bswap32u_addr = align_code_ptr(s);
145
+ bswap32u_addr = tcg_splitwx_to_rx(align_code_ptr(s));
146
/* t1 = (0000)000d */
147
tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP1, TCG_TMP0, 0xff);
148
/* t3 = 000a */
149
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
150
/*
151
* bswap64 -- 64-bit swap. a0 = abcdefgh
152
*/
153
- bswap64_addr = align_code_ptr(s);
154
+ bswap64_addr = tcg_splitwx_to_rx(align_code_ptr(s));
155
/* t3 = h0000000 */
156
tcg_out_dsll(s, TCG_TMP3, TCG_TMP0, 56);
157
/* t1 = 0000000a */
158
--
54
--
159
2.25.1
55
2.43.0
160
161
diff view generated by jsdifflib
1
Always true when movbe is available, otherwise leave
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
2
this to generic code.
3
2
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
5
---
7
tcg/i386/tcg-target.h | 3 +-
6
tcg/optimize.c | 27 ++++++++++++++-------------
8
tcg/i386/tcg-target.c.inc | 119 ++++++++++++++------------------------
7
1 file changed, 14 insertions(+), 13 deletions(-)
9
2 files changed, 47 insertions(+), 75 deletions(-)
10
8
11
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
12
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
13
--- a/tcg/i386/tcg-target.h
11
--- a/tcg/optimize.c
14
+++ b/tcg/i386/tcg-target.h
12
+++ b/tcg/optimize.c
15
@@ -XXX,XX +XXX,XX @@ extern bool have_bmi1;
13
@@ -XXX,XX +XXX,XX @@ static bool fold_sextract(OptContext *ctx, TCGOp *op)
16
extern bool have_popcnt;
14
static bool fold_shift(OptContext *ctx, TCGOp *op)
17
extern bool have_avx1;
18
extern bool have_avx2;
19
+extern bool have_movbe;
20
21
/* optional instructions */
22
#define TCG_TARGET_HAS_div2_i32 1
23
@@ -XXX,XX +XXX,XX @@ static inline void tb_target_set_jmp_target(uintptr_t tc_ptr,
24
25
#define TCG_TARGET_DEFAULT_MO (TCG_MO_ALL & ~TCG_MO_ST_LD)
26
27
-#define TCG_TARGET_HAS_MEMORY_BSWAP 1
28
+#define TCG_TARGET_HAS_MEMORY_BSWAP have_movbe
29
30
#ifdef CONFIG_SOFTMMU
31
#define TCG_TARGET_NEED_LDST_LABELS
32
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
33
index XXXXXXX..XXXXXXX 100644
34
--- a/tcg/i386/tcg-target.c.inc
35
+++ b/tcg/i386/tcg-target.c.inc
36
@@ -XXX,XX +XXX,XX @@ bool have_bmi1;
37
bool have_popcnt;
38
bool have_avx1;
39
bool have_avx2;
40
+bool have_movbe;
41
42
#ifdef CONFIG_CPUID_H
43
-static bool have_movbe;
44
static bool have_bmi2;
45
static bool have_lzcnt;
46
#else
47
-# define have_movbe 0
48
# define have_bmi2 0
49
# define have_lzcnt 0
50
#endif
51
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
52
TCGReg base, int index, intptr_t ofs,
53
int seg, bool is64, MemOp memop)
54
{
15
{
55
- const MemOp real_bswap = memop & MO_BSWAP;
16
uint64_t s_mask, z_mask, sign;
56
- MemOp bswap = real_bswap;
17
+ TempOptInfo *t1, *t2;
57
+ bool use_movbe = false;
18
58
int rexw = is64 * P_REXW;
19
if (fold_const2(ctx, op) ||
59
int movop = OPC_MOVL_GvEv;
20
fold_ix_to_i(ctx, op, 0) ||
60
21
@@ -XXX,XX +XXX,XX @@ static bool fold_shift(OptContext *ctx, TCGOp *op)
61
- if (have_movbe && real_bswap) {
22
return true;
62
- bswap = 0;
63
+ /* Do big-endian loads with movbe. */
64
+ if (memop & MO_BSWAP) {
65
+ tcg_debug_assert(have_movbe);
66
+ use_movbe = true;
67
movop = OPC_MOVBE_GyMy;
68
}
23
}
69
24
70
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
25
- s_mask = arg_info(op->args[1])->s_mask;
71
base, index, 0, ofs);
26
- z_mask = arg_info(op->args[1])->z_mask;
72
break;
27
+ t1 = arg_info(op->args[1]);
73
case MO_UW:
28
+ t2 = arg_info(op->args[2]);
74
- tcg_out_modrm_sib_offset(s, OPC_MOVZWL + seg, datalo,
29
+ s_mask = t1->s_mask;
75
- base, index, 0, ofs);
30
+ z_mask = t1->z_mask;
76
- if (real_bswap) {
31
77
- tcg_out_rolw_8(s, datalo);
32
- if (arg_is_const(op->args[2])) {
78
- }
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;
79
- break;
52
- break;
80
- case MO_SW:
53
+ return fold_masks_s(ctx, op, s_mask);
81
- if (real_bswap) {
54
CASE_OP_32_64(shr):
82
- if (have_movbe) {
55
/*
83
+ if (use_movbe) {
56
* If the sign bit is known zero, then logical right shift
84
+ /* There is no extending movbe; only low 16-bits are modified. */
57
- * will not reduced the number of input sign repetitions.
85
+ if (datalo != base && datalo != index) {
58
+ * will not reduce the number of input sign repetitions.
86
+ /* XOR breaks dependency chains. */
59
*/
87
+ tgen_arithr(s, ARITH_XOR, datalo, datalo);
60
- sign = (s_mask & -s_mask) >> 1;
88
tcg_out_modrm_sib_offset(s, OPC_MOVBE_GyMy + P_DATA16 + seg,
61
+ sign = -s_mask;
89
datalo, base, index, 0, ofs);
62
if (sign && !(z_mask & sign)) {
90
} else {
63
- ctx->s_mask = s_mask;
91
- tcg_out_modrm_sib_offset(s, OPC_MOVZWL + seg, datalo,
64
+ return fold_masks_s(ctx, op, s_mask);
92
- base, index, 0, ofs);
93
- tcg_out_rolw_8(s, datalo);
94
+ tcg_out_modrm_sib_offset(s, OPC_MOVBE_GyMy + P_DATA16 + seg,
95
+ datalo, base, index, 0, ofs);
96
+ tcg_out_ext16u(s, datalo, datalo);
97
}
98
- tcg_out_modrm(s, OPC_MOVSWL + rexw, datalo, datalo);
99
+ } else {
100
+ tcg_out_modrm_sib_offset(s, OPC_MOVZWL + seg, datalo,
101
+ base, index, 0, ofs);
102
+ }
103
+ break;
104
+ case MO_SW:
105
+ if (use_movbe) {
106
+ tcg_out_modrm_sib_offset(s, OPC_MOVBE_GyMy + P_DATA16 + seg,
107
+ datalo, base, index, 0, ofs);
108
+ tcg_out_ext16s(s, datalo, datalo, rexw);
109
} else {
110
tcg_out_modrm_sib_offset(s, OPC_MOVSWL + rexw + seg,
111
datalo, base, index, 0, ofs);
112
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
113
break;
114
case MO_UL:
115
tcg_out_modrm_sib_offset(s, movop + seg, datalo, base, index, 0, ofs);
116
- if (bswap) {
117
- tcg_out_bswap32(s, datalo);
118
- }
119
break;
120
#if TCG_TARGET_REG_BITS == 64
121
case MO_SL:
122
- if (real_bswap) {
123
- tcg_out_modrm_sib_offset(s, movop + seg, datalo,
124
+ if (use_movbe) {
125
+ tcg_out_modrm_sib_offset(s, OPC_MOVBE_GyMy + seg, datalo,
126
base, index, 0, ofs);
127
- if (bswap) {
128
- tcg_out_bswap32(s, datalo);
129
- }
130
tcg_out_ext32s(s, datalo, datalo);
131
} else {
132
tcg_out_modrm_sib_offset(s, OPC_MOVSLQ + seg, datalo,
133
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
134
if (TCG_TARGET_REG_BITS == 64) {
135
tcg_out_modrm_sib_offset(s, movop + P_REXW + seg, datalo,
136
base, index, 0, ofs);
137
- if (bswap) {
138
- tcg_out_bswap64(s, datalo);
139
- }
140
} else {
141
- if (real_bswap) {
142
- int t = datalo;
143
+ if (use_movbe) {
144
+ TCGReg t = datalo;
145
datalo = datahi;
146
datahi = t;
147
}
148
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
149
tcg_out_modrm_sib_offset(s, movop + seg, datalo,
150
base, index, 0, ofs);
151
}
152
- if (bswap) {
153
- tcg_out_bswap32(s, datalo);
154
- tcg_out_bswap32(s, datahi);
155
- }
156
}
65
}
157
break;
66
break;
158
default:
67
default:
159
- tcg_abort();
68
break;
160
+ g_assert_not_reached();
161
}
69
}
70
71
- return false;
72
+ return finish_folding(ctx, op);
162
}
73
}
163
74
164
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
75
static bool fold_sub_to_neg(OptContext *ctx, TCGOp *op)
165
TCGReg base, int index, intptr_t ofs,
166
int seg, MemOp memop)
167
{
168
- /* ??? Ideally we wouldn't need a scratch register. For user-only,
169
- we could perform the bswap twice to restore the original value
170
- instead of moving to the scratch. But as it is, the L constraint
171
- means that TCG_REG_L0 is definitely free here. */
172
const TCGReg scratch = TCG_REG_L0;
173
- const MemOp real_bswap = memop & MO_BSWAP;
174
- MemOp bswap = real_bswap;
175
+ bool use_movbe = false;
176
int movop = OPC_MOVL_EvGv;
177
178
- if (have_movbe && real_bswap) {
179
- bswap = 0;
180
+ /*
181
+ * Do big-endian stores with movbe or softmmu.
182
+ * User-only without movbe will have its swapping done generically.
183
+ */
184
+ if (memop & MO_BSWAP) {
185
+ tcg_debug_assert(have_movbe);
186
+ use_movbe = true;
187
movop = OPC_MOVBE_MyGy;
188
}
189
190
switch (memop & MO_SIZE) {
191
case MO_8:
192
- /* In 32-bit mode, 8-bit stores can only happen from [abcd]x.
193
- Use the scratch register if necessary. */
194
+ /*
195
+ * In 32-bit mode, 8-bit stores can only happen from [abcd]x.
196
+ * TODO: Adjust constraints such that this is is forced,
197
+ * then we won't need a scratch at all for user-only.
198
+ */
199
if (TCG_TARGET_REG_BITS == 32 && datalo >= 4) {
200
tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
201
datalo = scratch;
202
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
203
datalo, base, index, 0, ofs);
204
break;
205
case MO_16:
206
- if (bswap) {
207
- tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
208
- tcg_out_rolw_8(s, scratch);
209
- datalo = scratch;
210
- }
211
tcg_out_modrm_sib_offset(s, movop + P_DATA16 + seg, datalo,
212
base, index, 0, ofs);
213
break;
214
case MO_32:
215
- if (bswap) {
216
- tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
217
- tcg_out_bswap32(s, scratch);
218
- datalo = scratch;
219
- }
220
tcg_out_modrm_sib_offset(s, movop + seg, datalo, base, index, 0, ofs);
221
break;
222
case MO_64:
223
if (TCG_TARGET_REG_BITS == 64) {
224
- if (bswap) {
225
- tcg_out_mov(s, TCG_TYPE_I64, scratch, datalo);
226
- tcg_out_bswap64(s, scratch);
227
- datalo = scratch;
228
- }
229
tcg_out_modrm_sib_offset(s, movop + P_REXW + seg, datalo,
230
base, index, 0, ofs);
231
- } else if (bswap) {
232
- tcg_out_mov(s, TCG_TYPE_I32, scratch, datahi);
233
- tcg_out_bswap32(s, scratch);
234
- tcg_out_modrm_sib_offset(s, OPC_MOVL_EvGv + seg, scratch,
235
- base, index, 0, ofs);
236
- tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
237
- tcg_out_bswap32(s, scratch);
238
- tcg_out_modrm_sib_offset(s, OPC_MOVL_EvGv + seg, scratch,
239
- base, index, 0, ofs + 4);
240
} else {
241
- if (real_bswap) {
242
- int t = datalo;
243
+ if (use_movbe) {
244
+ TCGReg t = datalo;
245
datalo = datahi;
246
datahi = t;
247
}
248
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
249
}
250
break;
251
default:
252
- tcg_abort();
253
+ g_assert_not_reached();
254
}
255
}
256
257
--
76
--
258
2.25.1
77
2.43.0
259
260
diff view generated by jsdifflib
1
The maximum TB code gen size is UINT16_MAX, which the current
1
Merge the two conditions, sign != 0 && !(z_mask & sign),
2
code does not support. Use our utility function to optimally
2
by testing ~z_mask & sign. If sign == 0, the logical and
3
add an arbitrary constant.
3
will produce false.
4
4
5
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
---
7
tcg/ppc/tcg-target.c.inc | 5 ++---
8
tcg/optimize.c | 5 ++---
8
1 file changed, 2 insertions(+), 3 deletions(-)
9
1 file changed, 2 insertions(+), 3 deletions(-)
9
10
10
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
11
diff --git a/tcg/optimize.c b/tcg/optimize.c
11
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/ppc/tcg-target.c.inc
13
--- a/tcg/optimize.c
13
+++ b/tcg/ppc/tcg-target.c.inc
14
+++ b/tcg/optimize.c
14
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
15
@@ -XXX,XX +XXX,XX @@ static bool fold_sextract(OptContext *ctx, TCGOp *op)
15
set_jmp_reset_offset(s, args[0]);
16
16
if (USE_REG_TB) {
17
static bool fold_shift(OptContext *ctx, TCGOp *op)
17
/* For the unlinked case, need to reset TCG_REG_TB. */
18
{
18
- c = -tcg_current_code_size(s);
19
- uint64_t s_mask, z_mask, sign;
19
- assert(c == (int16_t)c);
20
+ uint64_t s_mask, z_mask;
20
- tcg_out32(s, ADDI | TAI(TCG_REG_TB, TCG_REG_TB, c));
21
TempOptInfo *t1, *t2;
21
+ tcg_out_mem_long(s, ADDI, ADD, TCG_REG_TB, TCG_REG_TB,
22
22
+ -tcg_current_code_size(s));
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);
23
}
32
}
24
break;
33
break;
25
case INDEX_op_goto_ptr:
26
--
34
--
27
2.25.1
35
2.43.0
28
29
diff view generated by jsdifflib
1
Duplicate fold_sub_vec into fold_sub instead of calling it,
2
now that fold_sub_vec always returns true.
3
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
1
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
---
6
---
3
tcg/arm/tcg-target.h | 2 +-
7
tcg/optimize.c | 9 ++++++---
4
tcg/arm/tcg-target.c.inc | 37 +++++++++++++++++++++----------------
8
1 file changed, 6 insertions(+), 3 deletions(-)
5
2 files changed, 22 insertions(+), 17 deletions(-)
6
9
7
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
8
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/arm/tcg-target.h
12
--- a/tcg/optimize.c
10
+++ b/tcg/arm/tcg-target.h
13
+++ b/tcg/optimize.c
11
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
14
@@ -XXX,XX +XXX,XX @@ static bool fold_sub_vec(OptContext *ctx, TCGOp *op)
12
#define TCG_TARGET_NEED_LDST_LABELS
15
fold_sub_to_neg(ctx, op)) {
13
#endif
14
#define TCG_TARGET_NEED_POOL_LABELS
15
-#define TCG_TARGET_SUPPORT_MIRROR 0
16
+#define TCG_TARGET_SUPPORT_MIRROR 1
17
18
#endif
19
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
20
index XXXXXXX..XXXXXXX 100644
21
--- a/tcg/arm/tcg-target.c.inc
22
+++ b/tcg/arm/tcg-target.c.inc
23
@@ -XXX,XX +XXX,XX @@ static const uint8_t tcg_cond_to_arm_cond[] = {
24
[TCG_COND_GTU] = COND_HI,
25
};
26
27
-static inline bool reloc_pc24(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
28
+static bool reloc_pc24(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
29
{
30
- ptrdiff_t offset = (tcg_ptr_byte_diff(target, code_ptr) - 8) >> 2;
31
+ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
32
+ ptrdiff_t offset = (tcg_ptr_byte_diff(target, src_rx) - 8) >> 2;
33
+
34
if (offset == sextract32(offset, 0, 24)) {
35
- *code_ptr = (*code_ptr & ~0xffffff) | (offset & 0xffffff);
36
+ *src_rw = deposit32(*src_rw, 0, 24, offset);
37
return true;
16
return true;
38
}
17
}
39
return false;
18
- return false;
19
+ return finish_folding(ctx, op);
40
}
20
}
41
21
42
-static inline bool reloc_pc13(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
22
static bool fold_sub(OptContext *ctx, TCGOp *op)
43
+static bool reloc_pc13(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
44
{
23
{
45
- ptrdiff_t offset = tcg_ptr_byte_diff(target, code_ptr) - 8;
24
- if (fold_const2(ctx, op) || fold_sub_vec(ctx, op)) {
46
+ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
25
+ if (fold_const2(ctx, op) ||
47
+ ptrdiff_t offset = tcg_ptr_byte_diff(target, src_rx) - 8;
26
+ fold_xx_to_i(ctx, op, 0) ||
48
27
+ fold_xi_to_x(ctx, op, 0) ||
49
if (offset >= -0xfff && offset <= 0xfff) {
28
+ fold_sub_to_neg(ctx, op)) {
50
- tcg_insn_unit insn = *code_ptr;
51
+ tcg_insn_unit insn = *src_rw;
52
bool u = (offset >= 0);
53
if (!u) {
54
offset = -offset;
55
}
56
insn = deposit32(insn, 23, 1, u);
57
insn = deposit32(insn, 0, 12, offset);
58
- *code_ptr = insn;
59
+ *src_rw = insn;
60
return true;
29
return true;
61
}
30
}
62
return false;
31
63
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
32
@@ -XXX,XX +XXX,XX @@ static bool fold_sub(OptContext *ctx, TCGOp *op)
64
tcg_debug_assert(addend == 0);
33
? INDEX_op_add_i32 : INDEX_op_add_i64);
65
34
op->args[2] = arg_new_constant(ctx, -val);
66
if (type == R_ARM_PC24) {
67
- return reloc_pc24(code_ptr, (tcg_insn_unit *)value);
68
+ return reloc_pc24(code_ptr, (const tcg_insn_unit *)value);
69
} else if (type == R_ARM_PC13) {
70
- return reloc_pc13(code_ptr, (tcg_insn_unit *)value);
71
+ return reloc_pc13(code_ptr, (const tcg_insn_unit *)value);
72
} else {
73
g_assert_not_reached();
74
}
35
}
75
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi32(TCGContext *s, int cond, int rd, uint32_t arg)
36
- return false;
76
37
+ return finish_folding(ctx, op);
77
/* Check for a pc-relative address. This will usually be the TB,
78
or within the TB, which is immediately before the code block. */
79
- diff = arg - ((intptr_t)s->code_ptr + 8);
80
+ diff = tcg_pcrel_diff(s, (void *)arg) - 8;
81
if (diff >= 0) {
82
rot = encode_imm(diff);
83
if (rot >= 0) {
84
@@ -XXX,XX +XXX,XX @@ static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
85
label->datahi_reg = datahi;
86
label->addrlo_reg = addrlo;
87
label->addrhi_reg = addrhi;
88
- label->raddr = raddr;
89
+ /* TODO: Cast goes away when all hosts converted */
90
+ label->raddr = (void *)tcg_splitwx_to_rx(raddr);
91
label->label_ptr[0] = label_ptr;
92
}
38
}
93
39
94
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
40
static bool fold_sub2(OptContext *ctx, TCGOp *op)
95
MemOp opc = get_memop(oi);
96
void *func;
97
98
- if (!reloc_pc24(lb->label_ptr[0], s->code_ptr)) {
99
+ if (!reloc_pc24(lb->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
100
return false;
101
}
102
103
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
104
TCGMemOpIdx oi = lb->oi;
105
MemOp opc = get_memop(oi);
106
107
- if (!reloc_pc24(lb->label_ptr[0], s->code_ptr)) {
108
+ if (!reloc_pc24(lb->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
109
return false;
110
}
111
112
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
113
TCGReg base = TCG_REG_PC;
114
115
tcg_debug_assert(s->tb_jmp_insn_offset == 0);
116
- ptr = (intptr_t)(s->tb_jmp_target_addr + args[0]);
117
- dif = ptr - ((intptr_t)s->code_ptr + 8);
118
+ ptr = (intptr_t)tcg_splitwx_to_rx(s->tb_jmp_target_addr + args[0]);
119
+ dif = tcg_pcrel_diff(s, (void *)ptr) - 8;
120
dil = sextract32(dif, 0, 12);
121
if (dif != dil) {
122
/* The TB is close, but outside the 12 bits addressable by
123
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
124
* Return path for goto_ptr. Set return value to 0, a-la exit_tb,
125
* and fall through to the rest of the epilogue.
126
*/
127
- tcg_code_gen_epilogue = s->code_ptr;
128
+ /* TODO: Cast goes away when all hosts converted */
129
+ tcg_code_gen_epilogue = (void *)tcg_splitwx_to_rx(s->code_ptr);
130
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R0, 0);
131
tcg_out_epilogue(s);
132
}
133
--
41
--
134
2.25.1
42
2.43.0
135
136
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
Enable this on i386 to restrict the set of input registers
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
for an 8-bit store, as required by the architecture. This
3
removes the last use of scratch registers for user-only mode.
4
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
3
---
8
include/tcg/tcg-opc.h | 5 +++++
4
tcg/optimize.c | 2 +-
9
tcg/aarch64/tcg-target.h | 1 +
5
1 file changed, 1 insertion(+), 1 deletion(-)
10
tcg/arm/tcg-target.h | 1 +
11
tcg/i386/tcg-target.h | 3 +++
12
tcg/mips/tcg-target.h | 1 +
13
tcg/ppc/tcg-target.h | 1 +
14
tcg/riscv/tcg-target.h | 1 +
15
tcg/s390/tcg-target.h | 1 +
16
tcg/sparc/tcg-target.h | 1 +
17
tcg/tci/tcg-target.h | 1 +
18
tcg/optimize.c | 1 +
19
tcg/tcg-op.c | 6 +++++-
20
tcg/tcg.c | 4 ++++
21
tcg/i386/tcg-target.c.inc | 29 ++++++++++++++++++-----------
22
tcg/README | 5 +++++
23
15 files changed, 49 insertions(+), 12 deletions(-)
24
6
25
diff --git a/include/tcg/tcg-opc.h b/include/tcg/tcg-opc.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/tcg/tcg-opc.h
28
+++ b/include/tcg/tcg-opc.h
29
@@ -XXX,XX +XXX,XX @@ DEF(qemu_ld_i64, DATA64_ARGS, TLADDR_ARGS, 1,
30
DEF(qemu_st_i64, 0, TLADDR_ARGS + DATA64_ARGS, 1,
31
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT)
32
33
+/* Only used by i386 to cope with stupid register constraints. */
34
+DEF(qemu_st8_i32, 0, TLADDR_ARGS + 1, 1,
35
+ TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS |
36
+ IMPL(TCG_TARGET_HAS_qemu_st8_i32))
37
+
38
/* Host vector support. */
39
40
#define IMPLVEC TCG_OPF_VECTOR | IMPL(TCG_TARGET_MAYBE_vec)
41
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
42
index XXXXXXX..XXXXXXX 100644
43
--- a/tcg/aarch64/tcg-target.h
44
+++ b/tcg/aarch64/tcg-target.h
45
@@ -XXX,XX +XXX,XX @@ typedef enum {
46
#define TCG_TARGET_HAS_extrl_i64_i32 0
47
#define TCG_TARGET_HAS_extrh_i64_i32 0
48
#define TCG_TARGET_HAS_goto_ptr 1
49
+#define TCG_TARGET_HAS_qemu_st8_i32 0
50
51
#define TCG_TARGET_HAS_div_i64 1
52
#define TCG_TARGET_HAS_rem_i64 1
53
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
54
index XXXXXXX..XXXXXXX 100644
55
--- a/tcg/arm/tcg-target.h
56
+++ b/tcg/arm/tcg-target.h
57
@@ -XXX,XX +XXX,XX @@ extern bool use_idiv_instructions;
58
#define TCG_TARGET_HAS_rem_i32 0
59
#define TCG_TARGET_HAS_goto_ptr 1
60
#define TCG_TARGET_HAS_direct_jump 0
61
+#define TCG_TARGET_HAS_qemu_st8_i32 0
62
63
enum {
64
TCG_AREG0 = TCG_REG_R6,
65
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
66
index XXXXXXX..XXXXXXX 100644
67
--- a/tcg/i386/tcg-target.h
68
+++ b/tcg/i386/tcg-target.h
69
@@ -XXX,XX +XXX,XX @@ extern bool have_movbe;
70
#define TCG_TARGET_HAS_muls2_i64 1
71
#define TCG_TARGET_HAS_muluh_i64 0
72
#define TCG_TARGET_HAS_mulsh_i64 0
73
+#define TCG_TARGET_HAS_qemu_st8_i32 0
74
+#else
75
+#define TCG_TARGET_HAS_qemu_st8_i32 1
76
#endif
77
78
/* We do not support older SSE systems, only beginning with AVX1. */
79
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
80
index XXXXXXX..XXXXXXX 100644
81
--- a/tcg/mips/tcg-target.h
82
+++ b/tcg/mips/tcg-target.h
83
@@ -XXX,XX +XXX,XX @@ extern bool use_mips32r2_instructions;
84
#define TCG_TARGET_HAS_clz_i32 use_mips32r2_instructions
85
#define TCG_TARGET_HAS_ctz_i32 0
86
#define TCG_TARGET_HAS_ctpop_i32 0
87
+#define TCG_TARGET_HAS_qemu_st8_i32 0
88
89
#if TCG_TARGET_REG_BITS == 64
90
#define TCG_TARGET_HAS_movcond_i64 use_movnz_instructions
91
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
92
index XXXXXXX..XXXXXXX 100644
93
--- a/tcg/ppc/tcg-target.h
94
+++ b/tcg/ppc/tcg-target.h
95
@@ -XXX,XX +XXX,XX @@ extern bool have_vsx;
96
#define TCG_TARGET_HAS_mulsh_i32 1
97
#define TCG_TARGET_HAS_goto_ptr 1
98
#define TCG_TARGET_HAS_direct_jump 1
99
+#define TCG_TARGET_HAS_qemu_st8_i32 0
100
101
#if TCG_TARGET_REG_BITS == 64
102
#define TCG_TARGET_HAS_add2_i32 0
103
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
104
index XXXXXXX..XXXXXXX 100644
105
--- a/tcg/riscv/tcg-target.h
106
+++ b/tcg/riscv/tcg-target.h
107
@@ -XXX,XX +XXX,XX @@ typedef enum {
108
#define TCG_TARGET_HAS_direct_jump 0
109
#define TCG_TARGET_HAS_brcond2 1
110
#define TCG_TARGET_HAS_setcond2 1
111
+#define TCG_TARGET_HAS_qemu_st8_i32 0
112
113
#if TCG_TARGET_REG_BITS == 64
114
#define TCG_TARGET_HAS_movcond_i64 0
115
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
116
index XXXXXXX..XXXXXXX 100644
117
--- a/tcg/s390/tcg-target.h
118
+++ b/tcg/s390/tcg-target.h
119
@@ -XXX,XX +XXX,XX @@ extern uint64_t s390_facilities;
120
#define TCG_TARGET_HAS_extrh_i64_i32 0
121
#define TCG_TARGET_HAS_goto_ptr 1
122
#define TCG_TARGET_HAS_direct_jump (s390_facilities & FACILITY_GEN_INST_EXT)
123
+#define TCG_TARGET_HAS_qemu_st8_i32 0
124
125
#define TCG_TARGET_HAS_div2_i64 1
126
#define TCG_TARGET_HAS_rot_i64 1
127
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
128
index XXXXXXX..XXXXXXX 100644
129
--- a/tcg/sparc/tcg-target.h
130
+++ b/tcg/sparc/tcg-target.h
131
@@ -XXX,XX +XXX,XX @@ extern bool use_vis3_instructions;
132
#define TCG_TARGET_HAS_mulsh_i32 0
133
#define TCG_TARGET_HAS_goto_ptr 1
134
#define TCG_TARGET_HAS_direct_jump 1
135
+#define TCG_TARGET_HAS_qemu_st8_i32 0
136
137
#define TCG_TARGET_HAS_extrl_i64_i32 1
138
#define TCG_TARGET_HAS_extrh_i64_i32 1
139
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
140
index XXXXXXX..XXXXXXX 100644
141
--- a/tcg/tci/tcg-target.h
142
+++ b/tcg/tci/tcg-target.h
143
@@ -XXX,XX +XXX,XX @@
144
#define TCG_TARGET_HAS_mulsh_i32 0
145
#define TCG_TARGET_HAS_goto_ptr 0
146
#define TCG_TARGET_HAS_direct_jump 1
147
+#define TCG_TARGET_HAS_qemu_st8_i32 0
148
149
#if TCG_TARGET_REG_BITS == 64
150
#define TCG_TARGET_HAS_extrl_i64_i32 0
151
diff --git a/tcg/optimize.c b/tcg/optimize.c
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
152
index XXXXXXX..XXXXXXX 100644
8
index XXXXXXX..XXXXXXX 100644
153
--- a/tcg/optimize.c
9
--- a/tcg/optimize.c
154
+++ b/tcg/optimize.c
10
+++ b/tcg/optimize.c
155
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s)
11
@@ -XXX,XX +XXX,XX @@ static bool fold_tcg_ld_memcopy(OptContext *ctx, TCGOp *op)
156
case INDEX_op_qemu_ld_i32:
12
TCGType type;
157
case INDEX_op_qemu_ld_i64:
13
158
case INDEX_op_qemu_st_i32:
14
if (op->args[1] != tcgv_ptr_arg(tcg_env)) {
159
+ case INDEX_op_qemu_st8_i32:
15
- return false;
160
case INDEX_op_qemu_st_i64:
16
+ return finish_folding(ctx, op);
161
case INDEX_op_call:
162
/* Opcodes that touch guest memory stop the optimization. */
163
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
164
index XXXXXXX..XXXXXXX 100644
165
--- a/tcg/tcg-op.c
166
+++ b/tcg/tcg-op.c
167
@@ -XXX,XX +XXX,XX @@ void tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCGArg idx, MemOp memop)
168
}
17
}
169
18
170
addr = plugin_prep_mem_callbacks(addr);
19
type = ctx->type;
171
- gen_ldst_i32(INDEX_op_qemu_st_i32, val, addr, memop, idx);
172
+ if (TCG_TARGET_HAS_qemu_st8_i32 && (memop & MO_SIZE) == MO_8) {
173
+ gen_ldst_i32(INDEX_op_qemu_st8_i32, val, addr, memop, idx);
174
+ } else {
175
+ gen_ldst_i32(INDEX_op_qemu_st_i32, val, addr, memop, idx);
176
+ }
177
plugin_gen_mem_callbacks(addr, info);
178
179
if (swap) {
180
diff --git a/tcg/tcg.c b/tcg/tcg.c
181
index XXXXXXX..XXXXXXX 100644
182
--- a/tcg/tcg.c
183
+++ b/tcg/tcg.c
184
@@ -XXX,XX +XXX,XX @@ bool tcg_op_supported(TCGOpcode op)
185
case INDEX_op_qemu_st_i64:
186
return true;
187
188
+ case INDEX_op_qemu_st8_i32:
189
+ return TCG_TARGET_HAS_qemu_st8_i32;
190
+
191
case INDEX_op_goto_ptr:
192
return TCG_TARGET_HAS_goto_ptr;
193
194
@@ -XXX,XX +XXX,XX @@ static void tcg_dump_ops(TCGContext *s, bool have_prefs)
195
break;
196
case INDEX_op_qemu_ld_i32:
197
case INDEX_op_qemu_st_i32:
198
+ case INDEX_op_qemu_st8_i32:
199
case INDEX_op_qemu_ld_i64:
200
case INDEX_op_qemu_st_i64:
201
{
202
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
203
index XXXXXXX..XXXXXXX 100644
204
--- a/tcg/i386/tcg-target.c.inc
205
+++ b/tcg/i386/tcg-target.c.inc
206
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
207
ct->regs |= ALL_VECTOR_REGS;
208
break;
209
210
- /* qemu_ld/st address constraint */
211
case 'L':
212
+ /* qemu_ld/st data+address constraint */
213
ct->regs = TCG_TARGET_REG_BITS == 64 ? 0xffff : 0xff;
214
+#ifdef CONFIG_SOFTMMU
215
tcg_regset_reset_reg(ct->regs, TCG_REG_L0);
216
tcg_regset_reset_reg(ct->regs, TCG_REG_L1);
217
+#endif
218
+ break;
219
+ case 's':
220
+ /* qemu_st8_i32 data constraint */
221
+ ct->regs = 0xf;
222
+#ifdef CONFIG_SOFTMMU
223
+ tcg_regset_reset_reg(ct->regs, TCG_REG_L0);
224
+ tcg_regset_reset_reg(ct->regs, TCG_REG_L1);
225
+#endif
226
break;
227
228
case 'e':
229
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
230
TCGReg base, int index, intptr_t ofs,
231
int seg, MemOp memop)
232
{
233
- const TCGReg scratch = TCG_REG_L0;
234
bool use_movbe = false;
235
int movop = OPC_MOVL_EvGv;
236
237
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
238
239
switch (memop & MO_SIZE) {
240
case MO_8:
241
- /*
242
- * In 32-bit mode, 8-bit stores can only happen from [abcd]x.
243
- * TODO: Adjust constraints such that this is is forced,
244
- * then we won't need a scratch at all for user-only.
245
- */
246
- if (TCG_TARGET_REG_BITS == 32 && datalo >= 4) {
247
- tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
248
- datalo = scratch;
249
- }
250
+ /* This is handled with constraints on INDEX_op_qemu_st8_i32. */
251
+ tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || datalo < 4);
252
tcg_out_modrm_sib_offset(s, OPC_MOVB_EvGv + P_REXB_R + seg,
253
datalo, base, index, 0, ofs);
254
break;
255
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
256
tcg_out_qemu_ld(s, args, 1);
257
break;
258
case INDEX_op_qemu_st_i32:
259
+ case INDEX_op_qemu_st8_i32:
260
tcg_out_qemu_st(s, args, 0);
261
break;
262
case INDEX_op_qemu_st_i64:
263
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
264
static const TCGTargetOpDef r_0_ci = { .args_ct_str = { "r", "0", "ci" } };
265
static const TCGTargetOpDef r_L = { .args_ct_str = { "r", "L" } };
266
static const TCGTargetOpDef L_L = { .args_ct_str = { "L", "L" } };
267
+ static const TCGTargetOpDef s_L = { .args_ct_str = { "s", "L" } };
268
static const TCGTargetOpDef r_L_L = { .args_ct_str = { "r", "L", "L" } };
269
static const TCGTargetOpDef r_r_L = { .args_ct_str = { "r", "r", "L" } };
270
static const TCGTargetOpDef L_L_L = { .args_ct_str = { "L", "L", "L" } };
271
+ static const TCGTargetOpDef s_L_L = { .args_ct_str = { "s", "L", "L" } };
272
static const TCGTargetOpDef r_r_L_L
273
= { .args_ct_str = { "r", "r", "L", "L" } };
274
static const TCGTargetOpDef L_L_L_L
275
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
276
return TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &r_L : &r_L_L;
277
case INDEX_op_qemu_st_i32:
278
return TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &L_L : &L_L_L;
279
+ case INDEX_op_qemu_st8_i32:
280
+ return TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &s_L : &s_L_L;
281
case INDEX_op_qemu_ld_i64:
282
return (TCG_TARGET_REG_BITS == 64 ? &r_L
283
: TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? &r_r_L
284
diff --git a/tcg/README b/tcg/README
285
index XXXXXXX..XXXXXXX 100644
286
--- a/tcg/README
287
+++ b/tcg/README
288
@@ -XXX,XX +XXX,XX @@ goto_ptr opcode, emitting this op is equivalent to emitting exit_tb(0).
289
290
* qemu_ld_i32/i64 t0, t1, flags, memidx
291
* qemu_st_i32/i64 t0, t1, flags, memidx
292
+* qemu_st8_i32 t0, t1, flags, memidx
293
294
Load data at the guest address t1 into t0, or store data in t0 at guest
295
address t1. The _i32/_i64 size applies to the size of the input/output
296
@@ -XXX,XX +XXX,XX @@ of the memory access.
297
For a 32-bit host, qemu_ld/st_i64 is guaranteed to only be used with a
298
64-bit memory access specified in flags.
299
300
+For i386, qemu_st8_i32 is exactly like qemu_st_i32, except the size of
301
+the memory operation is known to be 8-bit. This allows the backend to
302
+provide a different set of register constraints.
303
+
304
********* Host vector operations
305
306
All of the vector ops have two parameters, TCGOP_VECL & TCGOP_VECE.
307
--
20
--
308
2.25.1
21
2.43.0
309
310
diff view generated by jsdifflib
1
Simplify the arguments to always use s->code_ptr instead of
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
2
take it as an argument. That makes it easy to ensure that
2
Remove fold_masks as the function becomes unused.
3
the value_ptr is always the rx version.
4
3
5
Reviewed-by: Joelle van Dyne <j@getutm.app>
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
6
---
9
tcg/tcg.c | 6 +++---
7
tcg/optimize.c | 18 ++++++++----------
10
tcg/i386/tcg-target.c.inc | 10 +++++-----
8
1 file changed, 8 insertions(+), 10 deletions(-)
11
2 files changed, 8 insertions(+), 8 deletions(-)
12
9
13
diff --git a/tcg/tcg.c b/tcg/tcg.c
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
14
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
15
--- a/tcg/tcg.c
12
--- a/tcg/optimize.c
16
+++ b/tcg/tcg.c
13
+++ b/tcg/optimize.c
17
@@ -XXX,XX +XXX,XX @@ static void tcg_out_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
14
@@ -XXX,XX +XXX,XX @@ static bool fold_masks_s(OptContext *ctx, TCGOp *op, uint64_t s_mask)
18
QSIMPLEQ_INSERT_TAIL(&l->relocs, r, next);
15
return fold_masks_zs(ctx, op, -1, s_mask);
19
}
16
}
20
17
21
-static void tcg_out_label(TCGContext *s, TCGLabel *l, tcg_insn_unit *ptr)
18
-static bool fold_masks(OptContext *ctx, TCGOp *op)
22
+static void tcg_out_label(TCGContext *s, TCGLabel *l)
19
-{
20
- return fold_masks_zs(ctx, op, ctx->z_mask, ctx->s_mask);
21
-}
22
-
23
/*
24
* An "affected" mask bit is 0 if and only if the result is identical
25
* to the first input. Thus if the entire mask is 0, the operation
26
@@ -XXX,XX +XXX,XX @@ static bool fold_tcg_st_memcopy(OptContext *ctx, TCGOp *op)
27
28
static bool fold_xor(OptContext *ctx, TCGOp *op)
23
{
29
{
24
tcg_debug_assert(!l->has_value);
30
+ uint64_t z_mask, s_mask;
25
l->has_value = 1;
31
+ TempOptInfo *t1, *t2;
26
- l->u.value_ptr = tcg_splitwx_to_rx(ptr);
32
+
27
+ l->u.value_ptr = tcg_splitwx_to_rx(s->code_ptr);
33
if (fold_const2_commutative(ctx, op) ||
34
fold_xx_to_i(ctx, op, 0) ||
35
fold_xi_to_x(ctx, op, 0) ||
36
@@ -XXX,XX +XXX,XX @@ static bool fold_xor(OptContext *ctx, TCGOp *op)
37
return true;
38
}
39
40
- ctx->z_mask = arg_info(op->args[1])->z_mask
41
- | arg_info(op->args[2])->z_mask;
42
- ctx->s_mask = arg_info(op->args[1])->s_mask
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);
28
}
50
}
29
51
30
TCGLabel *gen_new_label(void)
52
static bool fold_bitsel_vec(OptContext *ctx, TCGOp *op)
31
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
32
break;
33
case INDEX_op_set_label:
34
tcg_reg_alloc_bb_end(s, s->reserved_regs);
35
- tcg_out_label(s, arg_label(op->args[0]), s->code_ptr);
36
+ tcg_out_label(s, arg_label(op->args[0]));
37
break;
38
case INDEX_op_call:
39
tcg_reg_alloc_call(s, op);
40
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
41
index XXXXXXX..XXXXXXX 100644
42
--- a/tcg/i386/tcg-target.c.inc
43
+++ b/tcg/i386/tcg-target.c.inc
44
@@ -XXX,XX +XXX,XX @@ static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
45
default:
46
tcg_abort();
47
}
48
- tcg_out_label(s, label_next, s->code_ptr);
49
+ tcg_out_label(s, label_next);
50
}
51
#endif
52
53
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
54
55
tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
56
tcg_out_jxx(s, JCC_JMP, label_over, 1);
57
- tcg_out_label(s, label_true, s->code_ptr);
58
+ tcg_out_label(s, label_true);
59
60
tcg_out_movi(s, TCG_TYPE_I32, args[0], 1);
61
- tcg_out_label(s, label_over, s->code_ptr);
62
+ tcg_out_label(s, label_over);
63
} else {
64
/* When the destination does not overlap one of the arguments,
65
clear the destination first, jump if cond false, and emit an
66
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
67
tcg_out_brcond2(s, new_args, const_args+1, 1);
68
69
tgen_arithi(s, ARITH_ADD, args[0], 1, 0);
70
- tcg_out_label(s, label_over, s->code_ptr);
71
+ tcg_out_label(s, label_over);
72
}
73
}
74
#endif
75
@@ -XXX,XX +XXX,XX @@ static void tcg_out_cmov(TCGContext *s, TCGCond cond, int rexw,
76
TCGLabel *over = gen_new_label();
77
tcg_out_jxx(s, tcg_cond_to_jcc[tcg_invert_cond(cond)], over, 1);
78
tcg_out_mov(s, TCG_TYPE_I32, dest, v1);
79
- tcg_out_label(s, over, s->code_ptr);
80
+ tcg_out_label(s, over);
81
}
82
}
83
84
--
53
--
85
2.25.1
54
2.43.0
86
87
diff view generated by jsdifflib
1
This produces a small pc-relative displacement within the
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
generated code to the TB structure that preceeds it.
3
4
Reviewed-by: Joelle van Dyne <j@getutm.app>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
3
---
7
accel/tcg/cpu-exec.c | 35 +++++++++++++++++++++--------------
4
tcg/optimize.c | 2 +-
8
tcg/tcg-op.c | 13 ++++++++++++-
5
1 file changed, 1 insertion(+), 1 deletion(-)
9
2 files changed, 33 insertions(+), 15 deletions(-)
10
6
11
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
12
index XXXXXXX..XXXXXXX 100644
8
index XXXXXXX..XXXXXXX 100644
13
--- a/accel/tcg/cpu-exec.c
9
--- a/tcg/optimize.c
14
+++ b/accel/tcg/cpu-exec.c
10
+++ b/tcg/optimize.c
15
@@ -XXX,XX +XXX,XX @@ static void init_delay_params(SyncClocks *sc, const CPUState *cpu)
11
@@ -XXX,XX +XXX,XX @@ static bool fold_bitsel_vec(OptContext *ctx, TCGOp *op)
16
* TCG is not considered a security-sensitive part of QEMU so this does not
12
return fold_orc(ctx, op);
17
* affect the impact of CFI in environment with high security requirements
18
*/
19
-QEMU_DISABLE_CFI
20
-static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb)
21
+static inline TranslationBlock * QEMU_DISABLE_CFI
22
+cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit)
23
{
24
CPUArchState *env = cpu->env_ptr;
25
uintptr_t ret;
26
TranslationBlock *last_tb;
27
- int tb_exit;
28
const void *tb_ptr = itb->tc.ptr;
29
30
qemu_log_mask_and_addr(CPU_LOG_EXEC, itb->pc,
31
@@ -XXX,XX +XXX,XX @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb)
32
33
ret = tcg_qemu_tb_exec(env, tb_ptr);
34
cpu->can_do_io = 1;
35
- last_tb = (TranslationBlock *)(ret & ~TB_EXIT_MASK);
36
- tb_exit = ret & TB_EXIT_MASK;
37
- trace_exec_tb_exit(last_tb, tb_exit);
38
+ /*
39
+ * TODO: Delay swapping back to the read-write region of the TB
40
+ * until we actually need to modify the TB. The read-only copy,
41
+ * coming from the rx region, shares the same host TLB entry as
42
+ * the code that executed the exit_tb opcode that arrived here.
43
+ * If we insist on touching both the RX and the RW pages, we
44
+ * double the host TLB pressure.
45
+ */
46
+ last_tb = tcg_splitwx_to_rw((void *)(ret & ~TB_EXIT_MASK));
47
+ *tb_exit = ret & TB_EXIT_MASK;
48
49
- if (tb_exit > TB_EXIT_IDX1) {
50
+ trace_exec_tb_exit(last_tb, *tb_exit);
51
+
52
+ if (*tb_exit > TB_EXIT_IDX1) {
53
/* We didn't start executing this TB (eg because the instruction
54
* counter hit zero); we must restore the guest PC to the address
55
* of the start of the TB.
56
@@ -XXX,XX +XXX,XX @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb)
57
cc->set_pc(cpu, last_tb->pc);
58
}
13
}
59
}
14
}
60
- return ret;
15
- return false;
61
+ return last_tb;
16
+ return finish_folding(ctx, op);
62
}
17
}
63
18
64
#ifndef CONFIG_USER_ONLY
19
/* Propagate constants and copies, fold constant expressions. */
65
@@ -XXX,XX +XXX,XX @@ static void cpu_exec_nocache(CPUState *cpu, int max_cycles,
66
{
67
TranslationBlock *tb;
68
uint32_t cflags = curr_cflags() | CF_NOCACHE;
69
+ int tb_exit;
70
71
if (ignore_icount) {
72
cflags &= ~CF_USE_ICOUNT;
73
@@ -XXX,XX +XXX,XX @@ static void cpu_exec_nocache(CPUState *cpu, int max_cycles,
74
75
/* execute the generated code */
76
trace_exec_tb_nocache(tb, tb->pc);
77
- cpu_tb_exec(cpu, tb);
78
+ cpu_tb_exec(cpu, tb, &tb_exit);
79
80
mmap_lock();
81
tb_phys_invalidate(tb, -1);
82
@@ -XXX,XX +XXX,XX @@ void cpu_exec_step_atomic(CPUState *cpu)
83
uint32_t flags;
84
uint32_t cflags = 1;
85
uint32_t cf_mask = cflags & CF_HASH_MASK;
86
+ int tb_exit;
87
88
if (sigsetjmp(cpu->jmp_env, 0) == 0) {
89
start_exclusive();
90
@@ -XXX,XX +XXX,XX @@ void cpu_exec_step_atomic(CPUState *cpu)
91
cpu_exec_enter(cpu);
92
/* execute the generated code */
93
trace_exec_tb(tb, pc);
94
- cpu_tb_exec(cpu, tb);
95
+ cpu_tb_exec(cpu, tb, &tb_exit);
96
cpu_exec_exit(cpu);
97
} else {
98
/*
99
@@ -XXX,XX +XXX,XX @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
100
static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb,
101
TranslationBlock **last_tb, int *tb_exit)
102
{
103
- uintptr_t ret;
104
int32_t insns_left;
105
106
trace_exec_tb(tb, tb->pc);
107
- ret = cpu_tb_exec(cpu, tb);
108
- tb = (TranslationBlock *)(ret & ~TB_EXIT_MASK);
109
- *tb_exit = ret & TB_EXIT_MASK;
110
+ tb = cpu_tb_exec(cpu, tb, tb_exit);
111
if (*tb_exit != TB_EXIT_REQUESTED) {
112
*last_tb = tb;
113
return;
114
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/tcg/tcg-op.c
117
+++ b/tcg/tcg-op.c
118
@@ -XXX,XX +XXX,XX @@ void tcg_gen_extr32_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg)
119
120
void tcg_gen_exit_tb(const TranslationBlock *tb, unsigned idx)
121
{
122
- uintptr_t val = (uintptr_t)tb + idx;
123
+ /*
124
+ * Let the jit code return the read-only version of the
125
+ * TranslationBlock, so that we minimize the pc-relative
126
+ * distance of the address of the exit_tb code to TB.
127
+ * This will improve utilization of pc-relative address loads.
128
+ *
129
+ * TODO: Move this to translator_loop, so that all const
130
+ * TranslationBlock pointers refer to read-only memory.
131
+ * This requires coordination with targets that do not use
132
+ * the translator_loop.
133
+ */
134
+ uintptr_t val = (uintptr_t)tcg_splitwx_to_rx((void *)tb) + idx;
135
136
if (tb == NULL) {
137
tcg_debug_assert(idx == 0);
138
--
20
--
139
2.25.1
21
2.43.0
140
141
diff view generated by jsdifflib
1
This value is constant across all thread-local copies of TCGContext,
1
All non-default cases now finish folding within each function.
2
so we might as well move it out of thread-local storage.
2
Do the same with the default case and assert it is done after.
3
3
4
Reviewed-by: Joelle van Dyne <j@getutm.app>
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
6
---
7
include/tcg/tcg.h | 2 +-
7
tcg/optimize.c | 6 ++----
8
accel/tcg/tcg-runtime.c | 2 +-
8
1 file changed, 2 insertions(+), 4 deletions(-)
9
tcg/tcg.c | 3 ++-
10
tcg/aarch64/tcg-target.c.inc | 4 ++--
11
tcg/arm/tcg-target.c.inc | 2 +-
12
tcg/i386/tcg-target.c.inc | 4 ++--
13
tcg/mips/tcg-target.c.inc | 2 +-
14
tcg/ppc/tcg-target.c.inc | 2 +-
15
tcg/riscv/tcg-target.c.inc | 4 ++--
16
tcg/s390/tcg-target.c.inc | 4 ++--
17
tcg/sparc/tcg-target.c.inc | 2 +-
18
11 files changed, 16 insertions(+), 15 deletions(-)
19
9
20
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
21
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
22
--- a/include/tcg/tcg.h
12
--- a/tcg/optimize.c
23
+++ b/include/tcg/tcg.h
13
+++ b/tcg/optimize.c
24
@@ -XXX,XX +XXX,XX @@ struct TCGContext {
14
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s)
25
here, because there's too much arithmetic throughout that relies
15
done = true;
26
on addition and subtraction working on bytes. Rely on the GCC
16
break;
27
extension that allows arithmetic on void*. */
17
default:
28
- void *code_gen_epilogue;
18
+ done = finish_folding(&ctx, op);
29
void *code_gen_buffer;
19
break;
30
size_t code_gen_buffer_size;
20
}
31
void *code_gen_ptr;
21
-
32
@@ -XXX,XX +XXX,XX @@ struct TCGContext {
22
- if (!done) {
33
23
- finish_folding(&ctx, op);
34
extern TCGContext tcg_init_ctx;
24
- }
35
extern __thread TCGContext *tcg_ctx;
25
+ tcg_debug_assert(done);
36
+extern void *tcg_code_gen_epilogue;
37
extern TCGv_env cpu_env;
38
39
static inline size_t temp_idx(TCGTemp *ts)
40
diff --git a/accel/tcg/tcg-runtime.c b/accel/tcg/tcg-runtime.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/accel/tcg/tcg-runtime.c
43
+++ b/accel/tcg/tcg-runtime.c
44
@@ -XXX,XX +XXX,XX @@ void *HELPER(lookup_tb_ptr)(CPUArchState *env)
45
46
tb = tb_lookup__cpu_state(cpu, &pc, &cs_base, &flags, curr_cflags());
47
if (tb == NULL) {
48
- return tcg_ctx->code_gen_epilogue;
49
+ return tcg_code_gen_epilogue;
50
}
51
qemu_log_mask_and_addr(CPU_LOG_EXEC, pc,
52
"Chain %d: %p ["
53
diff --git a/tcg/tcg.c b/tcg/tcg.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/tcg/tcg.c
56
+++ b/tcg/tcg.c
57
@@ -XXX,XX +XXX,XX @@ static int tcg_out_ldst_finalize(TCGContext *s);
58
static TCGContext **tcg_ctxs;
59
static unsigned int n_tcg_ctxs;
60
TCGv_env cpu_env = 0;
61
+void *tcg_code_gen_epilogue;
62
63
#ifndef CONFIG_TCG_INTERPRETER
64
tcg_prologue_fn *tcg_qemu_tb_exec;
65
@@ -XXX,XX +XXX,XX @@ void tcg_prologue_init(TCGContext *s)
66
67
/* Assert that goto_ptr is implemented completely. */
68
if (TCG_TARGET_HAS_goto_ptr) {
69
- tcg_debug_assert(s->code_gen_epilogue != NULL);
70
+ tcg_debug_assert(tcg_code_gen_epilogue != NULL);
71
}
26
}
72
}
27
}
73
74
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
75
index XXXXXXX..XXXXXXX 100644
76
--- a/tcg/aarch64/tcg-target.c.inc
77
+++ b/tcg/aarch64/tcg-target.c.inc
78
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
79
case INDEX_op_exit_tb:
80
/* Reuse the zeroing that exists for goto_ptr. */
81
if (a0 == 0) {
82
- tcg_out_goto_long(s, s->code_gen_epilogue);
83
+ tcg_out_goto_long(s, tcg_code_gen_epilogue);
84
} else {
85
tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_X0, a0);
86
tcg_out_goto_long(s, tb_ret_addr);
87
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
88
* Return path for goto_ptr. Set return value to 0, a-la exit_tb,
89
* and fall through to the rest of the epilogue.
90
*/
91
- s->code_gen_epilogue = s->code_ptr;
92
+ tcg_code_gen_epilogue = s->code_ptr;
93
tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_X0, 0);
94
95
/* TB epilogue */
96
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
97
index XXXXXXX..XXXXXXX 100644
98
--- a/tcg/arm/tcg-target.c.inc
99
+++ b/tcg/arm/tcg-target.c.inc
100
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
101
* Return path for goto_ptr. Set return value to 0, a-la exit_tb,
102
* and fall through to the rest of the epilogue.
103
*/
104
- s->code_gen_epilogue = s->code_ptr;
105
+ tcg_code_gen_epilogue = s->code_ptr;
106
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R0, 0);
107
tcg_out_epilogue(s);
108
}
109
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
110
index XXXXXXX..XXXXXXX 100644
111
--- a/tcg/i386/tcg-target.c.inc
112
+++ b/tcg/i386/tcg-target.c.inc
113
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
114
case INDEX_op_exit_tb:
115
/* Reuse the zeroing that exists for goto_ptr. */
116
if (a0 == 0) {
117
- tcg_out_jmp(s, s->code_gen_epilogue);
118
+ tcg_out_jmp(s, tcg_code_gen_epilogue);
119
} else {
120
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_EAX, a0);
121
tcg_out_jmp(s, tb_ret_addr);
122
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
123
* Return path for goto_ptr. Set return value to 0, a-la exit_tb,
124
* and fall through to the rest of the epilogue.
125
*/
126
- s->code_gen_epilogue = s->code_ptr;
127
+ tcg_code_gen_epilogue = s->code_ptr;
128
tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_EAX, 0);
129
130
/* TB epilogue */
131
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
132
index XXXXXXX..XXXXXXX 100644
133
--- a/tcg/mips/tcg-target.c.inc
134
+++ b/tcg/mips/tcg-target.c.inc
135
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
136
* Return path for goto_ptr. Set return value to 0, a-la exit_tb,
137
* and fall through to the rest of the epilogue.
138
*/
139
- s->code_gen_epilogue = s->code_ptr;
140
+ tcg_code_gen_epilogue = s->code_ptr;
141
tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_V0, TCG_REG_ZERO);
142
143
/* TB epilogue */
144
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
145
index XXXXXXX..XXXXXXX 100644
146
--- a/tcg/ppc/tcg-target.c.inc
147
+++ b/tcg/ppc/tcg-target.c.inc
148
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
149
tcg_out32(s, BCCTR | BO_ALWAYS);
150
151
/* Epilogue */
152
- s->code_gen_epilogue = tb_ret_addr = s->code_ptr;
153
+ tcg_code_gen_epilogue = tb_ret_addr = s->code_ptr;
154
155
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_R1, FRAME_SIZE+LR_OFFSET);
156
for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i) {
157
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
158
index XXXXXXX..XXXXXXX 100644
159
--- a/tcg/riscv/tcg-target.c.inc
160
+++ b/tcg/riscv/tcg-target.c.inc
161
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
162
case INDEX_op_exit_tb:
163
/* Reuse the zeroing that exists for goto_ptr. */
164
if (a0 == 0) {
165
- tcg_out_call_int(s, s->code_gen_epilogue, true);
166
+ tcg_out_call_int(s, tcg_code_gen_epilogue, true);
167
} else {
168
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, a0);
169
tcg_out_call_int(s, tb_ret_addr, true);
170
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
171
tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, tcg_target_call_iarg_regs[1], 0);
172
173
/* Return path for goto_ptr. Set return value to 0 */
174
- s->code_gen_epilogue = s->code_ptr;
175
+ tcg_code_gen_epilogue = s->code_ptr;
176
tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_A0, TCG_REG_ZERO);
177
178
/* TB epilogue */
179
diff --git a/tcg/s390/tcg-target.c.inc b/tcg/s390/tcg-target.c.inc
180
index XXXXXXX..XXXXXXX 100644
181
--- a/tcg/s390/tcg-target.c.inc
182
+++ b/tcg/s390/tcg-target.c.inc
183
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
184
/* Reuse the zeroing that exists for goto_ptr. */
185
a0 = args[0];
186
if (a0 == 0) {
187
- tgen_gotoi(s, S390_CC_ALWAYS, s->code_gen_epilogue);
188
+ tgen_gotoi(s, S390_CC_ALWAYS, tcg_code_gen_epilogue);
189
} else {
190
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, a0);
191
tgen_gotoi(s, S390_CC_ALWAYS, tb_ret_addr);
192
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
193
* Return path for goto_ptr. Set return value to 0, a-la exit_tb,
194
* and fall through to the rest of the epilogue.
195
*/
196
- s->code_gen_epilogue = s->code_ptr;
197
+ tcg_code_gen_epilogue = s->code_ptr;
198
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, 0);
199
200
/* TB epilogue */
201
diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc/tcg-target.c.inc
202
index XXXXXXX..XXXXXXX 100644
203
--- a/tcg/sparc/tcg-target.c.inc
204
+++ b/tcg/sparc/tcg-target.c.inc
205
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
206
tcg_out_nop(s);
207
208
/* Epilogue for goto_ptr. */
209
- s->code_gen_epilogue = s->code_ptr;
210
+ tcg_code_gen_epilogue = s->code_ptr;
211
tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, RETURN);
212
/* delay slot */
213
tcg_out_movi_imm13(s, TCG_REG_O0, 0);
214
--
28
--
215
2.25.1
29
2.43.0
216
217
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
Re-use the 256MiB region handling from alloc_code_gen_buffer_anon,
1
All instances of s_mask have been converted to the new
2
and replace that with the shared file mapping.
2
representation. We can now re-enable usage.
3
3
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
---
6
accel/tcg/translate-all.c | 46 ++++++++++++++++++++++++++++++++-------
7
tcg/optimize.c | 4 ++--
7
1 file changed, 38 insertions(+), 8 deletions(-)
8
1 file changed, 2 insertions(+), 2 deletions(-)
8
9
9
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
11
--- a/accel/tcg/translate-all.c
12
--- a/tcg/optimize.c
12
+++ b/accel/tcg/translate-all.c
13
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool alloc_code_gen_buffer_anon(size_t size, int prot,
14
@@ -XXX,XX +XXX,XX @@ static bool fold_exts(OptContext *ctx, TCGOp *op)
14
15
g_assert_not_reached();
15
static bool alloc_code_gen_buffer_splitwx_memfd(size_t size, Error **errp)
16
{
17
- void *buf_rw, *buf_rx;
18
+ void *buf_rw = NULL, *buf_rx = MAP_FAILED;
19
int fd = -1;
20
21
+#ifdef __mips__
22
+ /* Find space for the RX mapping, vs the 256MiB regions. */
23
+ if (!alloc_code_gen_buffer_anon(size, PROT_NONE,
24
+ MAP_PRIVATE | MAP_ANONYMOUS |
25
+ MAP_NORESERVE, errp)) {
26
+ return false;
27
+ }
28
+ /* The size of the mapping may have been adjusted. */
29
+ size = tcg_ctx->code_gen_buffer_size;
30
+ buf_rx = tcg_ctx->code_gen_buffer;
31
+#endif
32
+
33
buf_rw = qemu_memfd_alloc("tcg-jit", size, 0, &fd, errp);
34
if (buf_rw == NULL) {
35
- return false;
36
+ goto fail;
37
}
16
}
38
17
39
+#ifdef __mips__
18
- if (0 && !type_change && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
40
+ void *tmp = mmap(buf_rx, size, PROT_READ | PROT_EXEC,
19
+ if (!type_change && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
41
+ MAP_SHARED | MAP_FIXED, fd, 0);
20
return true;
42
+ if (tmp != buf_rx) {
43
+ goto fail_rx;
44
+ }
45
+#else
46
buf_rx = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0);
47
if (buf_rx == MAP_FAILED) {
48
- error_setg_errno(errp, errno,
49
- "failed to map shared memory for execute");
50
- munmap(buf_rw, size);
51
- close(fd);
52
- return false;
53
+ goto fail_rx;
54
}
21
}
55
- close(fd);
22
56
+#endif
23
@@ -XXX,XX +XXX,XX @@ static bool fold_sextract(OptContext *ctx, TCGOp *op)
57
24
s_mask = s_mask_old >> pos;
58
+ close(fd);
25
s_mask |= -1ull << (len - 1);
59
tcg_ctx->code_gen_buffer = buf_rw;
26
60
tcg_ctx->code_gen_buffer_size = size;
27
- if (0 && pos == 0 && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
61
tcg_splitwx_diff = buf_rx - buf_rw;
28
+ if (pos == 0 && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
62
@@ -XXX,XX +XXX,XX @@ static bool alloc_code_gen_buffer_splitwx_memfd(size_t size, Error **errp)
29
return true;
63
qemu_madvise(buf_rw, size, QEMU_MADV_HUGEPAGE);
30
}
64
qemu_madvise(buf_rx, size, QEMU_MADV_HUGEPAGE);
65
return true;
66
+
67
+ fail_rx:
68
+ error_setg_errno(errp, errno, "failed to map shared memory for execute");
69
+ fail:
70
+ if (buf_rx != MAP_FAILED) {
71
+ munmap(buf_rx, size);
72
+ }
73
+ if (buf_rw) {
74
+ munmap(buf_rw, size);
75
+ }
76
+ if (fd >= 0) {
77
+ close(fd);
78
+ }
79
+ return false;
80
}
81
#endif /* CONFIG_POSIX */
82
31
83
--
32
--
84
2.25.1
33
2.43.0
85
86
diff view generated by jsdifflib
1
We are shortly going to have a split rw/rx jit buffer. Depending
1
The big comment just above says functions should be sorted.
2
on the host, we need to flush the dcache at the rw data pointer and
2
Add forward declarations as needed.
3
flush the icache at the rx code pointer.
4
3
5
For now, the two passed pointers are identical, so there is no
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
6
effective change in behaviour.
7
8
Reviewed-by: Joelle van Dyne <j@getutm.app>
9
Reviewed-by: Alex Bennée <alex.bennee@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/qemu/cacheflush.h | 15 ++++++++++++--
7
tcg/optimize.c | 114 +++++++++++++++++++++++++------------------------
13
softmmu/physmem.c | 2 +-
8
1 file changed, 59 insertions(+), 55 deletions(-)
14
tcg/tcg.c | 6 ++++--
15
util/cacheflush.c | 38 +++++++++++++++++++++---------------
16
util/cacheinfo.c | 8 +++++---
17
tcg/aarch64/tcg-target.c.inc | 2 +-
18
tcg/mips/tcg-target.c.inc | 2 +-
19
tcg/ppc/tcg-target.c.inc | 4 ++--
20
tcg/sparc/tcg-target.c.inc | 4 ++--
21
9 files changed, 51 insertions(+), 30 deletions(-)
22
9
23
diff --git a/include/qemu/cacheflush.h b/include/qemu/cacheflush.h
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
24
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
25
--- a/include/qemu/cacheflush.h
12
--- a/tcg/optimize.c
26
+++ b/include/qemu/cacheflush.h
13
+++ b/tcg/optimize.c
27
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static bool fold_xx_to_x(OptContext *ctx, TCGOp *op)
28
#ifndef QEMU_CACHEFLUSH_H
15
* 3) those that produce information about the result value.
29
#define QEMU_CACHEFLUSH_H
16
*/
30
17
31
+/**
18
+static bool fold_or(OptContext *ctx, TCGOp *op);
32
+ * flush_idcache_range:
19
+static bool fold_orc(OptContext *ctx, TCGOp *op);
33
+ * @rx: instruction address
20
+static bool fold_xor(OptContext *ctx, TCGOp *op);
34
+ * @rw: data address
35
+ * @len: length to flush
36
+ *
37
+ * Flush @len bytes of the data cache at @rw and the icache at @rx
38
+ * to bring them in sync. The two addresses may be different virtual
39
+ * mappings of the same physical page(s).
40
+ */
41
+
21
+
42
#if defined(__i386__) || defined(__x86_64__) || defined(__s390__)
22
static bool fold_add(OptContext *ctx, TCGOp *op)
43
44
-static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
45
+static inline void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len)
46
{
23
{
47
/* icache is coherent and does not require flushing. */
24
if (fold_const2_commutative(ctx, op) ||
25
@@ -XXX,XX +XXX,XX @@ static bool fold_andc(OptContext *ctx, TCGOp *op)
26
return fold_masks_zs(ctx, op, z_mask, s_mask);
48
}
27
}
49
28
50
#else
29
+static bool fold_bitsel_vec(OptContext *ctx, TCGOp *op)
51
30
+{
52
-void flush_icache_range(uintptr_t start, uintptr_t stop);
31
+ /* If true and false values are the same, eliminate the cmp. */
53
+void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len);
32
+ if (args_are_copies(op->args[2], op->args[3])) {
54
33
+ return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[2]);
55
#endif
34
+ }
56
35
+
57
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
36
+ if (arg_is_const(op->args[2]) && arg_is_const(op->args[3])) {
58
index XXXXXXX..XXXXXXX 100644
37
+ uint64_t tv = arg_info(op->args[2])->val;
59
--- a/softmmu/physmem.c
38
+ uint64_t fv = arg_info(op->args[3])->val;
60
+++ b/softmmu/physmem.c
39
+
61
@@ -XXX,XX +XXX,XX @@ static inline MemTxResult address_space_write_rom_internal(AddressSpace *as,
40
+ if (tv == -1 && fv == 0) {
62
invalidate_and_set_dirty(mr, addr1, l);
41
+ return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[1]);
63
break;
42
+ }
64
case FLUSH_CACHE:
43
+ if (tv == 0 && fv == -1) {
65
- flush_icache_range((uintptr_t)ram_ptr, (uintptr_t)ram_ptr + l);
44
+ if (TCG_TARGET_HAS_not_vec) {
66
+ flush_idcache_range((uintptr_t)ram_ptr, (uintptr_t)ram_ptr, l);
45
+ op->opc = INDEX_op_not_vec;
67
break;
46
+ return fold_not(ctx, op);
68
}
47
+ } else {
69
}
48
+ op->opc = INDEX_op_xor_vec;
70
diff --git a/tcg/tcg.c b/tcg/tcg.c
49
+ op->args[2] = arg_new_constant(ctx, -1);
71
index XXXXXXX..XXXXXXX 100644
50
+ return fold_xor(ctx, op);
72
--- a/tcg/tcg.c
51
+ }
73
+++ b/tcg/tcg.c
52
+ }
74
@@ -XXX,XX +XXX,XX @@ void tcg_prologue_init(TCGContext *s)
53
+ }
75
54
+ if (arg_is_const(op->args[2])) {
76
buf1 = s->code_ptr;
55
+ uint64_t tv = arg_info(op->args[2])->val;
77
#ifndef CONFIG_TCG_INTERPRETER
56
+ if (tv == -1) {
78
- flush_icache_range((uintptr_t)buf0, (uintptr_t)buf1);
57
+ op->opc = INDEX_op_or_vec;
79
+ flush_idcache_range((uintptr_t)buf0, (uintptr_t)buf0,
58
+ op->args[2] = op->args[3];
80
+ tcg_ptr_byte_diff(buf1, buf0));
59
+ return fold_or(ctx, op);
81
#endif
60
+ }
82
61
+ if (tv == 0 && TCG_TARGET_HAS_andc_vec) {
83
/* Deduct the prologue from the buffer. */
62
+ op->opc = INDEX_op_andc_vec;
84
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
63
+ op->args[2] = op->args[1];
85
64
+ op->args[1] = op->args[3];
86
#ifndef CONFIG_TCG_INTERPRETER
65
+ return fold_andc(ctx, op);
87
/* flush instruction cache */
66
+ }
88
- flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr);
67
+ }
89
+ flush_idcache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_buf,
68
+ if (arg_is_const(op->args[3])) {
90
+ tcg_ptr_byte_diff(s->code_ptr, s->code_buf));
69
+ uint64_t fv = arg_info(op->args[3])->val;
91
#endif
70
+ if (fv == 0) {
92
71
+ op->opc = INDEX_op_and_vec;
93
return tcg_current_code_size(s);
72
+ return fold_and(ctx, op);
94
diff --git a/util/cacheflush.c b/util/cacheflush.c
73
+ }
95
index XXXXXXX..XXXXXXX 100644
74
+ if (fv == -1 && TCG_TARGET_HAS_orc_vec) {
96
--- a/util/cacheflush.c
75
+ op->opc = INDEX_op_orc_vec;
97
+++ b/util/cacheflush.c
76
+ op->args[2] = op->args[1];
98
@@ -XXX,XX +XXX,XX @@
77
+ op->args[1] = op->args[3];
99
#include <sys/cachectl.h>
78
+ return fold_orc(ctx, op);
100
#endif
79
+ }
101
80
+ }
102
-void flush_icache_range(uintptr_t start, uintptr_t stop)
81
+ return finish_folding(ctx, op);
103
+void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len)
82
+}
83
+
84
static bool fold_brcond(OptContext *ctx, TCGOp *op)
104
{
85
{
105
- cacheflush((void *)start, stop - start, ICACHE);
86
int i = do_constant_folding_cond1(ctx, op, NO_DEST, &op->args[0],
106
+ if (rx != rw) {
87
@@ -XXX,XX +XXX,XX @@ static bool fold_xor(OptContext *ctx, TCGOp *op)
107
+ cacheflush((void *)rw, len, DCACHE);
88
return fold_masks_zs(ctx, op, z_mask, s_mask);
108
+ }
109
+ cacheflush((void *)rx, len, ICACHE);
110
}
89
}
111
90
112
#elif defined(__powerpc__)
91
-static bool fold_bitsel_vec(OptContext *ctx, TCGOp *op)
113
92
-{
114
-void flush_icache_range(uintptr_t start, uintptr_t stop)
93
- /* If true and false values are the same, eliminate the cmp. */
115
+void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len)
94
- if (args_are_copies(op->args[2], op->args[3])) {
95
- return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[2]);
96
- }
97
-
98
- if (arg_is_const(op->args[2]) && arg_is_const(op->args[3])) {
99
- uint64_t tv = arg_info(op->args[2])->val;
100
- uint64_t fv = arg_info(op->args[3])->val;
101
-
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)
116
{
148
{
117
- uintptr_t p, start1, stop1;
118
+ uintptr_t p, b, e;
119
size_t dsize = qemu_dcache_linesize;
120
size_t isize = qemu_icache_linesize;
121
122
- start1 = start & ~(dsize - 1);
123
- stop1 = (stop + dsize - 1) & ~(dsize - 1);
124
- for (p = start1; p < stop1; p += dsize) {
125
+ b = rw & ~(dsize - 1);
126
+ e = (rw + len + dsize - 1) & ~(dsize - 1);
127
+ for (p = b; p < e; p += dsize) {
128
asm volatile ("dcbst 0,%0" : : "r"(p) : "memory");
129
}
130
asm volatile ("sync" : : : "memory");
131
132
- start &= start & ~(isize - 1);
133
- stop1 = (stop + isize - 1) & ~(isize - 1);
134
- for (p = start1; p < stop1; p += isize) {
135
+ b = rx & ~(isize - 1);
136
+ e = (rx + len + isize - 1) & ~(isize - 1);
137
+ for (p = b; p < e; p += isize) {
138
asm volatile ("icbi 0,%0" : : "r"(p) : "memory");
139
}
140
asm volatile ("sync" : : : "memory");
141
@@ -XXX,XX +XXX,XX @@ void flush_icache_range(uintptr_t start, uintptr_t stop)
142
143
#elif defined(__sparc__)
144
145
-void flush_icache_range(uintptr_t start, uintptr_t stop)
146
+void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len)
147
{
148
- uintptr_t p;
149
-
150
- for (p = start & -8; p < ((stop + 7) & -8); p += 8) {
151
+ /* No additional data flush to the RW virtual address required. */
152
+ uintptr_t p, end = (rx + len + 7) & -8;
153
+ for (p = rx & -8; p < end; p += 8) {
154
__asm__ __volatile__("flush\t%0" : : "r" (p));
155
}
156
}
157
158
#else
159
160
-void flush_icache_range(uintptr_t start, uintptr_t stop)
161
+void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len)
162
{
163
- __builtin___clear_cache((char *)start, (char *)stop);
164
+ if (rw != rx) {
165
+ __builtin___clear_cache((char *)rw, (char *)rw + len);
166
+ }
167
+ __builtin___clear_cache((char *)rx, (char *)rx + len);
168
}
169
170
#endif
171
diff --git a/util/cacheinfo.c b/util/cacheinfo.c
172
index XXXXXXX..XXXXXXX 100644
173
--- a/util/cacheinfo.c
174
+++ b/util/cacheinfo.c
175
@@ -XXX,XX +XXX,XX @@ static void fallback_cache_info(int *isize, int *dsize)
176
*isize = *dsize;
177
} else {
178
#if defined(_ARCH_PPC)
179
- /* For PPC, we're going to use the icache size computed for
180
- flush_icache_range. Which means that we must use the
181
- architecture minimum. */
182
+ /*
183
+ * For PPC, we're going to use the cache sizes computed for
184
+ * flush_idcache_range. Which means that we must use the
185
+ * architecture minimum.
186
+ */
187
*isize = *dsize = 16;
188
#else
189
/* Otherwise, 64 bytes is not uncommon. */
190
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
191
index XXXXXXX..XXXXXXX 100644
192
--- a/tcg/aarch64/tcg-target.c.inc
193
+++ b/tcg/aarch64/tcg-target.c.inc
194
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
195
}
196
pair = (uint64_t)i2 << 32 | i1;
197
qatomic_set((uint64_t *)jmp_addr, pair);
198
- flush_icache_range(jmp_addr, jmp_addr + 8);
199
+ flush_idcache_range(jmp_addr, jmp_addr, 8);
200
}
201
202
static inline void tcg_out_goto_label(TCGContext *s, TCGLabel *l)
203
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
204
index XXXXXXX..XXXXXXX 100644
205
--- a/tcg/mips/tcg-target.c.inc
206
+++ b/tcg/mips/tcg-target.c.inc
207
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
208
uintptr_t addr)
209
{
210
qatomic_set((uint32_t *)jmp_addr, deposit32(OPC_J, 0, 26, addr >> 2));
211
- flush_icache_range(jmp_addr, jmp_addr + 4);
212
+ flush_idcache_range(jmp_addr, jmp_addr, 4);
213
}
214
215
typedef struct {
216
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
217
index XXXXXXX..XXXXXXX 100644
218
--- a/tcg/ppc/tcg-target.c.inc
219
+++ b/tcg/ppc/tcg-target.c.inc
220
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
221
/* As per the enclosing if, this is ppc64. Avoid the _Static_assert
222
within qatomic_set that would fail to build a ppc32 host. */
223
qatomic_set__nocheck((uint64_t *)jmp_addr, pair);
224
- flush_icache_range(jmp_addr, jmp_addr + 8);
225
+ flush_idcache_range(jmp_addr, jmp_addr, 8);
226
} else {
227
intptr_t diff = addr - jmp_addr;
228
tcg_debug_assert(in_range_b(diff));
229
qatomic_set((uint32_t *)jmp_addr, B | (diff & 0x3fffffc));
230
- flush_icache_range(jmp_addr, jmp_addr + 4);
231
+ flush_idcache_range(jmp_addr, jmp_addr, 4);
232
}
233
}
234
235
diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc/tcg-target.c.inc
236
index XXXXXXX..XXXXXXX 100644
237
--- a/tcg/sparc/tcg-target.c.inc
238
+++ b/tcg/sparc/tcg-target.c.inc
239
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
240
if (!USE_REG_TB) {
241
qatomic_set((uint32_t *)jmp_addr,
242
         deposit32(CALL, 0, 30, br_disp >> 2));
243
- flush_icache_range(jmp_addr, jmp_addr + 4);
244
+ flush_idcache_range(jmp_addr, jmp_addr, 4);
245
return;
246
}
247
248
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
249
}
250
251
qatomic_set((uint64_t *)jmp_addr, deposit64(i2, 32, 32, i1));
252
- flush_icache_range(jmp_addr, jmp_addr + 8);
253
+ flush_idcache_range(jmp_addr, jmp_addr, 8);
254
}
255
--
149
--
256
2.25.1
150
2.43.0
257
258
diff view generated by jsdifflib
1
For darwin, the CTR_EL0 register is not accessible, but there
1
The big comment just above says functions should be sorted.
2
are system routines that we can use.
3
2
4
For other hosts, copy the single pointer implementation from
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
5
libgcc and modify it to support the double pointer interface
6
we require. This halves the number of cache operations required
7
when split-rwx is enabled.
8
9
Reviewed-by: Joelle van Dyne <j@getutm.app>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
5
---
12
util/cacheflush.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++
6
tcg/optimize.c | 60 +++++++++++++++++++++++++-------------------------
13
1 file changed, 69 insertions(+)
7
1 file changed, 30 insertions(+), 30 deletions(-)
14
8
15
diff --git a/util/cacheflush.c b/util/cacheflush.c
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
16
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
17
--- a/util/cacheflush.c
11
--- a/tcg/optimize.c
18
+++ b/util/cacheflush.c
12
+++ b/tcg/optimize.c
19
@@ -XXX,XX +XXX,XX @@
13
@@ -XXX,XX +XXX,XX @@ static bool fold_call(OptContext *ctx, TCGOp *op)
20
14
return true;
21
#include "qemu/osdep.h"
15
}
22
#include "qemu/cacheflush.h"
16
23
+#include "qemu/bitops.h"
17
+static bool fold_cmp_vec(OptContext *ctx, TCGOp *op)
24
25
26
#if defined(__i386__) || defined(__x86_64__) || defined(__s390__)
27
28
/* Caches are coherent and do not require flushing; symbol inline. */
29
30
+#elif defined(__aarch64__)
31
+
32
+#ifdef CONFIG_DARWIN
33
+/* Apple does not expose CTR_EL0, so we must use system interfaces. */
34
+extern void sys_icache_invalidate(void *start, size_t len);
35
+extern void sys_dcache_flush(void *start, size_t len);
36
+void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len)
37
+{
18
+{
38
+ sys_dcache_flush((void *)rw, len);
19
+ /* Canonicalize the comparison to put immediate second. */
39
+ sys_icache_invalidate((void *)rx, len);
20
+ if (swap_commutative(NO_DEST, &op->args[1], &op->args[2])) {
40
+}
21
+ op->args[3] = tcg_swap_cond(op->args[3]);
41
+#else
22
+ }
42
+
23
+ return finish_folding(ctx, op);
43
+/*
44
+ * TODO: unify this with cacheinfo.c.
45
+ * We want to save the whole contents of CTR_EL0, so that we
46
+ * have more than the linesize, but also IDC and DIC.
47
+ */
48
+static unsigned int save_ctr_el0;
49
+static void __attribute__((constructor)) init_ctr_el0(void)
50
+{
51
+ asm volatile("mrs\t%0, ctr_el0" : "=r"(save_ctr_el0));
52
+}
24
+}
53
+
25
+
54
+/*
26
+static bool fold_cmpsel_vec(OptContext *ctx, TCGOp *op)
55
+ * This is a copy of gcc's __aarch64_sync_cache_range, modified
56
+ * to fit this three-operand interface.
57
+ */
58
+void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len)
59
+{
27
+{
60
+ const unsigned CTR_IDC = 1u << 28;
28
+ /* If true and false values are the same, eliminate the cmp. */
61
+ const unsigned CTR_DIC = 1u << 29;
29
+ if (args_are_copies(op->args[3], op->args[4])) {
62
+ const unsigned int ctr_el0 = save_ctr_el0;
30
+ return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[3]);
63
+ const uintptr_t icache_lsize = 4 << extract32(ctr_el0, 0, 4);
64
+ const uintptr_t dcache_lsize = 4 << extract32(ctr_el0, 16, 4);
65
+ uintptr_t p;
66
+
67
+ /*
68
+ * If CTR_EL0.IDC is enabled, Data cache clean to the Point of Unification
69
+ * is not required for instruction to data coherence.
70
+ */
71
+ if (!(ctr_el0 & CTR_IDC)) {
72
+ /*
73
+ * Loop over the address range, clearing one cache line at once.
74
+ * Data cache must be flushed to unification first to make sure
75
+ * the instruction cache fetches the updated data.
76
+ */
77
+ for (p = rw & -dcache_lsize; p < rw + len; p += dcache_lsize) {
78
+ asm volatile("dc\tcvau, %0" : : "r" (p) : "memory");
79
+ }
80
+ asm volatile("dsb\tish" : : : "memory");
81
+ }
31
+ }
82
+
32
+
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
+ }
83
+ /*
37
+ /*
84
+ * If CTR_EL0.DIC is enabled, Instruction cache cleaning to the Point
38
+ * Canonicalize the "false" input reg to match the destination,
85
+ * of Unification is not required for instruction to data coherence.
39
+ * so that the tcg backend can implement "move if true".
86
+ */
40
+ */
87
+ if (!(ctr_el0 & CTR_DIC)) {
41
+ if (swap_commutative(op->args[0], &op->args[4], &op->args[3])) {
88
+ for (p = rx & -icache_lsize; p < rx + len; p += icache_lsize) {
42
+ op->args[5] = tcg_invert_cond(op->args[5]);
89
+ asm volatile("ic\tivau, %0" : : "r"(p) : "memory");
90
+ }
91
+ asm volatile ("dsb\tish" : : : "memory");
92
+ }
43
+ }
44
+ return finish_folding(ctx, op);
45
+}
93
+
46
+
94
+ asm volatile("isb" : : : "memory");
47
static bool fold_count_zeros(OptContext *ctx, TCGOp *op)
95
+}
48
{
96
+#endif /* CONFIG_DARWIN */
49
uint64_t z_mask, s_mask;
97
+
50
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond2(OptContext *ctx, TCGOp *op)
98
#elif defined(__mips__)
51
return tcg_opt_gen_movi(ctx, op, op->args[0], i);
99
52
}
100
#ifdef __OpenBSD__
53
54
-static bool fold_cmp_vec(OptContext *ctx, TCGOp *op)
55
-{
56
- /* Canonicalize the comparison to put immediate second. */
57
- if (swap_commutative(NO_DEST, &op->args[1], &op->args[2])) {
58
- op->args[3] = tcg_swap_cond(op->args[3]);
59
- }
60
- return finish_folding(ctx, op);
61
-}
62
-
63
-static bool fold_cmpsel_vec(OptContext *ctx, TCGOp *op)
64
-{
65
- /* If true and false values are the same, eliminate the cmp. */
66
- if (args_are_copies(op->args[3], op->args[4])) {
67
- return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[3]);
68
- }
69
-
70
- /* Canonicalize the comparison to put immediate second. */
71
- if (swap_commutative(NO_DEST, &op->args[1], &op->args[2])) {
72
- op->args[5] = tcg_swap_cond(op->args[5]);
73
- }
74
- /*
75
- * Canonicalize the "false" input reg to match the destination,
76
- * so that the tcg backend can implement "move if true".
77
- */
78
- if (swap_commutative(op->args[0], &op->args[4], &op->args[3])) {
79
- op->args[5] = tcg_invert_cond(op->args[5]);
80
- }
81
- return finish_folding(ctx, op);
82
-}
83
-
84
static bool fold_sextract(OptContext *ctx, TCGOp *op)
85
{
86
uint64_t z_mask, s_mask, s_mask_old;
101
--
87
--
102
2.25.1
88
2.43.0
103
104
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.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
qemu_try_memalign() expects a power of 2 alignment:
3
4
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
- posix_memalign(3):
6
7
The address of the allocated memory will be a multiple of alignment,
8
which must be a power of two and a multiple of sizeof(void *).
9
10
- _aligned_malloc()
11
12
The alignment value, which must be an integer power of 2.
13
14
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Message-Id: <20201021173803.2619054-3-philmd@redhat.com>
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
---
6
---
18
util/oslib-posix.c | 2 ++
7
include/fpu/softfloat.h | 6 ++++
19
util/oslib-win32.c | 1 +
8
fpu/softfloat.c | 58 ++++++++++++++++++++++-----------------
20
2 files changed, 3 insertions(+)
9
fpu/softfloat-parts.c.inc | 7 +++--
21
10
3 files changed, 44 insertions(+), 27 deletions(-)
22
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
11
12
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
23
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
24
--- a/util/oslib-posix.c
14
--- a/include/fpu/softfloat.h
25
+++ b/util/oslib-posix.c
15
+++ b/include/fpu/softfloat.h
26
@@ -XXX,XX +XXX,XX @@ void *qemu_try_memalign(size_t alignment, size_t size)
16
@@ -XXX,XX +XXX,XX @@ float16 float16_add(float16, float16, float_status *status);
27
17
float16 float16_sub(float16, float16, float_status *status);
28
if (alignment < sizeof(void*)) {
18
float16 float16_mul(float16, float16, float_status *status);
29
alignment = sizeof(void*);
19
float16 float16_muladd(float16, float16, float16, int, float_status *status);
30
+ } else {
20
+float16 float16_muladd_scalbn(float16, float16, float16,
31
+ g_assert(is_power_of_2(alignment));
21
+ int, int, float_status *status);
22
float16 float16_div(float16, float16, float_status *status);
23
float16 float16_scalbn(float16, int, float_status *status);
24
float16 float16_min(float16, float16, float_status *status);
25
@@ -XXX,XX +XXX,XX @@ float32 float32_mul(float32, float32, float_status *status);
26
float32 float32_div(float32, float32, float_status *status);
27
float32 float32_rem(float32, float32, float_status *status);
28
float32 float32_muladd(float32, float32, float32, int, float_status *status);
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
44
index XXXXXXX..XXXXXXX 100644
45
--- a/fpu/softfloat.c
46
+++ b/fpu/softfloat.c
47
@@ -XXX,XX +XXX,XX @@ static FloatParts128 *parts128_mul(FloatParts128 *a, FloatParts128 *b,
48
#define parts_mul(A, B, S) \
49
PARTS_GENERIC_64_128(mul, A)(A, B, S)
50
51
-static FloatParts64 *parts64_muladd(FloatParts64 *a, FloatParts64 *b,
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)
97
+{
98
+ return float16_muladd_scalbn(a, b, c, 0, flags, status);
99
+}
100
+
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);
32
}
187
}
33
188
34
#if defined(CONFIG_POSIX_MEMALIGN)
189
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
35
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
36
index XXXXXXX..XXXXXXX 100644
190
index XXXXXXX..XXXXXXX 100644
37
--- a/util/oslib-win32.c
191
--- a/fpu/softfloat-parts.c.inc
38
+++ b/util/oslib-win32.c
192
+++ b/fpu/softfloat-parts.c.inc
39
@@ -XXX,XX +XXX,XX @@ void *qemu_try_memalign(size_t alignment, size_t size)
193
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(mul)(FloatPartsN *a, FloatPartsN *b,
40
void *ptr;
194
* Requires A and C extracted into a double-sized structure to provide the
41
195
* extra space for the widening multiply.
42
g_assert(size != 0);
196
*/
43
+ g_assert(is_power_of_2(alignment));
197
-static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b,
44
ptr = _aligned_malloc(alignment, size);
198
- FloatPartsN *c, int flags, float_status *s)
45
trace_qemu_memalign(alignment, size, ptr);
199
+static FloatPartsN *partsN(muladd_scalbn)(FloatPartsN *a, FloatPartsN *b,
46
return ptr;
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;
47
--
217
--
48
2.25.1
218
2.43.0
49
219
50
220
diff view generated by jsdifflib
1
We must change all targets at once, since all must match
1
Use the scalbn interface instead of float_muladd_halve_result.
2
the declaration in tcg.c.
3
2
4
Reviewed-by: Joelle van Dyne <j@getutm.app>
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
5
---
8
tcg/tcg.c | 2 +-
6
target/arm/tcg/helper-a64.c | 6 +++---
9
tcg/aarch64/tcg-target.c.inc | 2 +-
7
1 file changed, 3 insertions(+), 3 deletions(-)
10
tcg/arm/tcg-target.c.inc | 2 +-
11
tcg/i386/tcg-target.c.inc | 4 ++--
12
tcg/mips/tcg-target.c.inc | 6 +++---
13
tcg/ppc/tcg-target.c.inc | 8 ++++----
14
tcg/riscv/tcg-target.c.inc | 6 +++---
15
tcg/s390/tcg-target.c.inc | 2 +-
16
tcg/sparc/tcg-target.c.inc | 4 ++--
17
tcg/tci/tcg-target.c.inc | 2 +-
18
10 files changed, 19 insertions(+), 19 deletions(-)
19
8
20
diff --git a/tcg/tcg.c b/tcg/tcg.c
9
diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c
21
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
22
--- a/tcg/tcg.c
11
--- a/target/arm/tcg/helper-a64.c
23
+++ b/tcg/tcg.c
12
+++ b/target/arm/tcg/helper-a64.c
24
@@ -XXX,XX +XXX,XX @@ static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
13
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(rsqrtsf_f16)(uint32_t a, uint32_t b, float_status *fpst)
25
intptr_t arg2);
14
(float16_is_infinity(b) && float16_is_zero(a))) {
26
static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
15
return float16_one_point_five;
27
TCGReg base, intptr_t ofs);
16
}
28
-static void tcg_out_call(TCGContext *s, tcg_insn_unit *target);
17
- return float16_muladd(a, b, float16_three, float_muladd_halve_result, fpst);
29
+static void tcg_out_call(TCGContext *s, const tcg_insn_unit *target);
18
+ return float16_muladd_scalbn(a, b, float16_three, -1, 0, fpst);
30
static int tcg_target_const_match(tcg_target_long val, TCGType type,
31
const TCGArgConstraint *arg_ct);
32
#ifdef TCG_TARGET_NEED_LDST_LABELS
33
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
34
index XXXXXXX..XXXXXXX 100644
35
--- a/tcg/aarch64/tcg-target.c.inc
36
+++ b/tcg/aarch64/tcg-target.c.inc
37
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_callr(TCGContext *s, TCGReg reg)
38
tcg_out_insn(s, 3207, BLR, reg);
39
}
19
}
40
20
41
-static inline void tcg_out_call(TCGContext *s, tcg_insn_unit *target)
21
float32 HELPER(rsqrtsf_f32)(float32 a, float32 b, float_status *fpst)
42
+static inline void tcg_out_call(TCGContext *s, const tcg_insn_unit *target)
22
@@ -XXX,XX +XXX,XX @@ float32 HELPER(rsqrtsf_f32)(float32 a, float32 b, float_status *fpst)
43
{
23
(float32_is_infinity(b) && float32_is_zero(a))) {
44
ptrdiff_t offset = target - s->code_ptr;
24
return float32_one_point_five;
45
if (offset == sextract64(offset, 0, 26)) {
46
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
47
index XXXXXXX..XXXXXXX 100644
48
--- a/tcg/arm/tcg-target.c.inc
49
+++ b/tcg/arm/tcg-target.c.inc
50
@@ -XXX,XX +XXX,XX @@ static void tcg_out_goto(TCGContext *s, int cond, const tcg_insn_unit *addr)
51
52
/* The call case is mostly used for helpers - so it's not unreasonable
53
* for them to be beyond branch range */
54
-static void tcg_out_call(TCGContext *s, tcg_insn_unit *addr)
55
+static void tcg_out_call(TCGContext *s, const tcg_insn_unit *addr)
56
{
57
intptr_t addri = (intptr_t)addr;
58
ptrdiff_t disp = tcg_pcrel_diff(s, addr);
59
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
60
index XXXXXXX..XXXXXXX 100644
61
--- a/tcg/i386/tcg-target.c.inc
62
+++ b/tcg/i386/tcg-target.c.inc
63
@@ -XXX,XX +XXX,XX @@ static void tcg_out_clz(TCGContext *s, int rexw, TCGReg dest, TCGReg arg1,
64
}
25
}
26
- return float32_muladd(a, b, float32_three, float_muladd_halve_result, fpst);
27
+ return float32_muladd_scalbn(a, b, float32_three, -1, 0, fpst);
65
}
28
}
66
29
67
-static void tcg_out_branch(TCGContext *s, int call, tcg_insn_unit *dest)
30
float64 HELPER(rsqrtsf_f64)(float64 a, float64 b, float_status *fpst)
68
+static void tcg_out_branch(TCGContext *s, int call, const tcg_insn_unit *dest)
31
@@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrtsf_f64)(float64 a, float64 b, float_status *fpst)
69
{
32
(float64_is_infinity(b) && float64_is_zero(a))) {
70
intptr_t disp = tcg_pcrel_diff(s, dest) - 5;
33
return float64_one_point_five;
71
72
@@ -XXX,XX +XXX,XX @@ static void tcg_out_branch(TCGContext *s, int call, tcg_insn_unit *dest)
73
}
34
}
35
- return float64_muladd(a, b, float64_three, float_muladd_halve_result, fpst);
36
+ return float64_muladd_scalbn(a, b, float64_three, -1, 0, fpst);
74
}
37
}
75
38
76
-static inline void tcg_out_call(TCGContext *s, tcg_insn_unit *dest)
39
/* Floating-point reciprocal exponent - see FPRecpX in ARM ARM */
77
+static inline void tcg_out_call(TCGContext *s, const tcg_insn_unit *dest)
78
{
79
tcg_out_branch(s, 1, dest);
80
}
81
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
82
index XXXXXXX..XXXXXXX 100644
83
--- a/tcg/mips/tcg-target.c.inc
84
+++ b/tcg/mips/tcg-target.c.inc
85
@@ -XXX,XX +XXX,XX @@ static void tcg_out_opc_sa64(TCGContext *s, MIPSInsn opc1, MIPSInsn opc2,
86
* Type jump.
87
* Returns true if the branch was in range and the insn was emitted.
88
*/
89
-static bool tcg_out_opc_jmp(TCGContext *s, MIPSInsn opc, void *target)
90
+static bool tcg_out_opc_jmp(TCGContext *s, MIPSInsn opc, const void *target)
91
{
92
uintptr_t dest = (uintptr_t)target;
93
uintptr_t from = (uintptr_t)s->code_ptr + 4;
94
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
95
}
96
}
97
98
-static void tcg_out_call_int(TCGContext *s, tcg_insn_unit *arg, bool tail)
99
+static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail)
100
{
101
/* Note that the ABI requires the called function's address to be
102
loaded into T9, even if a direct branch is in range. */
103
@@ -XXX,XX +XXX,XX @@ static void tcg_out_call_int(TCGContext *s, tcg_insn_unit *arg, bool tail)
104
}
105
}
106
107
-static void tcg_out_call(TCGContext *s, tcg_insn_unit *arg)
108
+static void tcg_out_call(TCGContext *s, const tcg_insn_unit *arg)
109
{
110
tcg_out_call_int(s, arg, false);
111
tcg_out_nop(s);
112
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
113
index XXXXXXX..XXXXXXX 100644
114
--- a/tcg/ppc/tcg-target.c.inc
115
+++ b/tcg/ppc/tcg-target.c.inc
116
@@ -XXX,XX +XXX,XX @@ static void tcg_out_xori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
117
tcg_out_zori32(s, dst, src, c, XORI, XORIS);
118
}
119
120
-static void tcg_out_b(TCGContext *s, int mask, tcg_insn_unit *target)
121
+static void tcg_out_b(TCGContext *s, int mask, const tcg_insn_unit *target)
122
{
123
ptrdiff_t disp = tcg_pcrel_diff(s, target);
124
if (in_range_b(disp)) {
125
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
126
}
127
}
128
129
-static void tcg_out_call(TCGContext *s, tcg_insn_unit *target)
130
+static void tcg_out_call(TCGContext *s, const tcg_insn_unit *target)
131
{
132
#ifdef _CALL_AIX
133
/* Look through the descriptor. If the branch is in range, and we
134
don't have to spend too much effort on building the toc. */
135
- void *tgt = ((void **)target)[0];
136
- uintptr_t toc = ((uintptr_t *)target)[1];
137
+ const void *tgt = ((const void * const *)target)[0];
138
+ uintptr_t toc = ((const uintptr_t *)target)[1];
139
intptr_t diff = tcg_pcrel_diff(s, tgt);
140
141
if (in_range_b(diff) && toc == (uint32_t)toc) {
142
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
143
index XXXXXXX..XXXXXXX 100644
144
--- a/tcg/riscv/tcg-target.c.inc
145
+++ b/tcg/riscv/tcg-target.c.inc
146
@@ -XXX,XX +XXX,XX @@ static bool reloc_jimm20(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
147
return false;
148
}
149
150
-static bool reloc_call(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
151
+static bool reloc_call(tcg_insn_unit *code_ptr, const tcg_insn_unit *target)
152
{
153
intptr_t offset = (intptr_t)target - (intptr_t)code_ptr;
154
int32_t lo = sextreg(offset, 0, 12);
155
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_goto(TCGContext *s, tcg_insn_unit *target)
156
tcg_out_opc_jump(s, OPC_JAL, TCG_REG_ZERO, offset);
157
}
158
159
-static void tcg_out_call_int(TCGContext *s, tcg_insn_unit *arg, bool tail)
160
+static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail)
161
{
162
TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA;
163
ptrdiff_t offset = tcg_pcrel_diff(s, arg);
164
@@ -XXX,XX +XXX,XX @@ static void tcg_out_call_int(TCGContext *s, tcg_insn_unit *arg, bool tail)
165
}
166
}
167
168
-static void tcg_out_call(TCGContext *s, tcg_insn_unit *arg)
169
+static void tcg_out_call(TCGContext *s, const tcg_insn_unit *arg)
170
{
171
tcg_out_call_int(s, arg, false);
172
}
173
diff --git a/tcg/s390/tcg-target.c.inc b/tcg/s390/tcg-target.c.inc
174
index XXXXXXX..XXXXXXX 100644
175
--- a/tcg/s390/tcg-target.c.inc
176
+++ b/tcg/s390/tcg-target.c.inc
177
@@ -XXX,XX +XXX,XX @@ static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
178
tgen_branch(s, cc, l);
179
}
180
181
-static void tcg_out_call(TCGContext *s, tcg_insn_unit *dest)
182
+static void tcg_out_call(TCGContext *s, const tcg_insn_unit *dest)
183
{
184
ptrdiff_t off = dest - s->code_ptr;
185
if (off == (int32_t)off) {
186
diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc/tcg-target.c.inc
187
index XXXXXXX..XXXXXXX 100644
188
--- a/tcg/sparc/tcg-target.c.inc
189
+++ b/tcg/sparc/tcg-target.c.inc
190
@@ -XXX,XX +XXX,XX @@ static void tcg_out_addsub2_i64(TCGContext *s, TCGReg rl, TCGReg rh,
191
tcg_out_mov(s, TCG_TYPE_I64, rl, tmp);
192
}
193
194
-static void tcg_out_call_nodelay(TCGContext *s, tcg_insn_unit *dest,
195
+static void tcg_out_call_nodelay(TCGContext *s, const tcg_insn_unit *dest,
196
bool in_prologue)
197
{
198
ptrdiff_t disp = tcg_pcrel_diff(s, dest);
199
@@ -XXX,XX +XXX,XX @@ static void tcg_out_call_nodelay(TCGContext *s, tcg_insn_unit *dest,
200
}
201
}
202
203
-static void tcg_out_call(TCGContext *s, tcg_insn_unit *dest)
204
+static void tcg_out_call(TCGContext *s, const tcg_insn_unit *dest)
205
{
206
tcg_out_call_nodelay(s, dest, false);
207
tcg_out_nop(s);
208
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
209
index XXXXXXX..XXXXXXX 100644
210
--- a/tcg/tci/tcg-target.c.inc
211
+++ b/tcg/tci/tcg-target.c.inc
212
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi(TCGContext *s, TCGType type,
213
old_code_ptr[1] = s->code_ptr - old_code_ptr;
214
}
215
216
-static inline void tcg_out_call(TCGContext *s, tcg_insn_unit *arg)
217
+static inline void tcg_out_call(TCGContext *s, const tcg_insn_unit *arg)
218
{
219
uint8_t *old_code_ptr = s->code_ptr;
220
tcg_out_op_t(s, INDEX_op_call);
221
--
40
--
222
2.25.1
41
2.43.0
223
42
224
43
diff view generated by jsdifflib
New patch
1
1
Use the scalbn interface instead of float_muladd_halve_result.
2
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
target/sparc/helper.h | 4 +-
7
target/sparc/fop_helper.c | 8 ++--
8
target/sparc/translate.c | 80 +++++++++++++++++++++++----------------
9
3 files changed, 54 insertions(+), 38 deletions(-)
10
11
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/sparc/helper.h
14
+++ b/target/sparc/helper.h
15
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_WG, f64, env, f64, f64)
16
DEF_HELPER_FLAGS_3(fsubd, TCG_CALL_NO_WG, f64, env, f64, f64)
17
DEF_HELPER_FLAGS_3(fmuld, TCG_CALL_NO_WG, f64, env, f64, f64)
18
DEF_HELPER_FLAGS_3(fdivd, TCG_CALL_NO_WG, f64, env, f64, f64)
19
-DEF_HELPER_FLAGS_5(fmaddd, TCG_CALL_NO_WG, f64, env, f64, f64, f64, i32)
20
+DEF_HELPER_FLAGS_6(fmaddd, TCG_CALL_NO_WG, f64, env, f64, f64, f64, s32, i32)
21
DEF_HELPER_FLAGS_3(fnaddd, TCG_CALL_NO_WG, f64, env, f64, f64)
22
DEF_HELPER_FLAGS_3(fnmuld, TCG_CALL_NO_WG, f64, env, f64, f64)
23
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(fadds, TCG_CALL_NO_WG, f32, env, f32, f32)
25
DEF_HELPER_FLAGS_3(fsubs, TCG_CALL_NO_WG, f32, env, f32, f32)
26
DEF_HELPER_FLAGS_3(fmuls, TCG_CALL_NO_WG, f32, env, f32, f32)
27
DEF_HELPER_FLAGS_3(fdivs, TCG_CALL_NO_WG, f32, env, f32, f32)
28
-DEF_HELPER_FLAGS_5(fmadds, TCG_CALL_NO_WG, f32, env, f32, f32, f32, i32)
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());
47
return ret;
48
}
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)
205
--
206
2.43.0
207
208
diff view generated by jsdifflib
1
Now that all native tcg hosts support splitwx,
1
All uses have been convered to float*_muladd_scalbn.
2
make this pointer const.
3
2
4
Reviewed-by: Joelle van Dyne <j@getutm.app>
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.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/tcg/tcg.h | 2 +-
6
include/fpu/softfloat.h | 3 ---
9
tcg/tcg.c | 2 +-
7
fpu/softfloat.c | 6 ------
10
tcg/aarch64/tcg-target.c.inc | 3 +--
8
fpu/softfloat-parts.c.inc | 4 ----
11
tcg/arm/tcg-target.c.inc | 3 +--
9
3 files changed, 13 deletions(-)
12
tcg/i386/tcg-target.c.inc | 3 +--
13
tcg/mips/tcg-target.c.inc | 3 +--
14
tcg/ppc/tcg-target.c.inc | 3 +--
15
tcg/riscv/tcg-target.c.inc | 3 +--
16
tcg/s390/tcg-target.c.inc | 3 +--
17
tcg/sparc/tcg-target.c.inc | 3 +--
18
10 files changed, 10 insertions(+), 18 deletions(-)
19
10
20
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
11
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
21
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
22
--- a/include/tcg/tcg.h
13
--- a/include/fpu/softfloat.h
23
+++ b/include/tcg/tcg.h
14
+++ b/include/fpu/softfloat.h
24
@@ -XXX,XX +XXX,XX @@ struct TCGContext {
15
@@ -XXX,XX +XXX,XX @@ bfloat16 bfloat16_squash_input_denormal(bfloat16 a, float_status *status);
25
16
| Using these differs from negating an input or output before calling
26
extern TCGContext tcg_init_ctx;
17
| the muladd function in that this means that a NaN doesn't have its
27
extern __thread TCGContext *tcg_ctx;
18
| sign bit inverted before it is propagated.
28
-extern void *tcg_code_gen_epilogue;
19
-| We also support halving the result before rounding, as a special
29
+extern const void *tcg_code_gen_epilogue;
20
-| case to support the ARM fused-sqrt-step instruction FRSQRTS.
30
extern uintptr_t tcg_splitwx_diff;
21
*----------------------------------------------------------------------------*/
31
extern TCGv_env cpu_env;
22
enum {
32
23
float_muladd_negate_c = 1,
33
diff --git a/tcg/tcg.c b/tcg/tcg.c
24
float_muladd_negate_product = 2,
25
float_muladd_negate_result = 4,
26
- float_muladd_halve_result = 8,
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/tcg/tcg.c
32
--- a/fpu/softfloat.c
36
+++ b/tcg/tcg.c
33
+++ b/fpu/softfloat.c
37
@@ -XXX,XX +XXX,XX @@ static int tcg_out_ldst_finalize(TCGContext *s);
34
@@ -XXX,XX +XXX,XX @@ float32_muladd(float32 xa, float32 xb, float32 xc, int flags, float_status *s)
38
static TCGContext **tcg_ctxs;
35
if (unlikely(!can_use_fpu(s))) {
39
static unsigned int n_tcg_ctxs;
36
goto soft;
40
TCGv_env cpu_env = 0;
37
}
41
-void *tcg_code_gen_epilogue;
38
- if (unlikely(flags & float_muladd_halve_result)) {
42
+const void *tcg_code_gen_epilogue;
39
- goto soft;
43
uintptr_t tcg_splitwx_diff;
40
- }
44
41
45
#ifndef CONFIG_TCG_INTERPRETER
42
float32_input_flush3(&ua.s, &ub.s, &uc.s, s);
46
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
43
if (unlikely(!f32_is_zon3(ua, ub, uc))) {
44
@@ -XXX,XX +XXX,XX @@ float64_muladd(float64 xa, float64 xb, float64 xc, int flags, float_status *s)
45
if (unlikely(!can_use_fpu(s))) {
46
goto soft;
47
}
48
- if (unlikely(flags & float_muladd_halve_result)) {
49
- goto soft;
50
- }
51
52
float64_input_flush3(&ua.s, &ub.s, &uc.s, s);
53
if (unlikely(!f64_is_zon3(ua, ub, uc))) {
54
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
47
index XXXXXXX..XXXXXXX 100644
55
index XXXXXXX..XXXXXXX 100644
48
--- a/tcg/aarch64/tcg-target.c.inc
56
--- a/fpu/softfloat-parts.c.inc
49
+++ b/tcg/aarch64/tcg-target.c.inc
57
+++ b/fpu/softfloat-parts.c.inc
50
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
58
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(muladd_scalbn)(FloatPartsN *a, FloatPartsN *b,
51
* Return path for goto_ptr. Set return value to 0, a-la exit_tb,
59
a->exp = p_widen.exp;
52
* and fall through to the rest of the epilogue.
60
53
*/
61
return_normal:
54
- /* TODO: Cast goes away when all hosts converted */
62
- /* TODO: Replace all use of float_muladd_halve_result with scale. */
55
- tcg_code_gen_epilogue = (void *)tcg_splitwx_to_rx(s->code_ptr);
63
- if (flags & float_muladd_halve_result) {
56
+ tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
64
- a->exp -= 1;
57
tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_X0, 0);
65
- }
58
66
a->exp += scale;
59
/* TB epilogue */
67
finish_sign:
60
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
68
if (flags & float_muladd_negate_result) {
61
index XXXXXXX..XXXXXXX 100644
62
--- a/tcg/arm/tcg-target.c.inc
63
+++ b/tcg/arm/tcg-target.c.inc
64
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
65
* Return path for goto_ptr. Set return value to 0, a-la exit_tb,
66
* and fall through to the rest of the epilogue.
67
*/
68
- /* TODO: Cast goes away when all hosts converted */
69
- tcg_code_gen_epilogue = (void *)tcg_splitwx_to_rx(s->code_ptr);
70
+ tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
71
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R0, 0);
72
tcg_out_epilogue(s);
73
}
74
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
75
index XXXXXXX..XXXXXXX 100644
76
--- a/tcg/i386/tcg-target.c.inc
77
+++ b/tcg/i386/tcg-target.c.inc
78
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
79
* Return path for goto_ptr. Set return value to 0, a-la exit_tb,
80
* and fall through to the rest of the epilogue.
81
*/
82
- /* TODO: Cast goes away when all hosts converted */
83
- tcg_code_gen_epilogue = (void *)tcg_splitwx_to_rx(s->code_ptr);
84
+ tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
85
tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_EAX, 0);
86
87
/* TB epilogue */
88
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
89
index XXXXXXX..XXXXXXX 100644
90
--- a/tcg/mips/tcg-target.c.inc
91
+++ b/tcg/mips/tcg-target.c.inc
92
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
93
* Return path for goto_ptr. Set return value to 0, a-la exit_tb,
94
* and fall through to the rest of the epilogue.
95
*/
96
- /* TODO: Cast goes away when all hosts converted */
97
- tcg_code_gen_epilogue = (void *)tcg_splitwx_to_rx(s->code_ptr);
98
+ tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
99
tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_V0, TCG_REG_ZERO);
100
101
/* TB epilogue */
102
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
103
index XXXXXXX..XXXXXXX 100644
104
--- a/tcg/ppc/tcg-target.c.inc
105
+++ b/tcg/ppc/tcg-target.c.inc
106
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
107
tcg_out32(s, BCCTR | BO_ALWAYS);
108
109
/* Epilogue */
110
- /* TODO: Cast goes away when all hosts converted */
111
- tcg_code_gen_epilogue = (void *)tcg_splitwx_to_rx(s->code_ptr);
112
+ tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
113
114
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_R1, FRAME_SIZE+LR_OFFSET);
115
for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i) {
116
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
117
index XXXXXXX..XXXXXXX 100644
118
--- a/tcg/riscv/tcg-target.c.inc
119
+++ b/tcg/riscv/tcg-target.c.inc
120
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
121
tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, tcg_target_call_iarg_regs[1], 0);
122
123
/* Return path for goto_ptr. Set return value to 0 */
124
- /* TODO: Cast goes away when all hosts converted */
125
- tcg_code_gen_epilogue = (void *)tcg_splitwx_to_rx(s->code_ptr);
126
+ tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
127
tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_A0, TCG_REG_ZERO);
128
129
/* TB epilogue */
130
diff --git a/tcg/s390/tcg-target.c.inc b/tcg/s390/tcg-target.c.inc
131
index XXXXXXX..XXXXXXX 100644
132
--- a/tcg/s390/tcg-target.c.inc
133
+++ b/tcg/s390/tcg-target.c.inc
134
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
135
* Return path for goto_ptr. Set return value to 0, a-la exit_tb,
136
* and fall through to the rest of the epilogue.
137
*/
138
- /* TODO: Cast goes away when all hosts converted */
139
- tcg_code_gen_epilogue = (void *)tcg_splitwx_to_rx(s->code_ptr);
140
+ tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
141
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, 0);
142
143
/* TB epilogue */
144
diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc/tcg-target.c.inc
145
index XXXXXXX..XXXXXXX 100644
146
--- a/tcg/sparc/tcg-target.c.inc
147
+++ b/tcg/sparc/tcg-target.c.inc
148
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
149
tcg_out_nop(s);
150
151
/* Epilogue for goto_ptr. */
152
- /* TODO: Cast goes away when all hosts converted */
153
- tcg_code_gen_epilogue = (void *)tcg_splitwx_to_rx(s->code_ptr);
154
+ tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
155
tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, RETURN);
156
/* delay slot */
157
tcg_out_movi_imm13(s, TCG_REG_O0, 0);
158
--
69
--
159
2.25.1
70
2.43.0
160
71
161
72
diff view generated by jsdifflib
1
Use tcg_tbrel_diff when we need a displacement to a label,
1
This rounding mode is used by Hexagon.
2
and with a NULL argument when we need the normalizing addend.
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
tcg/s390/tcg-target.c.inc | 16 ++++++++--------
5
include/fpu/softfloat-types.h | 2 ++
7
1 file changed, 8 insertions(+), 8 deletions(-)
6
fpu/softfloat-parts.c.inc | 3 +++
7
2 files changed, 5 insertions(+)
8
8
9
diff --git a/tcg/s390/tcg-target.c.inc b/tcg/s390/tcg-target.c.inc
9
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
10
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/s390/tcg-target.c.inc
11
--- a/include/fpu/softfloat-types.h
12
+++ b/tcg/s390/tcg-target.c.inc
12
+++ b/include/fpu/softfloat-types.h
13
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret,
13
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
14
return;
14
float_round_to_odd = 5,
15
}
15
/* Not an IEEE rounding mode: round to closest odd, overflow to inf */
16
} else if (USE_REG_TB && !in_prologue) {
16
float_round_to_odd_inf = 6,
17
- ptrdiff_t off = sval - (uintptr_t)s->code_gen_ptr;
17
+ /* Not an IEEE rounding mode: round to nearest even, overflow to max */
18
+ ptrdiff_t off = tcg_tbrel_diff(s, (void *)sval);
18
+ float_round_nearest_even_max = 7,
19
if (off == sextract64(off, 0, 20)) {
19
} FloatRoundMode;
20
/* This is certain to be an address within TB, and therefore
20
21
OFF will be negative; don't try RX_LA. */
21
/*
22
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret,
22
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
23
} else if (USE_REG_TB && !in_prologue) {
23
index XXXXXXX..XXXXXXX 100644
24
tcg_out_insn(s, RXY, LG, ret, TCG_REG_TB, TCG_REG_NONE, 0);
24
--- a/fpu/softfloat-parts.c.inc
25
new_pool_label(s, sval, R_390_20, s->code_ptr - 2,
25
+++ b/fpu/softfloat-parts.c.inc
26
- -(intptr_t)s->code_gen_ptr);
26
@@ -XXX,XX +XXX,XX @@ static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s,
27
+ tcg_tbrel_diff(s, NULL));
27
int exp, flags = 0;
28
} else {
28
29
TCGReg base = ret ? ret : TCG_TMP0;
29
switch (s->float_rounding_mode) {
30
tcg_out_insn(s, RIL, LARL, base, 0);
30
+ case float_round_nearest_even_max:
31
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ld_abs(TCGContext *s, TCGType type, TCGReg dest, void *abs)
31
+ overflow_norm = true;
32
}
32
+ /* fall through */
33
}
33
case float_round_nearest_even:
34
if (USE_REG_TB) {
34
if (N > 64 && frac_lsb == 0) {
35
- ptrdiff_t disp = abs - (void *)s->code_gen_ptr;
35
inc = ((p->frac_hi & 1) || (p->frac_lo & round_mask) != frac_lsbm1
36
+ ptrdiff_t disp = tcg_tbrel_diff(s, abs);
37
if (disp == sextract64(disp, 0, 20)) {
38
tcg_out_ld(s, type, dest, TCG_REG_TB, disp);
39
return;
40
@@ -XXX,XX +XXX,XX @@ static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
41
if (!maybe_out_small_movi(s, type, TCG_TMP0, val)) {
42
tcg_out_insn(s, RXY, NG, dest, TCG_REG_TB, TCG_REG_NONE, 0);
43
new_pool_label(s, val & valid, R_390_20, s->code_ptr - 2,
44
- -(intptr_t)s->code_gen_ptr);
45
+ tcg_tbrel_diff(s, NULL));
46
return;
47
}
48
} else {
49
@@ -XXX,XX +XXX,XX @@ static void tgen_ori(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
50
} else if (USE_REG_TB) {
51
tcg_out_insn(s, RXY, OG, dest, TCG_REG_TB, TCG_REG_NONE, 0);
52
new_pool_label(s, val, R_390_20, s->code_ptr - 2,
53
- -(intptr_t)s->code_gen_ptr);
54
+ tcg_tbrel_diff(s, NULL));
55
} else {
56
/* Perform the OR via sequential modifications to the high and
57
low parts. Do this via recursion to handle 16-bit vs 32-bit
58
@@ -XXX,XX +XXX,XX @@ static void tgen_xori(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
59
} else if (USE_REG_TB) {
60
tcg_out_insn(s, RXY, XG, dest, TCG_REG_TB, TCG_REG_NONE, 0);
61
new_pool_label(s, val, R_390_20, s->code_ptr - 2,
62
- -(intptr_t)s->code_gen_ptr);
63
+ tcg_tbrel_diff(s, NULL));
64
} else {
65
/* Perform the xor by parts. */
66
tcg_debug_assert(s390_facilities & FACILITY_EXT_IMM);
67
@@ -XXX,XX +XXX,XX @@ static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
68
op = (is_unsigned ? RXY_CLY : RXY_CY);
69
tcg_out_insn_RXY(s, op, r1, TCG_REG_TB, TCG_REG_NONE, 0);
70
new_pool_label(s, (uint32_t)c2, R_390_20, s->code_ptr - 2,
71
- 4 - (intptr_t)s->code_gen_ptr);
72
+ 4 - tcg_tbrel_diff(s, NULL));
73
} else {
74
op = (is_unsigned ? RXY_CLG : RXY_CG);
75
tcg_out_insn_RXY(s, op, r1, TCG_REG_TB, TCG_REG_NONE, 0);
76
new_pool_label(s, c2, R_390_20, s->code_ptr - 2,
77
- -(intptr_t)s->code_gen_ptr);
78
+ tcg_tbrel_diff(s, NULL));
79
}
80
goto exit;
81
} else {
82
--
36
--
83
2.25.1
37
2.43.0
84
85
diff view generated by jsdifflib
1
Use tcg_tbrel_diff when we need a displacement to a label,
1
Certain Hexagon instructions suppress changes to the result
2
and with a NULL argument when we need the normalizing addend.
2
when the product of fma() is a true zero.
3
3
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
5
---
6
tcg/ppc/tcg-target.c.inc | 6 +++---
6
include/fpu/softfloat.h | 5 +++++
7
1 file changed, 3 insertions(+), 3 deletions(-)
7
fpu/softfloat.c | 3 +++
8
fpu/softfloat-parts.c.inc | 4 +++-
9
3 files changed, 11 insertions(+), 1 deletion(-)
8
10
9
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
11
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
10
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/ppc/tcg-target.c.inc
13
--- a/include/fpu/softfloat.h
12
+++ b/tcg/ppc/tcg-target.c.inc
14
+++ b/include/fpu/softfloat.h
13
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret,
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;
14
}
39
}
15
40
+ if (unlikely(flags & float_muladd_suppress_add_product_zero)) {
16
/* Load addresses within the TB with one insn. */
41
+ goto soft;
17
- tb_diff = arg - (intptr_t)s->code_gen_ptr;
42
+ }
18
+ tb_diff = tcg_tbrel_diff(s, (void *)arg);
43
19
if (!in_prologue && USE_REG_TB && tb_diff == (int16_t)tb_diff) {
44
float32_input_flush3(&ua.s, &ub.s, &uc.s, s);
20
tcg_out32(s, ADDI | TAI(ret, TCG_REG_TB, tb_diff));
45
if (unlikely(!f32_is_zon3(ua, ub, uc))) {
21
return;
46
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
22
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret,
47
index XXXXXXX..XXXXXXX 100644
23
/* Use the constant pool, if possible. */
48
--- a/fpu/softfloat-parts.c.inc
24
if (!in_prologue && USE_REG_TB) {
49
+++ b/fpu/softfloat-parts.c.inc
25
new_pool_label(s, arg, R_PPC_ADDR16, s->code_ptr,
50
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(muladd_scalbn)(FloatPartsN *a, FloatPartsN *b,
26
- -(intptr_t)s->code_gen_ptr);
51
goto return_normal;
27
+ tcg_tbrel_diff(s, NULL));
52
}
28
tcg_out32(s, LD | TAI(ret, TCG_REG_TB, 0));
53
if (c->cls == float_class_zero) {
29
return;
54
- if (a->sign != c->sign) {
30
}
55
+ if (flags & float_muladd_suppress_add_product_zero) {
31
@@ -XXX,XX +XXX,XX @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType type, TCGReg ret,
56
+ a->sign = c->sign;
32
*/
57
+ } else if (a->sign != c->sign) {
33
if (USE_REG_TB) {
58
goto return_sub_zero;
34
rel = R_PPC_ADDR16;
59
}
35
- add = -(intptr_t)s->code_gen_ptr;
60
goto return_zero;
36
+ add = tcg_tbrel_diff(s, NULL);
37
} else {
38
rel = R_PPC_ADDR32;
39
add = 0;
40
--
61
--
41
2.25.1
62
2.43.0
42
43
diff view generated by jsdifflib
1
We must change all targets at once, since all must match
1
There are no special cases for this instruction.
2
the declaration in tcg.c.
2
Remove internal_mpyf as unused.
3
3
4
Reviewed-by: Joelle van Dyne <j@getutm.app>
4
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
6
---
7
include/tcg/tcg.h | 2 +-
7
target/hexagon/fma_emu.h | 1 -
8
tcg/tcg.c | 10 +++++-----
8
target/hexagon/fma_emu.c | 8 --------
9
tcg/aarch64/tcg-target.c.inc | 2 +-
9
target/hexagon/op_helper.c | 2 +-
10
tcg/arm/tcg-target.c.inc | 2 +-
10
3 files changed, 1 insertion(+), 10 deletions(-)
11
tcg/i386/tcg-target.c.inc | 2 +-
12
tcg/mips/tcg-target.c.inc | 2 +-
13
tcg/ppc/tcg-target.c.inc | 2 +-
14
tcg/riscv/tcg-target.c.inc | 2 +-
15
tcg/s390/tcg-target.c.inc | 2 +-
16
tcg/sparc/tcg-target.c.inc | 2 +-
17
10 files changed, 14 insertions(+), 14 deletions(-)
18
11
19
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
12
diff --git a/target/hexagon/fma_emu.h b/target/hexagon/fma_emu.h
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/include/tcg/tcg.h
14
--- a/target/hexagon/fma_emu.h
22
+++ b/include/tcg/tcg.h
15
+++ b/target/hexagon/fma_emu.h
23
@@ -XXX,XX +XXX,XX @@ typedef uintptr_t tcg_prologue_fn(CPUArchState *env, const void *tb_ptr);
16
@@ -XXX,XX +XXX,XX @@ int32_t float32_getexp(float32 f32);
24
extern tcg_prologue_fn *tcg_qemu_tb_exec;
17
float32 infinite_float32(uint8_t sign);
25
#endif
18
float32 internal_fmafx(float32 a, float32 b, float32 c,
26
19
int scale, float_status *fp_status);
27
-void tcg_register_jit(void *buf, size_t buf_size);
20
-float32 internal_mpyf(float32 a, float32 b, float_status *fp_status);
28
+void tcg_register_jit(const void *buf, size_t buf_size);
21
float64 internal_mpyhh(float64 a, float64 b,
29
22
unsigned long long int accumulated,
30
#if TCG_TARGET_MAYBE_vec
23
float_status *fp_status);
31
/* Return zero if the tuple (opc, type, vece) is unsupportable;
24
diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c
32
diff --git a/tcg/tcg.c b/tcg/tcg.c
33
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
34
--- a/tcg/tcg.c
26
--- a/target/hexagon/fma_emu.c
35
+++ b/tcg/tcg.c
27
+++ b/target/hexagon/fma_emu.c
36
@@ -XXX,XX +XXX,XX @@ typedef struct QEMU_PACKED {
28
@@ -XXX,XX +XXX,XX @@ float32 internal_fmafx(float32 a, float32 b, float32 c, int scale,
37
DebugFrameFDEHeader fde;
29
return accum_round_float32(result, fp_status);
38
} DebugFrameHeader;
39
40
-static void tcg_register_jit_int(void *buf, size_t size,
41
+static void tcg_register_jit_int(const void *buf, size_t size,
42
const void *debug_frame,
43
size_t debug_frame_size)
44
__attribute__((unused));
45
@@ -XXX,XX +XXX,XX @@ void tcg_prologue_init(TCGContext *s)
46
total_size -= prologue_size;
47
s->code_gen_buffer_size = total_size;
48
49
- tcg_register_jit(s->code_gen_buffer, total_size);
50
+ tcg_register_jit(tcg_splitwx_to_rx(s->code_gen_buffer), total_size);
51
52
#ifdef DEBUG_DISAS
53
if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
54
@@ -XXX,XX +XXX,XX @@ static int find_string(const char *strtab, const char *str)
55
}
56
}
30
}
57
31
58
-static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
32
-float32 internal_mpyf(float32 a, float32 b, float_status *fp_status)
59
+static void tcg_register_jit_int(const void *buf_ptr, size_t buf_size,
33
-{
60
const void *debug_frame,
34
- if (float32_is_zero(a) || float32_is_zero(b)) {
61
size_t debug_frame_size)
35
- return float32_mul(a, b, fp_status);
36
- }
37
- return internal_fmafx(a, b, float32_zero, 0, fp_status);
38
-}
39
-
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)
62
{
48
{
63
@@ -XXX,XX +XXX,XX @@ static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
49
float32 RdV;
64
/* No support for the feature. Provide the entry point expected by exec.c,
50
arch_fpop_start(env);
65
and implement the internal function we declared earlier. */
51
- RdV = internal_mpyf(RsV, RtV, &env->fp_status);
66
52
+ RdV = float32_mul(RsV, RtV, &env->fp_status);
67
-static void tcg_register_jit_int(void *buf, size_t size,
53
arch_fpop_end(env);
68
+static void tcg_register_jit_int(const void *buf, size_t size,
54
return RdV;
69
const void *debug_frame,
70
size_t debug_frame_size)
71
{
72
}
73
74
-void tcg_register_jit(void *buf, size_t buf_size)
75
+void tcg_register_jit(const void *buf, size_t buf_size)
76
{
77
}
78
#endif /* ELF_HOST_MACHINE */
79
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
80
index XXXXXXX..XXXXXXX 100644
81
--- a/tcg/aarch64/tcg-target.c.inc
82
+++ b/tcg/aarch64/tcg-target.c.inc
83
@@ -XXX,XX +XXX,XX @@ static const DebugFrame debug_frame = {
84
}
85
};
86
87
-void tcg_register_jit(void *buf, size_t buf_size)
88
+void tcg_register_jit(const void *buf, size_t buf_size)
89
{
90
tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
91
}
92
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
93
index XXXXXXX..XXXXXXX 100644
94
--- a/tcg/arm/tcg-target.c.inc
95
+++ b/tcg/arm/tcg-target.c.inc
96
@@ -XXX,XX +XXX,XX @@ static const DebugFrame debug_frame = {
97
}
98
};
99
100
-void tcg_register_jit(void *buf, size_t buf_size)
101
+void tcg_register_jit(const void *buf, size_t buf_size)
102
{
103
tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
104
}
105
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
106
index XXXXXXX..XXXXXXX 100644
107
--- a/tcg/i386/tcg-target.c.inc
108
+++ b/tcg/i386/tcg-target.c.inc
109
@@ -XXX,XX +XXX,XX @@ static const DebugFrame debug_frame = {
110
#endif
111
112
#if defined(ELF_HOST_MACHINE)
113
-void tcg_register_jit(void *buf, size_t buf_size)
114
+void tcg_register_jit(const void *buf, size_t buf_size)
115
{
116
tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
117
}
118
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
119
index XXXXXXX..XXXXXXX 100644
120
--- a/tcg/mips/tcg-target.c.inc
121
+++ b/tcg/mips/tcg-target.c.inc
122
@@ -XXX,XX +XXX,XX @@ static const DebugFrame debug_frame = {
123
}
124
};
125
126
-void tcg_register_jit(void *buf, size_t buf_size)
127
+void tcg_register_jit(const void *buf, size_t buf_size)
128
{
129
tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
130
}
131
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
132
index XXXXXXX..XXXXXXX 100644
133
--- a/tcg/ppc/tcg-target.c.inc
134
+++ b/tcg/ppc/tcg-target.c.inc
135
@@ -XXX,XX +XXX,XX @@ static DebugFrame debug_frame = {
136
}
137
};
138
139
-void tcg_register_jit(void *buf, size_t buf_size)
140
+void tcg_register_jit(const void *buf, size_t buf_size)
141
{
142
uint8_t *p = &debug_frame.fde_reg_ofs[3];
143
int i;
144
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
145
index XXXXXXX..XXXXXXX 100644
146
--- a/tcg/riscv/tcg-target.c.inc
147
+++ b/tcg/riscv/tcg-target.c.inc
148
@@ -XXX,XX +XXX,XX @@ static const DebugFrame debug_frame = {
149
}
150
};
151
152
-void tcg_register_jit(void *buf, size_t buf_size)
153
+void tcg_register_jit(const void *buf, size_t buf_size)
154
{
155
tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
156
}
157
diff --git a/tcg/s390/tcg-target.c.inc b/tcg/s390/tcg-target.c.inc
158
index XXXXXXX..XXXXXXX 100644
159
--- a/tcg/s390/tcg-target.c.inc
160
+++ b/tcg/s390/tcg-target.c.inc
161
@@ -XXX,XX +XXX,XX @@ static const DebugFrame debug_frame = {
162
}
163
};
164
165
-void tcg_register_jit(void *buf, size_t buf_size)
166
+void tcg_register_jit(const void *buf, size_t buf_size)
167
{
168
tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
169
}
170
diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc/tcg-target.c.inc
171
index XXXXXXX..XXXXXXX 100644
172
--- a/tcg/sparc/tcg-target.c.inc
173
+++ b/tcg/sparc/tcg-target.c.inc
174
@@ -XXX,XX +XXX,XX @@ static const DebugFrame debug_frame = {
175
.fde_ret_save = { 9, 15, 31 }, /* DW_CFA_register o7, i7 */
176
};
177
178
-void tcg_register_jit(void *buf, size_t buf_size)
179
+void tcg_register_jit(const void *buf, size_t buf_size)
180
{
181
tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
182
}
55
}
183
--
56
--
184
2.25.1
57
2.43.0
185
186
diff view generated by jsdifflib
New patch
1
There are no special cases for this instruction.
1
2
3
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
target/hexagon/op_helper.c | 2 +-
7
1 file changed, 1 insertion(+), 1 deletion(-)
8
9
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/target/hexagon/op_helper.c
12
+++ b/target/hexagon/op_helper.c
13
@@ -XXX,XX +XXX,XX @@ float32 HELPER(sffma)(CPUHexagonState *env, float32 RxV,
14
float32 RsV, float32 RtV)
15
{
16
arch_fpop_start(env);
17
- RxV = internal_fmafx(RsV, RtV, RxV, 0, &env->fp_status);
18
+ RxV = float32_muladd(RsV, RtV, RxV, 0, &env->fp_status);
19
arch_fpop_end(env);
20
return RxV;
21
}
22
--
23
2.43.0
diff view generated by jsdifflib
New patch
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.
1
4
5
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
target/hexagon/op_helper.c | 5 ++---
9
1 file changed, 2 insertions(+), 3 deletions(-)
10
11
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/hexagon/op_helper.c
14
+++ b/target/hexagon/op_helper.c
15
@@ -XXX,XX +XXX,XX @@ float32 HELPER(sffma_sc)(CPUHexagonState *env, float32 RxV,
16
float32 HELPER(sffms)(CPUHexagonState *env, float32 RxV,
17
float32 RsV, float32 RtV)
18
{
19
- float32 neg_RsV;
20
arch_fpop_start(env);
21
- neg_RsV = float32_set_sign(RsV, float32_is_neg(RsV) ? 0 : 1);
22
- RxV = internal_fmafx(neg_RsV, RtV, RxV, 0, &env->fp_status);
23
+ RxV = float32_muladd(RsV, RtV, RxV, float_muladd_negate_product,
24
+ &env->fp_status);
25
arch_fpop_end(env);
26
return RxV;
27
}
28
--
29
2.43.0
diff view generated by jsdifflib
New patch
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.
1
5
6
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
9
target/hexagon/op_helper.c | 11 +++--------
10
1 file changed, 3 insertions(+), 8 deletions(-)
11
12
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/hexagon/op_helper.c
15
+++ b/target/hexagon/op_helper.c
16
@@ -XXX,XX +XXX,XX @@ static float32 check_nan(float32 dst, float32 x, float_status *fp_status)
17
float32 HELPER(sffma_sc)(CPUHexagonState *env, float32 RxV,
18
float32 RsV, float32 RtV, float32 PuV)
19
{
20
- size4s_t tmp;
21
arch_fpop_start(env);
22
- RxV = check_nan(RxV, RxV, &env->fp_status);
23
- RxV = check_nan(RxV, RsV, &env->fp_status);
24
- RxV = check_nan(RxV, RtV, &env->fp_status);
25
- tmp = internal_fmafx(RsV, RtV, RxV, fSXTN(8, 64, PuV), &env->fp_status);
26
- if (!(float32_is_zero(RxV) && is_zero_prod(RsV, RtV))) {
27
- RxV = tmp;
28
- }
29
+ RxV = float32_muladd_scalbn(RsV, RtV, RxV, fSXTN(8, 64, PuV),
30
+ float_muladd_suppress_add_product_zero,
31
+ &env->fp_status);
32
arch_fpop_end(env);
33
return RxV;
34
}
35
--
36
2.43.0
diff view generated by jsdifflib
1
Now that all native tcg hosts support splitwx,
1
There are multiple special cases for this instruction.
2
make this pointer const.
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.
3
8
4
Reviewed-by: Joelle van Dyne <j@getutm.app>
9
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
11
---
8
tcg/aarch64/tcg-target.c.inc | 3 +--
12
target/hexagon/op_helper.c | 105 +++++++++----------------------------
9
tcg/arm/tcg-target.c.inc | 3 +--
13
1 file changed, 26 insertions(+), 79 deletions(-)
10
tcg/i386/tcg-target.c.inc | 3 +--
11
tcg/mips/tcg-target.c.inc | 3 +--
12
tcg/ppc/tcg-target.c.inc | 3 +--
13
tcg/riscv/tcg-target.c.inc | 3 +--
14
tcg/s390/tcg-target.c.inc | 3 +--
15
tcg/tcg-ldst.c.inc | 2 +-
16
8 files changed, 8 insertions(+), 15 deletions(-)
17
14
18
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
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/tcg/aarch64/tcg-target.c.inc
17
--- a/target/hexagon/op_helper.c
21
+++ b/tcg/aarch64/tcg-target.c.inc
18
+++ b/target/hexagon/op_helper.c
22
@@ -XXX,XX +XXX,XX @@ static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
19
@@ -XXX,XX +XXX,XX @@ float32 HELPER(sffma)(CPUHexagonState *env, float32 RxV,
23
label->type = ext;
20
return RxV;
24
label->datalo_reg = data_reg;
25
label->addrlo_reg = addr_reg;
26
- /* TODO: Cast goes away when all hosts converted */
27
- label->raddr = (void *)tcg_splitwx_to_rx(raddr);
28
+ label->raddr = tcg_splitwx_to_rx(raddr);
29
label->label_ptr[0] = label_ptr;
30
}
21
}
31
22
32
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
23
-static bool is_zero_prod(float32 a, float32 b)
33
index XXXXXXX..XXXXXXX 100644
24
-{
34
--- a/tcg/arm/tcg-target.c.inc
25
- return ((float32_is_zero(a) && is_finite(b)) ||
35
+++ b/tcg/arm/tcg-target.c.inc
26
- (float32_is_zero(b) && is_finite(a)));
36
@@ -XXX,XX +XXX,XX @@ static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
27
-}
37
label->datahi_reg = datahi;
28
-
38
label->addrlo_reg = addrlo;
29
-static float32 check_nan(float32 dst, float32 x, float_status *fp_status)
39
label->addrhi_reg = addrhi;
30
-{
40
- /* TODO: Cast goes away when all hosts converted */
31
- float32 ret = dst;
41
- label->raddr = (void *)tcg_splitwx_to_rx(raddr);
32
- if (float32_is_any_nan(x)) {
42
+ label->raddr = tcg_splitwx_to_rx(raddr);
33
- if (extract32(x, 22, 1) == 0) {
43
label->label_ptr[0] = label_ptr;
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)
43
{
44
@@ -XXX,XX +XXX,XX @@ float32 HELPER(sffms)(CPUHexagonState *env, float32 RxV,
45
return RxV;
44
}
46
}
45
47
46
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
48
-static bool is_inf_prod(int32_t a, int32_t b)
47
index XXXXXXX..XXXXXXX 100644
49
+static float32 do_sffma_lib(CPUHexagonState *env, float32 RxV,
48
--- a/tcg/i386/tcg-target.c.inc
50
+ float32 RsV, float32 RtV, int negate)
49
+++ b/tcg/i386/tcg-target.c.inc
51
{
50
@@ -XXX,XX +XXX,XX @@ static void add_qemu_ldst_label(TCGContext *s, bool is_ld, bool is_64,
52
- return (float32_is_infinity(a) && float32_is_infinity(b)) ||
51
label->datahi_reg = datahi;
53
- (float32_is_infinity(a) && is_finite(b) && !float32_is_zero(b)) ||
52
label->addrlo_reg = addrlo;
54
- (float32_is_infinity(b) && is_finite(a) && !float32_is_zero(a));
53
label->addrhi_reg = addrhi;
55
+ int flags;
54
- /* TODO: Cast goes away when all hosts converted */
56
+
55
- label->raddr = (void *)tcg_splitwx_to_rx(raddr);
57
+ arch_fpop_start(env);
56
+ label->raddr = tcg_splitwx_to_rx(raddr);
58
+
57
label->label_ptr[0] = label_ptr[0];
59
+ set_float_rounding_mode(float_round_nearest_even_max, &env->fp_status);
58
if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
60
+ RxV = float32_muladd(RsV, RtV, RxV,
59
label->label_ptr[1] = label_ptr[1];
61
+ negate | float_muladd_suppress_add_product_zero,
60
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
62
+ &env->fp_status);
61
index XXXXXXX..XXXXXXX 100644
63
+
62
--- a/tcg/mips/tcg-target.c.inc
64
+ flags = get_float_exception_flags(&env->fp_status);
63
+++ b/tcg/mips/tcg-target.c.inc
65
+ if (flags) {
64
@@ -XXX,XX +XXX,XX @@ static void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOpIdx oi,
66
+ /* Flags are suppressed by this instruction. */
65
label->datahi_reg = datahi;
67
+ set_float_exception_flags(0, &env->fp_status);
66
label->addrlo_reg = addrlo;
68
+
67
label->addrhi_reg = addrhi;
69
+ /* Return 0 for Inf - Inf. */
68
- /* TODO: Cast goes away when all hosts converted */
70
+ if (flags & float_flag_invalid_isi) {
69
- label->raddr = (void *)tcg_splitwx_to_rx(raddr);
71
+ RxV = 0;
70
+ label->raddr = tcg_splitwx_to_rx(raddr);
72
+ }
71
label->label_ptr[0] = label_ptr[0];
73
+ }
72
if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
74
+
73
label->label_ptr[1] = label_ptr[1];
75
+ arch_fpop_end(env);
74
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
76
+ return RxV;
75
index XXXXXXX..XXXXXXX 100644
76
--- a/tcg/ppc/tcg-target.c.inc
77
+++ b/tcg/ppc/tcg-target.c.inc
78
@@ -XXX,XX +XXX,XX @@ static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
79
label->datahi_reg = datahi_reg;
80
label->addrlo_reg = addrlo_reg;
81
label->addrhi_reg = addrhi_reg;
82
- /* TODO: Cast goes away when all hosts converted */
83
- label->raddr = (void *)tcg_splitwx_to_rx(raddr);
84
+ label->raddr = tcg_splitwx_to_rx(raddr);
85
label->label_ptr[0] = lptr;
86
}
77
}
87
78
88
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
79
float32 HELPER(sffma_lib)(CPUHexagonState *env, float32 RxV,
89
index XXXXXXX..XXXXXXX 100644
80
float32 RsV, float32 RtV)
90
--- a/tcg/riscv/tcg-target.c.inc
81
{
91
+++ b/tcg/riscv/tcg-target.c.inc
82
- bool infinp;
92
@@ -XXX,XX +XXX,XX @@ static void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOpIdx oi,
83
- bool infminusinf;
93
label->datahi_reg = datahi;
84
- float32 tmp;
94
label->addrlo_reg = addrlo;
85
-
95
label->addrhi_reg = addrhi;
86
- arch_fpop_start(env);
96
- /* TODO: Cast goes away when all hosts converted */
87
- set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
97
- label->raddr = (void *)tcg_splitwx_to_rx(raddr);
88
- infminusinf = float32_is_infinity(RxV) &&
98
+ label->raddr = tcg_splitwx_to_rx(raddr);
89
- is_inf_prod(RsV, RtV) &&
99
label->label_ptr[0] = label_ptr[0];
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);
100
}
111
}
101
112
102
diff --git a/tcg/s390/tcg-target.c.inc b/tcg/s390/tcg-target.c.inc
113
float32 HELPER(sffms_lib)(CPUHexagonState *env, float32 RxV,
103
index XXXXXXX..XXXXXXX 100644
114
float32 RsV, float32 RtV)
104
--- a/tcg/s390/tcg-target.c.inc
115
{
105
+++ b/tcg/s390/tcg-target.c.inc
116
- bool infinp;
106
@@ -XXX,XX +XXX,XX @@ static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
117
- bool infminusinf;
107
label->oi = oi;
118
- float32 tmp;
108
label->datalo_reg = data;
119
-
109
label->addrlo_reg = addr;
120
- arch_fpop_start(env);
110
- /* TODO: Cast goes away when all hosts converted */
121
- set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
111
- label->raddr = (void *)tcg_splitwx_to_rx(raddr);
122
- infminusinf = float32_is_infinity(RxV) &&
112
+ label->raddr = tcg_splitwx_to_rx(raddr);
123
- is_inf_prod(RsV, RtV) &&
113
label->label_ptr[0] = label_ptr;
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);
114
}
146
}
115
147
116
diff --git a/tcg/tcg-ldst.c.inc b/tcg/tcg-ldst.c.inc
148
float64 HELPER(dfmpyfix)(CPUHexagonState *env, float64 RssV, float64 RttV)
117
index XXXXXXX..XXXXXXX 100644
118
--- a/tcg/tcg-ldst.c.inc
119
+++ b/tcg/tcg-ldst.c.inc
120
@@ -XXX,XX +XXX,XX @@ typedef struct TCGLabelQemuLdst {
121
TCGReg addrhi_reg; /* reg index for high word of guest virtual addr */
122
TCGReg datalo_reg; /* reg index for low word to be loaded or stored */
123
TCGReg datahi_reg; /* reg index for high word to be loaded or stored */
124
- tcg_insn_unit *raddr; /* gen code addr of the next IR of qemu_ld/st IR */
125
+ const tcg_insn_unit *raddr; /* addr of the next IR of qemu_ld/st IR */
126
tcg_insn_unit *label_ptr[2]; /* label pointers to be updated */
127
QSIMPLEQ_ENTRY(TCGLabelQemuLdst) next;
128
} TCGLabelQemuLdst;
129
--
149
--
130
2.25.1
150
2.43.0
131
132
diff view generated by jsdifflib
1
This value is constant across all thread-local copies of TCGContext,
1
The function is now unused.
2
so we might as well move it out of thread-local storage.
3
2
4
Use the correct function pointer type, and name the variable
3
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
5
tcg_qemu_tb_exec, which means that we are able to remove the
6
macro that does the casting.
7
8
Replace HAVE_TCG_QEMU_TB_EXEC with CONFIG_TCG_INTERPRETER,
9
as this is somewhat clearer in intent.
10
11
Reviewed-by: Joelle van Dyne <j@getutm.app>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
---
5
---
16
include/tcg/tcg.h | 9 ++++-----
6
target/hexagon/fma_emu.h | 2 -
17
tcg/tcg.c | 9 ++++++++-
7
target/hexagon/fma_emu.c | 171 ---------------------------------------
18
tcg/tci.c | 4 ++--
8
2 files changed, 173 deletions(-)
19
3 files changed, 14 insertions(+), 8 deletions(-)
20
9
21
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
10
diff --git a/target/hexagon/fma_emu.h b/target/hexagon/fma_emu.h
22
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
23
--- a/include/tcg/tcg.h
12
--- a/target/hexagon/fma_emu.h
24
+++ b/include/tcg/tcg.h
13
+++ b/target/hexagon/fma_emu.h
25
@@ -XXX,XX +XXX,XX @@ struct TCGContext {
14
@@ -XXX,XX +XXX,XX @@ static inline uint32_t float32_getexp_raw(float32 f32)
26
here, because there's too much arithmetic throughout that relies
15
}
27
on addition and subtraction working on bytes. Rely on the GCC
16
int32_t float32_getexp(float32 f32);
28
extension that allows arithmetic on void*. */
17
float32 infinite_float32(uint8_t sign);
29
- void *code_gen_prologue;
18
-float32 internal_fmafx(float32 a, float32 b, float32 c,
30
void *code_gen_epilogue;
19
- int scale, float_status *fp_status);
31
void *code_gen_buffer;
20
float64 internal_mpyhh(float64 a, float64 b,
32
size_t code_gen_buffer_size;
21
unsigned long long int accumulated,
33
@@ -XXX,XX +XXX,XX @@ static inline unsigned get_mmuidx(TCGMemOpIdx oi)
22
float_status *fp_status);
34
#define TB_EXIT_IDXMAX 1
23
diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c
35
#define TB_EXIT_REQUESTED 3
36
37
-#ifdef HAVE_TCG_QEMU_TB_EXEC
38
-uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr);
39
+#ifdef CONFIG_TCG_INTERPRETER
40
+uintptr_t tcg_qemu_tb_exec(CPUArchState *env, void *tb_ptr);
41
#else
42
-# define tcg_qemu_tb_exec(env, tb_ptr) \
43
- ((uintptr_t (*)(void *, void *))tcg_ctx->code_gen_prologue)(env, tb_ptr)
44
+typedef uintptr_t tcg_prologue_fn(CPUArchState *env, void *tb_ptr);
45
+extern tcg_prologue_fn *tcg_qemu_tb_exec;
46
#endif
47
48
void tcg_register_jit(void *buf, size_t buf_size);
49
diff --git a/tcg/tcg.c b/tcg/tcg.c
50
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
51
--- a/tcg/tcg.c
25
--- a/target/hexagon/fma_emu.c
52
+++ b/tcg/tcg.c
26
+++ b/target/hexagon/fma_emu.c
53
@@ -XXX,XX +XXX,XX @@ static TCGContext **tcg_ctxs;
27
@@ -XXX,XX +XXX,XX @@ int32_t float64_getexp(float64 f64)
54
static unsigned int n_tcg_ctxs;
28
return -1;
55
TCGv_env cpu_env = 0;
29
}
56
30
57
+#ifndef CONFIG_TCG_INTERPRETER
31
-static uint64_t float32_getmant(float32 f32)
58
+tcg_prologue_fn *tcg_qemu_tb_exec;
32
-{
59
+#endif
33
- Float a = { .i = f32 };
60
+
34
- if (float32_is_normal(f32)) {
61
struct tcg_region_tree {
35
- return a.mant | 1ULL << 23;
62
QemuMutex lock;
36
- }
63
GTree *tree;
37
- if (float32_is_zero(f32)) {
64
@@ -XXX,XX +XXX,XX @@ void tcg_prologue_init(TCGContext *s)
38
- return 0;
65
s->code_ptr = buf0;
39
- }
66
s->code_buf = buf0;
40
- if (float32_is_denormal(f32)) {
67
s->data_gen_ptr = NULL;
41
- return a.mant;
68
- s->code_gen_prologue = buf0;
42
- }
69
+
43
- return ~0ULL;
70
+#ifndef CONFIG_TCG_INTERPRETER
44
-}
71
+ tcg_qemu_tb_exec = (tcg_prologue_fn *)buf0;
45
-
72
+#endif
46
int32_t float32_getexp(float32 f32)
73
74
/* Compute a high-water mark, at which we voluntarily flush the buffer
75
and start over. The size here is arbitrary, significantly larger
76
diff --git a/tcg/tci.c b/tcg/tci.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/tcg/tci.c
79
+++ b/tcg/tci.c
80
@@ -XXX,XX +XXX,XX @@ static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
81
* One possible operation in the pseudo code is a call to binary code.
82
* Therefore, disable CFI checks in the interpreter function
83
*/
84
-QEMU_DISABLE_CFI
85
-uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
86
+uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env, void *v_tb_ptr)
87
{
47
{
88
+ uint8_t *tb_ptr = v_tb_ptr;
48
Float a = { .i = f32 };
89
tcg_target_ulong regs[TCG_TARGET_NB_REGS];
49
@@ -XXX,XX +XXX,XX @@ float32 infinite_float32(uint8_t sign)
90
long tcg_temps[CPU_TEMP_BUF_NLONGS];
50
}
91
uintptr_t sp_value = (uintptr_t)(tcg_temps + CPU_TEMP_BUF_NLONGS);
51
52
/* Return a maximum finite value with the requested sign */
53
-static float32 maxfinite_float32(uint8_t sign)
54
-{
55
- if (sign) {
56
- return make_float32(SF_MINUS_MAXF);
57
- } else {
58
- return make_float32(SF_MAXF);
59
- }
60
-}
61
-
62
-/* Return a zero value with requested sign */
63
-static float32 zero_float32(uint8_t sign)
64
-{
65
- if (sign) {
66
- return make_float32(0x80000000);
67
- } else {
68
- return float32_zero;
69
- }
70
-}
71
-
72
#define GEN_XF_ROUND(SUFFIX, MANTBITS, INF_EXP, INTERNAL_TYPE) \
73
static SUFFIX accum_round_##SUFFIX(Accum a, float_status * fp_status) \
74
{ \
75
@@ -XXX,XX +XXX,XX @@ static SUFFIX accum_round_##SUFFIX(Accum a, float_status * fp_status) \
76
}
77
78
GEN_XF_ROUND(float64, DF_MANTBITS, DF_INF_EXP, Double)
79
-GEN_XF_ROUND(float32, SF_MANTBITS, SF_INF_EXP, Float)
80
-
81
-static bool is_inf_prod(float64 a, float64 b)
82
-{
83
- return ((float64_is_infinity(a) && float64_is_infinity(b)) ||
84
- (float64_is_infinity(a) && is_finite(b) && (!float64_is_zero(b))) ||
85
- (float64_is_infinity(b) && is_finite(a) && (!float64_is_zero(a))));
86
-}
87
-
88
-static float64 special_fma(float64 a, float64 b, float64 c,
89
- float_status *fp_status)
90
-{
91
- float64 ret = make_float64(0);
92
-
93
- /*
94
- * If A multiplied by B is an exact infinity and C is also an infinity
95
- * but with the opposite sign, FMA returns NaN and raises invalid.
96
- */
97
- uint8_t a_sign = float64_is_neg(a);
98
- uint8_t b_sign = float64_is_neg(b);
99
- uint8_t c_sign = float64_is_neg(c);
100
- if (is_inf_prod(a, b) && float64_is_infinity(c)) {
101
- if ((a_sign ^ b_sign) != c_sign) {
102
- ret = make_float64(DF_NAN);
103
- float_raise(float_flag_invalid, fp_status);
104
- return ret;
105
- }
106
- }
107
- if ((float64_is_infinity(a) && float64_is_zero(b)) ||
108
- (float64_is_zero(a) && float64_is_infinity(b))) {
109
- ret = make_float64(DF_NAN);
110
- float_raise(float_flag_invalid, fp_status);
111
- return ret;
112
- }
113
- /*
114
- * If none of the above checks are true and C is a NaN,
115
- * a NaN shall be returned
116
- * If A or B are NaN, a NAN shall be returned.
117
- */
118
- if (float64_is_any_nan(a) ||
119
- float64_is_any_nan(b) ||
120
- float64_is_any_nan(c)) {
121
- if (float64_is_any_nan(a) && (fGETBIT(51, a) == 0)) {
122
- float_raise(float_flag_invalid, fp_status);
123
- }
124
- if (float64_is_any_nan(b) && (fGETBIT(51, b) == 0)) {
125
- float_raise(float_flag_invalid, fp_status);
126
- }
127
- if (float64_is_any_nan(c) && (fGETBIT(51, c) == 0)) {
128
- float_raise(float_flag_invalid, fp_status);
129
- }
130
- ret = make_float64(DF_NAN);
131
- return ret;
132
- }
133
- /*
134
- * We have checked for adding opposite-signed infinities.
135
- * Other infinities return infinity with the correct sign
136
- */
137
- if (float64_is_infinity(c)) {
138
- ret = infinite_float64(c_sign);
139
- return ret;
140
- }
141
- if (float64_is_infinity(a) || float64_is_infinity(b)) {
142
- ret = infinite_float64(a_sign ^ b_sign);
143
- return ret;
144
- }
145
- g_assert_not_reached();
146
-}
147
-
148
-static float32 special_fmaf(float32 a, float32 b, float32 c,
149
- float_status *fp_status)
150
-{
151
- float64 aa, bb, cc;
152
- aa = float32_to_float64(a, fp_status);
153
- bb = float32_to_float64(b, fp_status);
154
- cc = float32_to_float64(c, fp_status);
155
- return float64_to_float32(special_fma(aa, bb, cc, fp_status), fp_status);
156
-}
157
-
158
-float32 internal_fmafx(float32 a, float32 b, float32 c, int scale,
159
- float_status *fp_status)
160
-{
161
- Accum prod;
162
- Accum acc;
163
- Accum result;
164
- accum_init(&prod);
165
- accum_init(&acc);
166
- accum_init(&result);
167
-
168
- uint8_t a_sign = float32_is_neg(a);
169
- uint8_t b_sign = float32_is_neg(b);
170
- uint8_t c_sign = float32_is_neg(c);
171
- if (float32_is_infinity(a) ||
172
- float32_is_infinity(b) ||
173
- float32_is_infinity(c)) {
174
- return special_fmaf(a, b, c, fp_status);
175
- }
176
- if (float32_is_any_nan(a) ||
177
- float32_is_any_nan(b) ||
178
- float32_is_any_nan(c)) {
179
- return special_fmaf(a, b, c, fp_status);
180
- }
181
- if ((scale == 0) && (float32_is_zero(a) || float32_is_zero(b))) {
182
- float32 tmp = float32_mul(a, b, fp_status);
183
- tmp = float32_add(tmp, c, fp_status);
184
- return tmp;
185
- }
186
-
187
- /* (a * 2**b) * (c * 2**d) == a*c * 2**(b+d) */
188
- prod.mant = int128_mul_6464(float32_getmant(a), float32_getmant(b));
189
-
190
- /*
191
- * Note: extracting the mantissa into an int is multiplying by
192
- * 2**23, so adjust here
193
- */
194
- prod.exp = float32_getexp(a) + float32_getexp(b) - SF_BIAS - 23;
195
- prod.sign = a_sign ^ b_sign;
196
- if (float32_is_zero(a) || float32_is_zero(b)) {
197
- prod.exp = -2 * WAY_BIG_EXP;
198
- }
199
- if ((scale > 0) && float32_is_denormal(c)) {
200
- acc.mant = int128_mul_6464(0, 0);
201
- acc.exp = -WAY_BIG_EXP;
202
- acc.sign = c_sign;
203
- acc.sticky = 1;
204
- result = accum_add(prod, acc);
205
- } else if (!float32_is_zero(c)) {
206
- acc.mant = int128_mul_6464(float32_getmant(c), 1);
207
- acc.exp = float32_getexp(c);
208
- acc.sign = c_sign;
209
- result = accum_add(prod, acc);
210
- } else {
211
- result = prod;
212
- }
213
- result.exp += scale;
214
- return accum_round_float32(result, fp_status);
215
-}
216
217
float64 internal_mpyhh(float64 a, float64 b,
218
unsigned long long int accumulated,
92
--
219
--
93
2.25.1
220
2.43.0
94
95
diff view generated by jsdifflib
1
We do not need or want to be allocating page sized quanta.
1
This massive macro is now only used once.
2
Expand it for use only by float64.
2
3
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
4
Reviewed-by: Stefan Weil <sw@weilnetz.de>
5
Message-Id: <20201018164836.1149452-1-richard.henderson@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
6
---
9
util/oslib-win32.c | 11 ++++-------
7
target/hexagon/fma_emu.c | 255 +++++++++++++++++++--------------------
10
1 file changed, 4 insertions(+), 7 deletions(-)
8
1 file changed, 127 insertions(+), 128 deletions(-)
11
9
12
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
10
diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c
13
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
14
--- a/util/oslib-win32.c
12
--- a/target/hexagon/fma_emu.c
15
+++ b/util/oslib-win32.c
13
+++ b/target/hexagon/fma_emu.c
16
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ float32 infinite_float32(uint8_t sign)
17
#include "trace.h"
18
#include "qemu/sockets.h"
19
#include "qemu/cutils.h"
20
+#include <malloc.h>
21
22
/* this must come after including "trace.h" */
23
#include <shlobj.h>
24
@@ -XXX,XX +XXX,XX @@ void *qemu_try_memalign(size_t alignment, size_t size)
25
{
26
void *ptr;
27
28
- if (!size) {
29
- abort();
30
- }
31
- ptr = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
32
+ g_assert(size != 0);
33
+ ptr = _aligned_malloc(alignment, size);
34
trace_qemu_memalign(alignment, size, ptr);
35
return ptr;
36
}
15
}
37
@@ -XXX,XX +XXX,XX @@ void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared)
16
38
void qemu_vfree(void *ptr)
17
/* Return a maximum finite value with the requested sign */
39
{
18
-#define GEN_XF_ROUND(SUFFIX, MANTBITS, INF_EXP, INTERNAL_TYPE) \
40
trace_qemu_vfree(ptr);
19
-static SUFFIX accum_round_##SUFFIX(Accum a, float_status * fp_status) \
41
- if (ptr) {
20
-{ \
42
- VirtualFree(ptr, 0, MEM_RELEASE);
21
- if ((int128_gethi(a.mant) == 0) && (int128_getlo(a.mant) == 0) \
43
- }
22
- && ((a.guard | a.round | a.sticky) == 0)) { \
44
+ _aligned_free(ptr);
23
- /* result zero */ \
24
- switch (fp_status->float_rounding_mode) { \
25
- case float_round_down: \
26
- return zero_##SUFFIX(1); \
27
- default: \
28
- return zero_##SUFFIX(0); \
29
- } \
30
- } \
31
- /* Normalize right */ \
32
- /* We want MANTBITS bits of mantissa plus the leading one. */ \
33
- /* That means that we want MANTBITS+1 bits, or 0x000000000000FF_FFFF */ \
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;
45
}
271
}
46
272
47
void qemu_anon_ram_free(void *ptr, size_t size)
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)
48
--
278
--
49
2.25.1
279
2.43.0
50
51
diff view generated by jsdifflib
1
This fixes the build for older ppc64 kernel headers.
1
This structure, with bitfields, is incorrect for big-endian.
2
Use the existing float32_getexp_raw which uses extract32.
2
3
3
Fixes: 6addf06a3c4
4
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
4
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
6
---
8
linux-user/ioctls.h | 2 ++
7
target/hexagon/fma_emu.c | 16 +++-------------
9
1 file changed, 2 insertions(+)
8
1 file changed, 3 insertions(+), 13 deletions(-)
10
9
11
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
10
diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c
12
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
13
--- a/linux-user/ioctls.h
12
--- a/target/hexagon/fma_emu.c
14
+++ b/linux-user/ioctls.h
13
+++ b/target/hexagon/fma_emu.c
15
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ typedef union {
16
IOCTL(TUNSETQUEUE, IOC_W, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
15
};
17
IOCTL(TUNSETIFINDEX , IOC_W, MK_PTR(TYPE_INT))
16
} Double;
18
/* TUNGETFILTER is not supported: see TUNATTACHFILTER. */
17
19
+#ifdef TUNSETVNETLE
18
-typedef union {
20
IOCTL(TUNSETVNETLE, IOC_W, MK_PTR(TYPE_INT))
19
- float f;
21
IOCTL(TUNGETVNETLE, IOC_R, MK_PTR(TYPE_INT))
20
- uint32_t i;
22
+#endif
21
- struct {
23
#ifdef TUNSETVNETBE
22
- uint32_t mant:23;
24
IOCTL(TUNSETVNETBE, IOC_W, MK_PTR(TYPE_INT))
23
- uint32_t exp:8;
25
IOCTL(TUNGETVNETBE, IOC_R, MK_PTR(TYPE_INT))
24
- uint32_t sign:1;
25
- };
26
-} Float;
27
-
28
static uint64_t float64_getmant(float64 f64)
29
{
30
Double a = { .i = f64 };
31
@@ -XXX,XX +XXX,XX @@ int32_t float64_getexp(float64 f64)
32
33
int32_t float32_getexp(float32 f32)
34
{
35
- Float a = { .i = f32 };
36
+ int exp = float32_getexp_raw(f32);
37
if (float32_is_normal(f32)) {
38
- return a.exp;
39
+ return exp;
40
}
41
if (float32_is_denormal(f32)) {
42
- return a.exp + 1;
43
+ return exp + 1;
44
}
45
return -1;
46
}
26
--
47
--
27
2.25.1
48
2.43.0
28
29
diff view generated by jsdifflib
1
Change TCGLabel.u.value_ptr to const, and initialize it with
1
This structure, with bitfields, is incorrect for big-endian.
2
tcg_splitwx_to_rx. Propagate const through tcg/host/ only
2
Use extract64 and deposit64 instead.
3
as far as needed to avoid errors from the value_ptr change.
4
3
5
Reviewed-by: Joelle van Dyne <j@getutm.app>
4
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
6
---
8
include/tcg/tcg.h | 2 +-
7
target/hexagon/fma_emu.c | 46 ++++++++++++++--------------------------
9
tcg/tcg.c | 2 +-
8
1 file changed, 16 insertions(+), 30 deletions(-)
10
tcg/aarch64/tcg-target.c.inc | 2 +-
11
tcg/arm/tcg-target.c.inc | 2 +-
12
tcg/mips/tcg-target.c.inc | 5 +++--
13
tcg/ppc/tcg-target.c.inc | 4 ++--
14
tcg/s390/tcg-target.c.inc | 2 +-
15
7 files changed, 10 insertions(+), 9 deletions(-)
16
9
17
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
10
diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c
18
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
19
--- a/include/tcg/tcg.h
12
--- a/target/hexagon/fma_emu.c
20
+++ b/include/tcg/tcg.h
13
+++ b/target/hexagon/fma_emu.c
21
@@ -XXX,XX +XXX,XX @@ struct TCGLabel {
14
@@ -XXX,XX +XXX,XX @@
22
unsigned refs : 16;
15
23
union {
16
#define WAY_BIG_EXP 4096
24
uintptr_t value;
17
25
- tcg_insn_unit *value_ptr;
18
-typedef union {
26
+ const tcg_insn_unit *value_ptr;
19
- double f;
27
} u;
20
- uint64_t i;
28
QSIMPLEQ_HEAD(, TCGRelocation) relocs;
21
- struct {
29
QSIMPLEQ_ENTRY(TCGLabel) next;
22
- uint64_t mant:52;
30
diff --git a/tcg/tcg.c b/tcg/tcg.c
23
- uint64_t exp:11;
31
index XXXXXXX..XXXXXXX 100644
24
- uint64_t sign:1;
32
--- a/tcg/tcg.c
25
- };
33
+++ b/tcg/tcg.c
26
-} Double;
34
@@ -XXX,XX +XXX,XX @@ static void tcg_out_label(TCGContext *s, TCGLabel *l, tcg_insn_unit *ptr)
27
-
28
static uint64_t float64_getmant(float64 f64)
35
{
29
{
36
tcg_debug_assert(!l->has_value);
30
- Double a = { .i = f64 };
37
l->has_value = 1;
31
+ uint64_t mant = extract64(f64, 0, 52);
38
- l->u.value_ptr = ptr;
32
if (float64_is_normal(f64)) {
39
+ l->u.value_ptr = tcg_splitwx_to_rx(ptr);
33
- return a.mant | 1ULL << 52;
34
+ return mant | 1ULL << 52;
35
}
36
if (float64_is_zero(f64)) {
37
return 0;
38
}
39
if (float64_is_denormal(f64)) {
40
- return a.mant;
41
+ return mant;
42
}
43
return ~0ULL;
40
}
44
}
41
45
42
TCGLabel *gen_new_label(void)
46
int32_t float64_getexp(float64 f64)
43
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
47
{
44
index XXXXXXX..XXXXXXX 100644
48
- Double a = { .i = f64 };
45
--- a/tcg/aarch64/tcg-target.c.inc
49
+ int exp = extract64(f64, 52, 11);
46
+++ b/tcg/aarch64/tcg-target.c.inc
50
if (float64_is_normal(f64)) {
47
@@ -XXX,XX +XXX,XX @@ static void tcg_out_cmp(TCGContext *s, TCGType ext, TCGReg a,
51
- return a.exp;
52
+ return exp;
48
}
53
}
54
if (float64_is_denormal(f64)) {
55
- return a.exp + 1;
56
+ return exp + 1;
57
}
58
return -1;
49
}
59
}
50
60
@@ -XXX,XX +XXX,XX @@ float32 infinite_float32(uint8_t sign)
51
-static inline void tcg_out_goto(TCGContext *s, tcg_insn_unit *target)
61
/* Return a maximum finite value with the requested sign */
52
+static void tcg_out_goto(TCGContext *s, const tcg_insn_unit *target)
62
static float64 accum_round_float64(Accum a, float_status *fp_status)
53
{
63
{
54
ptrdiff_t offset = target - s->code_ptr;
64
+ uint64_t ret;
55
tcg_debug_assert(offset == sextract64(offset, 0, 26));
65
+
56
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
66
if ((int128_gethi(a.mant) == 0) && (int128_getlo(a.mant) == 0)
57
index XXXXXXX..XXXXXXX 100644
67
&& ((a.guard | a.round | a.sticky) == 0)) {
58
--- a/tcg/arm/tcg-target.c.inc
68
/* result zero */
59
+++ b/tcg/arm/tcg-target.c.inc
69
@@ -XXX,XX +XXX,XX @@ static float64 accum_round_float64(Accum a, float_status *fp_status)
60
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_st8(TCGContext *s, int cond,
70
}
61
* with the code buffer limited to 16MB we wouldn't need the long case.
71
}
62
* But we also use it for the tail-call to the qemu_ld/st helpers, which does.
72
/* Underflow? */
63
*/
73
- if (int128_getlo(a.mant) & (1ULL << DF_MANTBITS)) {
64
-static void tcg_out_goto(TCGContext *s, int cond, tcg_insn_unit *addr)
74
+ ret = int128_getlo(a.mant);
65
+static void tcg_out_goto(TCGContext *s, int cond, const tcg_insn_unit *addr)
75
+ if (ret & (1ULL << DF_MANTBITS)) {
66
{
76
/* Leading one means: No, we're normal. So, we should be done... */
67
intptr_t addri = (intptr_t)addr;
77
- Double ret;
68
ptrdiff_t disp = tcg_pcrel_diff(s, addr);
78
- ret.i = 0;
69
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
79
- ret.sign = a.sign;
70
index XXXXXXX..XXXXXXX 100644
80
- ret.exp = a.exp;
71
--- a/tcg/mips/tcg-target.c.inc
81
- ret.mant = int128_getlo(a.mant);
72
+++ b/tcg/mips/tcg-target.c.inc
82
- return ret.i;
73
@@ -XXX,XX +XXX,XX @@ static tcg_insn_unit *bswap32_addr;
83
+ ret = deposit64(ret, 52, 11, a.exp);
74
static tcg_insn_unit *bswap32u_addr;
84
+ } else {
75
static tcg_insn_unit *bswap64_addr;
85
+ assert(a.exp == 1);
76
86
+ ret = deposit64(ret, 52, 11, 0);
77
-static inline uint32_t reloc_pc16_val(tcg_insn_unit *pc, tcg_insn_unit *target)
87
}
78
+static inline uint32_t reloc_pc16_val(tcg_insn_unit *pc,
88
- assert(a.exp == 1);
79
+ const tcg_insn_unit *target)
89
- Double ret;
80
{
90
- ret.i = 0;
81
/* Let the compiler perform the right-shift as part of the arithmetic. */
91
- ret.sign = a.sign;
82
ptrdiff_t disp = target - (pc + 1);
92
- ret.exp = 0;
83
@@ -XXX,XX +XXX,XX @@ static inline uint32_t reloc_pc16_val(tcg_insn_unit *pc, tcg_insn_unit *target)
93
- ret.mant = int128_getlo(a.mant);
84
return disp & 0xffff;
94
- return ret.i;
95
+ ret = deposit64(ret, 63, 1, a.sign);
96
+ return ret;
85
}
97
}
86
98
87
-static inline void reloc_pc16(tcg_insn_unit *pc, tcg_insn_unit *target)
99
float64 internal_mpyhh(float64 a, float64 b,
88
+static inline void reloc_pc16(tcg_insn_unit *pc, const tcg_insn_unit *target)
89
{
90
*pc = deposit32(*pc, 0, 16, reloc_pc16_val(pc, target));
91
}
92
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
93
index XXXXXXX..XXXXXXX 100644
94
--- a/tcg/ppc/tcg-target.c.inc
95
+++ b/tcg/ppc/tcg-target.c.inc
96
@@ -XXX,XX +XXX,XX @@ static inline bool in_range_b(tcg_target_long target)
97
return target == sextract64(target, 0, 26);
98
}
99
100
-static uint32_t reloc_pc24_val(tcg_insn_unit *pc, tcg_insn_unit *target)
101
+static uint32_t reloc_pc24_val(tcg_insn_unit *pc, const tcg_insn_unit *target)
102
{
103
ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
104
tcg_debug_assert(in_range_b(disp));
105
@@ -XXX,XX +XXX,XX @@ static bool reloc_pc24(tcg_insn_unit *pc, tcg_insn_unit *target)
106
return false;
107
}
108
109
-static uint16_t reloc_pc14_val(tcg_insn_unit *pc, tcg_insn_unit *target)
110
+static uint16_t reloc_pc14_val(tcg_insn_unit *pc, const tcg_insn_unit *target)
111
{
112
ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
113
tcg_debug_assert(disp == (int16_t) disp);
114
diff --git a/tcg/s390/tcg-target.c.inc b/tcg/s390/tcg-target.c.inc
115
index XXXXXXX..XXXXXXX 100644
116
--- a/tcg/s390/tcg-target.c.inc
117
+++ b/tcg/s390/tcg-target.c.inc
118
@@ -XXX,XX +XXX,XX @@ static void tgen_extract(TCGContext *s, TCGReg dest, TCGReg src,
119
tcg_out_risbg(s, dest, src, 64 - len, 63, 64 - ofs, 1);
120
}
121
122
-static void tgen_gotoi(TCGContext *s, int cc, tcg_insn_unit *dest)
123
+static void tgen_gotoi(TCGContext *s, int cc, const tcg_insn_unit *dest)
124
{
125
ptrdiff_t off = dest - s->code_ptr;
126
if (off == (int16_t)off) {
127
--
100
--
128
2.25.1
101
2.43.0
129
130
diff view generated by jsdifflib
1
This target was not updated with 7ecd02a06f8, and so did
1
No need to open-code 64x64->128-bit multiplication.
2
not allow re-compilation with relocation overflow.
3
2
4
Remove reloc_26 and reloc_26_val as unused.
3
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
5
---
8
tcg/mips/tcg-target.c.inc | 53 ++++++++++++++-------------------------
6
target/hexagon/fma_emu.c | 32 +++-----------------------------
9
1 file changed, 19 insertions(+), 34 deletions(-)
7
1 file changed, 3 insertions(+), 29 deletions(-)
10
8
11
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
9
diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c
12
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
13
--- a/tcg/mips/tcg-target.c.inc
11
--- a/target/hexagon/fma_emu.c
14
+++ b/tcg/mips/tcg-target.c.inc
12
+++ b/target/hexagon/fma_emu.c
15
@@ -XXX,XX +XXX,XX @@ static tcg_insn_unit *bswap32_addr;
13
@@ -XXX,XX +XXX,XX @@ int32_t float32_getexp(float32 f32)
16
static tcg_insn_unit *bswap32u_addr;
14
return -1;
17
static tcg_insn_unit *bswap64_addr;
15
}
18
16
19
-static inline uint32_t reloc_pc16_val(tcg_insn_unit *pc,
17
-static uint32_t int128_getw0(Int128 x)
20
- const tcg_insn_unit *target)
18
-{
21
+static bool reloc_pc16(tcg_insn_unit *pc, const tcg_insn_unit *target)
19
- return int128_getlo(x);
22
{
23
/* Let the compiler perform the right-shift as part of the arithmetic. */
24
ptrdiff_t disp = target - (pc + 1);
25
- tcg_debug_assert(disp == (int16_t)disp);
26
- return disp & 0xffff;
27
-}
20
-}
28
-
21
-
29
-static inline void reloc_pc16(tcg_insn_unit *pc, const tcg_insn_unit *target)
22
-static uint32_t int128_getw1(Int128 x)
30
-{
23
-{
31
- *pc = deposit32(*pc, 0, 16, reloc_pc16_val(pc, target));
24
- return int128_getlo(x) >> 32;
32
-}
25
-}
33
-
26
-
34
-static inline uint32_t reloc_26_val(tcg_insn_unit *pc, tcg_insn_unit *target)
27
static Int128 int128_mul_6464(uint64_t ai, uint64_t bi)
35
-{
28
{
36
- tcg_debug_assert((((uintptr_t)pc ^ (uintptr_t)target) & 0xf0000000) == 0);
29
- Int128 a, b;
37
- return ((uintptr_t)target >> 2) & 0x3ffffff;
30
- uint64_t pp0, pp1a, pp1b, pp1s, pp2;
38
-}
31
+ uint64_t l, h;
32
33
- a = int128_make64(ai);
34
- b = int128_make64(bi);
35
- pp0 = (uint64_t)int128_getw0(a) * (uint64_t)int128_getw0(b);
36
- pp1a = (uint64_t)int128_getw1(a) * (uint64_t)int128_getw0(b);
37
- pp1b = (uint64_t)int128_getw1(b) * (uint64_t)int128_getw0(a);
38
- pp2 = (uint64_t)int128_getw1(a) * (uint64_t)int128_getw1(b);
39
-
39
-
40
-static inline void reloc_26(tcg_insn_unit *pc, tcg_insn_unit *target)
40
- pp1s = pp1a + pp1b;
41
-{
41
- if ((pp1s < pp1a) || (pp1s < pp1b)) {
42
- *pc = deposit32(*pc, 0, 26, reloc_26_val(pc, target));
42
- pp2 += (1ULL << 32);
43
+ if (disp == (int16_t)disp) {
43
- }
44
+ *pc = deposit32(*pc, 0, 16, disp);
44
- uint64_t ret_low = pp0 + (pp1s << 32);
45
+ return true;
45
- if ((ret_low < pp0) || (ret_low < (pp1s << 32))) {
46
+ }
46
- pp2 += 1;
47
+ return false;
47
- }
48
-
49
- return int128_make128(ret_low, pp2 + (pp1s >> 32));
50
+ mulu64(&l, &h, ai, bi);
51
+ return int128_make128(l, h);
48
}
52
}
49
53
50
static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
54
static Int128 int128_sub_borrow(Int128 a, Int128 b, int borrow)
51
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
52
{
53
tcg_debug_assert(type == R_MIPS_PC16);
54
tcg_debug_assert(addend == 0);
55
- reloc_pc16(code_ptr, (tcg_insn_unit *)value);
56
- return true;
57
+ return reloc_pc16(code_ptr, (const tcg_insn_unit *)value);
58
}
59
60
#define TCG_CT_CONST_ZERO 0x100
61
@@ -XXX,XX +XXX,XX @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
62
}
63
64
tcg_out_opc_br(s, b_opc, arg1, arg2);
65
- if (l->has_value) {
66
- reloc_pc16(s->code_ptr - 1, l->u.value_ptr);
67
- } else {
68
- tcg_out_reloc(s, s->code_ptr - 1, R_MIPS_PC16, l, 0);
69
- }
70
+ tcg_out_reloc(s, s->code_ptr - 1, R_MIPS_PC16, l, 0);
71
tcg_out_nop(s);
72
}
73
74
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
75
int i;
76
77
/* resolve label address */
78
- reloc_pc16(l->label_ptr[0], s->code_ptr);
79
- if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
80
- reloc_pc16(l->label_ptr[1], s->code_ptr);
81
+ if (!reloc_pc16(l->label_ptr[0], s->code_ptr)
82
+ || (TCG_TARGET_REG_BITS < TARGET_LONG_BITS
83
+ && !reloc_pc16(l->label_ptr[1], s->code_ptr))) {
84
+ return false;
85
}
86
87
i = 1;
88
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
89
}
90
91
tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
92
- reloc_pc16(s->code_ptr - 1, l->raddr);
93
+ if (!reloc_pc16(s->code_ptr - 1, l->raddr)) {
94
+ return false;
95
+ }
96
97
/* delay slot */
98
if (TCG_TARGET_REG_BITS == 64 && l->type == TCG_TYPE_I32) {
99
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
100
int i;
101
102
/* resolve label address */
103
- reloc_pc16(l->label_ptr[0], s->code_ptr);
104
- if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
105
- reloc_pc16(l->label_ptr[1], s->code_ptr);
106
+ if (!reloc_pc16(l->label_ptr[0], s->code_ptr)
107
+ || (TCG_TARGET_REG_BITS < TARGET_LONG_BITS
108
+ && !reloc_pc16(l->label_ptr[1], s->code_ptr))) {
109
+ return false;
110
}
111
112
i = 1;
113
--
55
--
114
2.25.1
56
2.43.0
115
116
diff view generated by jsdifflib
1
A typo generated a branch-and-link insn instead of plain branch.
1
Initialize x with accumulated via direct assignment,
2
rather than multiplying by 1.
2
3
3
Reviewed-by: Joelle van Dyne <j@getutm.app>
4
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
---
6
tcg/aarch64/tcg-target.c.inc | 2 +-
7
target/hexagon/fma_emu.c | 2 +-
7
1 file changed, 1 insertion(+), 1 deletion(-)
8
1 file changed, 1 insertion(+), 1 deletion(-)
8
9
9
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
10
diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c
10
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/aarch64/tcg-target.c.inc
12
--- a/target/hexagon/fma_emu.c
12
+++ b/tcg/aarch64/tcg-target.c.inc
13
+++ b/target/hexagon/fma_emu.c
13
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_goto_long(TCGContext *s, tcg_insn_unit *target)
14
@@ -XXX,XX +XXX,XX @@ float64 internal_mpyhh(float64 a, float64 b,
14
{
15
float64_is_infinity(b)) {
15
ptrdiff_t offset = target - s->code_ptr;
16
return float64_mul(a, b, fp_status);
16
if (offset == sextract64(offset, 0, 26)) {
17
}
17
- tcg_out_insn(s, 3206, BL, offset);
18
- x.mant = int128_mul_6464(accumulated, 1);
18
+ tcg_out_insn(s, 3206, B, offset);
19
+ x.mant = int128_make64(accumulated);
19
} else {
20
x.sticky = sticky;
20
tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, (intptr_t)target);
21
prod = fGETUWORD(1, float64_getmant(a)) * fGETUWORD(1, float64_getmant(b));
21
tcg_out_insn(s, 3207, BR, TCG_REG_TMP);
22
x.mant = int128_add(x.mant, int128_mul_6464(prod, 0x100000000ULL));
22
--
23
--
23
2.25.1
24
2.43.0
24
25
diff view generated by jsdifflib
1
There is nothing within the translators that ought to be
1
Convert all targets simultaneously, as the gen_intermediate_code
2
changing the TranslationBlock data, so make it const.
2
function disappears from the target. While there are possible
3
workarounds, they're larger than simply performing the conversion.
3
4
4
This does not actually use the read-only copy of the
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
data structure that exists within the rx region.
6
7
Reviewed-by: Joelle van Dyne <j@getutm.app>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.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/hw/core/cpu.h | 3 ++-
8
include/exec/translator.h | 14 --------------
12
target/arm/cpu.c | 3 ++-
9
include/hw/core/tcg-cpu-ops.h | 13 +++++++++++++
13
target/avr/cpu.c | 3 ++-
10
target/alpha/cpu.h | 2 ++
14
target/hppa/cpu.c | 3 ++-
11
target/arm/internals.h | 2 ++
15
target/i386/tcg/tcg-cpu.c | 3 ++-
12
target/avr/cpu.h | 2 ++
16
target/microblaze/cpu.c | 3 ++-
13
target/hexagon/cpu.h | 2 ++
17
target/mips/cpu.c | 3 ++-
14
target/hppa/cpu.h | 2 ++
18
target/riscv/cpu.c | 3 ++-
15
target/i386/tcg/helper-tcg.h | 2 ++
19
target/rx/cpu.c | 3 ++-
16
target/loongarch/internals.h | 2 ++
20
target/sh4/cpu.c | 3 ++-
17
target/m68k/cpu.h | 2 ++
21
target/sparc/cpu.c | 3 ++-
18
target/microblaze/cpu.h | 2 ++
22
target/tricore/cpu.c | 2 +-
19
target/mips/tcg/tcg-internal.h | 2 ++
23
12 files changed, 23 insertions(+), 12 deletions(-)
20
target/openrisc/cpu.h | 2 ++
21
target/ppc/cpu.h | 2 ++
22
target/riscv/cpu.h | 3 +++
23
target/rx/cpu.h | 2 ++
24
target/s390x/s390x-internal.h | 2 ++
25
target/sh4/cpu.h | 2 ++
26
target/sparc/cpu.h | 2 ++
27
target/tricore/cpu.h | 2 ++
28
target/xtensa/cpu.h | 2 ++
29
accel/tcg/cpu-exec.c | 8 +++++---
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(-)
24
71
25
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
72
diff --git a/include/exec/translator.h b/include/exec/translator.h
26
index XXXXXXX..XXXXXXX 100644
73
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/core/cpu.h
74
--- a/include/exec/translator.h
28
+++ b/include/hw/core/cpu.h
75
+++ b/include/exec/translator.h
29
@@ -XXX,XX +XXX,XX @@ struct CPUClass {
76
@@ -XXX,XX +XXX,XX @@
30
void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list,
77
#include "qemu/bswap.h"
31
Error **errp);
78
#include "exec/vaddr.h"
32
void (*set_pc)(CPUState *cpu, vaddr value);
79
33
- void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb);
80
-/**
34
+ void (*synchronize_from_tb)(CPUState *cpu,
81
- * gen_intermediate_code
35
+ const struct TranslationBlock *tb);
82
- * @cpu: cpu context
36
bool (*tlb_fill)(CPUState *cpu, vaddr address, int size,
83
- * @tb: translation block
37
MMUAccessType access_type, int mmu_idx,
84
- * @max_insns: max number of instructions to translate
38
bool probe, uintptr_t retaddr);
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
-
94
/**
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
428
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
429
index XXXXXXX..XXXXXXX 100644
430
--- a/target/alpha/translate.c
431
+++ b/target/alpha/translate.c
432
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps alpha_tr_ops = {
433
.tb_stop = alpha_tr_tb_stop,
434
};
435
436
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
437
- vaddr pc, void *host_pc)
438
+void alpha_translate_code(CPUState *cpu, TranslationBlock *tb,
439
+ int *max_insns, vaddr pc, void *host_pc)
440
{
441
DisasContext dc;
442
translator_loop(cpu, tb, max_insns, pc, host_pc, &alpha_tr_ops, &dc.base);
39
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
443
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
40
index XXXXXXX..XXXXXXX 100644
444
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/cpu.c
445
--- a/target/arm/cpu.c
42
+++ b/target/arm/cpu.c
446
+++ b/target/arm/cpu.c
43
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_set_pc(CPUState *cs, vaddr value)
447
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps arm_sysemu_ops = {
44
}
448
#ifdef CONFIG_TCG
45
}
449
static const TCGCPUOps arm_tcg_ops = {
46
450
.initialize = arm_translate_init,
47
-static void arm_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
451
+ .translate_code = arm_translate_code,
48
+static void arm_cpu_synchronize_from_tb(CPUState *cs,
452
.synchronize_from_tb = arm_cpu_synchronize_from_tb,
49
+ const TranslationBlock *tb)
453
.debug_excp_handler = arm_debug_excp_handler,
50
{
454
.restore_state_to_opc = arm_restore_state_to_opc,
51
ARMCPU *cpu = ARM_CPU(cs);
455
diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c
52
CPUARMState *env = &cpu->env;
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,
467
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
468
index XXXXXXX..XXXXXXX 100644
469
--- a/target/arm/tcg/translate.c
470
+++ b/target/arm/tcg/translate.c
471
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps thumb_translator_ops = {
472
.tb_stop = arm_tr_tb_stop,
473
};
474
475
-/* generate intermediate code for basic block 'tb'. */
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)
480
{
481
DisasContext dc = { };
482
const TranslatorOps *ops = &arm_translator_ops;
53
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
483
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
54
index XXXXXXX..XXXXXXX 100644
484
index XXXXXXX..XXXXXXX 100644
55
--- a/target/avr/cpu.c
485
--- a/target/avr/cpu.c
56
+++ b/target/avr/cpu.c
486
+++ b/target/avr/cpu.c
57
@@ -XXX,XX +XXX,XX @@ static bool avr_cpu_has_work(CPUState *cs)
487
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps avr_sysemu_ops = {
58
&& cpu_interrupts_enabled(env);
488
59
}
489
static const TCGCPUOps avr_tcg_ops = {
60
490
.initialize = avr_cpu_tcg_init,
61
-static void avr_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
491
+ .translate_code = avr_cpu_translate_code,
62
+static void avr_cpu_synchronize_from_tb(CPUState *cs,
492
.synchronize_from_tb = avr_cpu_synchronize_from_tb,
63
+ const TranslationBlock *tb)
493
.restore_state_to_opc = avr_restore_state_to_opc,
64
{
494
.cpu_exec_interrupt = avr_cpu_exec_interrupt,
65
AVRCPU *cpu = AVR_CPU(cs);
495
diff --git a/target/avr/translate.c b/target/avr/translate.c
66
CPUAVRState *env = &cpu->env;
496
index XXXXXXX..XXXXXXX 100644
497
--- a/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
*/
508
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps avr_tr_ops = {
509
.tb_stop = avr_tr_tb_stop,
510
};
511
512
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
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)
516
{
517
DisasContext dc = { };
518
translator_loop(cs, tb, max_insns, pc, host_pc, &avr_tr_ops, &dc.base);
519
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
520
index XXXXXXX..XXXXXXX 100644
521
--- a/target/hexagon/cpu.c
522
+++ b/target/hexagon/cpu.c
523
@@ -XXX,XX +XXX,XX @@ static void hexagon_cpu_init(Object *obj)
524
525
static const TCGCPUOps hexagon_tcg_ops = {
526
.initialize = hexagon_translate_init,
527
+ .translate_code = hexagon_translate_code,
528
.synchronize_from_tb = hexagon_cpu_synchronize_from_tb,
529
.restore_state_to_opc = hexagon_restore_state_to_opc,
530
};
531
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
532
index XXXXXXX..XXXXXXX 100644
533
--- a/target/hexagon/translate.c
534
+++ b/target/hexagon/translate.c
535
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps hexagon_tr_ops = {
536
.tb_stop = hexagon_tr_tb_stop,
537
};
538
539
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
540
- vaddr pc, void *host_pc)
541
+void hexagon_translate_code(CPUState *cs, TranslationBlock *tb,
542
+ int *max_insns, vaddr pc, void *host_pc)
543
{
544
DisasContext ctx;
545
67
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
546
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
68
index XXXXXXX..XXXXXXX 100644
547
index XXXXXXX..XXXXXXX 100644
69
--- a/target/hppa/cpu.c
548
--- a/target/hppa/cpu.c
70
+++ b/target/hppa/cpu.c
549
+++ b/target/hppa/cpu.c
71
@@ -XXX,XX +XXX,XX @@ static void hppa_cpu_set_pc(CPUState *cs, vaddr value)
550
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps hppa_sysemu_ops = {
72
cpu->env.iaoq_b = value + 4;
551
73
}
552
static const TCGCPUOps hppa_tcg_ops = {
74
553
.initialize = hppa_translate_init,
75
-static void hppa_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
554
+ .translate_code = hppa_translate_code,
76
+static void hppa_cpu_synchronize_from_tb(CPUState *cs,
555
.synchronize_from_tb = hppa_cpu_synchronize_from_tb,
77
+ const TranslationBlock *tb)
556
.restore_state_to_opc = hppa_restore_state_to_opc,
78
{
557
79
HPPACPU *cpu = HPPA_CPU(cs);
558
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
80
559
index XXXXXXX..XXXXXXX 100644
560
--- a/target/hppa/translate.c
561
+++ b/target/hppa/translate.c
562
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps hppa_tr_ops = {
563
#endif
564
};
565
566
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
567
- vaddr pc, void *host_pc)
568
+void hppa_translate_code(CPUState *cs, TranslationBlock *tb,
569
+ int *max_insns, vaddr pc, void *host_pc)
570
{
571
DisasContext ctx = { };
572
translator_loop(cs, tb, max_insns, pc, host_pc, &hppa_tr_ops, &ctx.base);
81
diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c
573
diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c
82
index XXXXXXX..XXXXXXX 100644
574
index XXXXXXX..XXXXXXX 100644
83
--- a/target/i386/tcg/tcg-cpu.c
575
--- a/target/i386/tcg/tcg-cpu.c
84
+++ b/target/i386/tcg/tcg-cpu.c
576
+++ b/target/i386/tcg/tcg-cpu.c
85
@@ -XXX,XX +XXX,XX @@ static void x86_cpu_exec_exit(CPUState *cs)
577
@@ -XXX,XX +XXX,XX @@ static bool x86_debug_check_breakpoint(CPUState *cs)
86
env->eflags = cpu_compute_eflags(env);
578
87
}
579
static const TCGCPUOps x86_tcg_ops = {
88
580
.initialize = tcg_x86_init,
89
-static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
581
+ .translate_code = x86_translate_code,
90
+static void x86_cpu_synchronize_from_tb(CPUState *cs,
582
.synchronize_from_tb = x86_cpu_synchronize_from_tb,
91
+ const TranslationBlock *tb)
583
.restore_state_to_opc = x86_restore_state_to_opc,
92
{
584
.cpu_exec_enter = x86_cpu_exec_enter,
93
X86CPU *cpu = X86_CPU(cs);
585
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
94
586
index XXXXXXX..XXXXXXX 100644
587
--- a/target/i386/tcg/translate.c
588
+++ b/target/i386/tcg/translate.c
589
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps i386_tr_ops = {
590
.tb_stop = i386_tr_tb_stop,
591
};
592
593
-/* generate intermediate code for basic block 'tb'. */
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)
598
{
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,
612
613
diff --git a/target/loongarch/tcg/translate.c b/target/loongarch/tcg/translate.c
614
index XXXXXXX..XXXXXXX 100644
615
--- a/target/loongarch/tcg/translate.c
616
+++ b/target/loongarch/tcg/translate.c
617
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps loongarch_tr_ops = {
618
.tb_stop = loongarch_tr_tb_stop,
619
};
620
621
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
622
- vaddr pc, void *host_pc)
623
+void loongarch_translate_code(CPUState *cs, TranslationBlock *tb,
624
+ int *max_insns, vaddr pc, void *host_pc)
625
{
626
DisasContext ctx;
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
640
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
641
index XXXXXXX..XXXXXXX 100644
642
--- a/target/m68k/translate.c
643
+++ b/target/m68k/translate.c
644
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps m68k_tr_ops = {
645
.tb_stop = m68k_tr_tb_stop,
646
};
647
648
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
649
- vaddr pc, void *host_pc)
650
+void m68k_translate_code(CPUState *cpu, TranslationBlock *tb,
651
+ int *max_insns, vaddr pc, void *host_pc)
652
{
653
DisasContext dc;
654
translator_loop(cpu, tb, max_insns, pc, host_pc, &m68k_tr_ops, &dc.base);
95
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
655
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
96
index XXXXXXX..XXXXXXX 100644
656
index XXXXXXX..XXXXXXX 100644
97
--- a/target/microblaze/cpu.c
657
--- a/target/microblaze/cpu.c
98
+++ b/target/microblaze/cpu.c
658
+++ b/target/microblaze/cpu.c
99
@@ -XXX,XX +XXX,XX @@ static void mb_cpu_set_pc(CPUState *cs, vaddr value)
659
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps mb_sysemu_ops = {
100
cpu->env.iflags = 0;
660
101
}
661
static const TCGCPUOps mb_tcg_ops = {
102
662
.initialize = mb_tcg_init,
103
-static void mb_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
663
+ .translate_code = mb_translate_code,
104
+static void mb_cpu_synchronize_from_tb(CPUState *cs,
664
.synchronize_from_tb = mb_cpu_synchronize_from_tb,
105
+ const TranslationBlock *tb)
665
.restore_state_to_opc = mb_restore_state_to_opc,
106
{
666
107
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
667
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
108
668
index XXXXXXX..XXXXXXX 100644
669
--- a/target/microblaze/translate.c
670
+++ b/target/microblaze/translate.c
671
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps mb_tr_ops = {
672
.tb_stop = mb_tr_tb_stop,
673
};
674
675
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
676
- vaddr pc, void *host_pc)
677
+void mb_translate_code(CPUState *cpu, TranslationBlock *tb,
678
+ int *max_insns, vaddr pc, void *host_pc)
679
{
680
DisasContext dc;
681
translator_loop(cpu, tb, max_insns, pc, host_pc, &mb_tr_ops, &dc.base);
109
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
682
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
110
index XXXXXXX..XXXXXXX 100644
683
index XXXXXXX..XXXXXXX 100644
111
--- a/target/mips/cpu.c
684
--- a/target/mips/cpu.c
112
+++ b/target/mips/cpu.c
685
+++ b/target/mips/cpu.c
113
@@ -XXX,XX +XXX,XX @@ static void mips_cpu_set_pc(CPUState *cs, vaddr value)
686
@@ -XXX,XX +XXX,XX @@ static const Property mips_cpu_properties[] = {
114
}
687
#include "hw/core/tcg-cpu-ops.h"
115
}
688
static const TCGCPUOps mips_tcg_ops = {
116
689
.initialize = mips_tcg_init,
117
-static void mips_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
690
+ .translate_code = mips_translate_code,
118
+static void mips_cpu_synchronize_from_tb(CPUState *cs,
691
.synchronize_from_tb = mips_cpu_synchronize_from_tb,
119
+ const TranslationBlock *tb)
692
.restore_state_to_opc = mips_restore_state_to_opc,
120
{
693
121
MIPSCPU *cpu = MIPS_CPU(cs);
694
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
122
CPUMIPSState *env = &cpu->env;
695
index XXXXXXX..XXXXXXX 100644
123
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
696
--- a/target/mips/tcg/translate.c
124
index XXXXXXX..XXXXXXX 100644
697
+++ b/target/mips/tcg/translate.c
125
--- a/target/riscv/cpu.c
698
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps mips_tr_ops = {
126
+++ b/target/riscv/cpu.c
699
.tb_stop = mips_tr_tb_stop,
127
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
700
};
128
env->pc = value;
701
129
}
702
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
130
703
- vaddr pc, void *host_pc)
131
-static void riscv_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
704
+void mips_translate_code(CPUState *cs, TranslationBlock *tb,
132
+static void riscv_cpu_synchronize_from_tb(CPUState *cs,
705
+ int *max_insns, vaddr pc, void *host_pc)
133
+ const TranslationBlock *tb)
706
{
134
{
707
DisasContext ctx;
135
RISCVCPU *cpu = RISCV_CPU(cs);
708
136
CPURISCVState *env = &cpu->env;
709
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
710
index XXXXXXX..XXXXXXX 100644
711
--- a/target/openrisc/cpu.c
712
+++ b/target/openrisc/cpu.c
713
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps openrisc_sysemu_ops = {
714
715
static const TCGCPUOps openrisc_tcg_ops = {
716
.initialize = openrisc_translate_init,
717
+ .translate_code = openrisc_translate_code,
718
.synchronize_from_tb = openrisc_cpu_synchronize_from_tb,
719
.restore_state_to_opc = openrisc_restore_state_to_opc,
720
721
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
722
index XXXXXXX..XXXXXXX 100644
723
--- a/target/openrisc/translate.c
724
+++ b/target/openrisc/translate.c
725
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps openrisc_tr_ops = {
726
.tb_stop = openrisc_tr_tb_stop,
727
};
728
729
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
730
- vaddr pc, void *host_pc)
731
+void openrisc_translate_code(CPUState *cs, TranslationBlock *tb,
732
+ int *max_insns, vaddr pc, void *host_pc)
733
{
734
DisasContext ctx;
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
748
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
749
index XXXXXXX..XXXXXXX 100644
750
--- a/target/ppc/translate.c
751
+++ b/target/ppc/translate.c
752
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps ppc_tr_ops = {
753
.tb_stop = ppc_tr_tb_stop,
754
};
755
756
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
757
- vaddr pc, void *host_pc)
758
+void ppc_translate_code(CPUState *cs, TranslationBlock *tb,
759
+ int *max_insns, vaddr pc, void *host_pc)
760
{
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,
774
775
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
776
index XXXXXXX..XXXXXXX 100644
777
--- a/target/riscv/translate.c
778
+++ b/target/riscv/translate.c
779
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps riscv_tr_ops = {
780
.tb_stop = riscv_tr_tb_stop,
781
};
782
783
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
784
- vaddr pc, void *host_pc)
785
+void riscv_translate_code(CPUState *cs, TranslationBlock *tb,
786
+ int *max_insns, vaddr pc, void *host_pc)
787
{
788
DisasContext ctx;
789
137
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
790
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
138
index XXXXXXX..XXXXXXX 100644
791
index XXXXXXX..XXXXXXX 100644
139
--- a/target/rx/cpu.c
792
--- a/target/rx/cpu.c
140
+++ b/target/rx/cpu.c
793
+++ b/target/rx/cpu.c
141
@@ -XXX,XX +XXX,XX @@ static void rx_cpu_set_pc(CPUState *cs, vaddr value)
794
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps rx_sysemu_ops = {
142
cpu->env.pc = value;
795
143
}
796
static const TCGCPUOps rx_tcg_ops = {
144
797
.initialize = rx_translate_init,
145
-static void rx_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
798
+ .translate_code = rx_translate_code,
146
+static void rx_cpu_synchronize_from_tb(CPUState *cs,
799
.synchronize_from_tb = rx_cpu_synchronize_from_tb,
147
+ const TranslationBlock *tb)
800
.restore_state_to_opc = rx_restore_state_to_opc,
148
{
801
.tlb_fill = rx_cpu_tlb_fill,
149
RXCPU *cpu = RX_CPU(cs);
802
diff --git a/target/rx/translate.c b/target/rx/translate.c
803
index XXXXXXX..XXXXXXX 100644
804
--- a/target/rx/translate.c
805
+++ b/target/rx/translate.c
806
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps rx_tr_ops = {
807
.tb_stop = rx_tr_tb_stop,
808
};
809
810
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
811
- vaddr pc, void *host_pc)
812
+void rx_translate_code(CPUState *cs, TranslationBlock *tb,
813
+ int *max_insns, vaddr pc, void *host_pc)
814
{
815
DisasContext dc;
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
829
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
830
index XXXXXXX..XXXXXXX 100644
831
--- a/target/s390x/tcg/translate.c
832
+++ b/target/s390x/tcg/translate.c
833
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps s390x_tr_ops = {
834
.disas_log = s390x_tr_disas_log,
835
};
836
837
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
838
- vaddr pc, void *host_pc)
839
+void s390x_translate_code(CPUState *cs, TranslationBlock *tb,
840
+ int *max_insns, vaddr pc, void *host_pc)
841
{
842
DisasContext dc;
150
843
151
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
844
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
152
index XXXXXXX..XXXXXXX 100644
845
index XXXXXXX..XXXXXXX 100644
153
--- a/target/sh4/cpu.c
846
--- a/target/sh4/cpu.c
154
+++ b/target/sh4/cpu.c
847
+++ b/target/sh4/cpu.c
155
@@ -XXX,XX +XXX,XX @@ static void superh_cpu_set_pc(CPUState *cs, vaddr value)
848
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps sh4_sysemu_ops = {
156
cpu->env.pc = value;
849
157
}
850
static const TCGCPUOps superh_tcg_ops = {
158
851
.initialize = sh4_translate_init,
159
-static void superh_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
852
+ .translate_code = sh4_translate_code,
160
+static void superh_cpu_synchronize_from_tb(CPUState *cs,
853
.synchronize_from_tb = superh_cpu_synchronize_from_tb,
161
+ const TranslationBlock *tb)
854
.restore_state_to_opc = superh_restore_state_to_opc,
162
{
855
163
SuperHCPU *cpu = SUPERH_CPU(cs);
856
diff --git a/target/sh4/translate.c b/target/sh4/translate.c
857
index XXXXXXX..XXXXXXX 100644
858
--- a/target/sh4/translate.c
859
+++ b/target/sh4/translate.c
860
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps sh4_tr_ops = {
861
.tb_stop = sh4_tr_tb_stop,
862
};
863
864
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
865
- vaddr pc, void *host_pc)
866
+void sh4_translate_code(CPUState *cs, TranslationBlock *tb,
867
+ int *max_insns, vaddr pc, void *host_pc)
868
{
869
DisasContext ctx;
164
870
165
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
871
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
166
index XXXXXXX..XXXXXXX 100644
872
index XXXXXXX..XXXXXXX 100644
167
--- a/target/sparc/cpu.c
873
--- a/target/sparc/cpu.c
168
+++ b/target/sparc/cpu.c
874
+++ b/target/sparc/cpu.c
169
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_set_pc(CPUState *cs, vaddr value)
875
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps sparc_sysemu_ops = {
170
cpu->env.npc = value + 4;
876
171
}
877
static const TCGCPUOps sparc_tcg_ops = {
172
878
.initialize = sparc_tcg_init,
173
-static void sparc_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
879
+ .translate_code = sparc_translate_code,
174
+static void sparc_cpu_synchronize_from_tb(CPUState *cs,
880
.synchronize_from_tb = sparc_cpu_synchronize_from_tb,
175
+ const TranslationBlock *tb)
881
.restore_state_to_opc = sparc_restore_state_to_opc,
176
{
882
177
SPARCCPU *cpu = SPARC_CPU(cs);
883
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
884
index XXXXXXX..XXXXXXX 100644
885
--- a/target/sparc/translate.c
886
+++ b/target/sparc/translate.c
887
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps sparc_tr_ops = {
888
.tb_stop = sparc_tr_tb_stop,
889
};
890
891
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
892
- vaddr pc, void *host_pc)
893
+void sparc_translate_code(CPUState *cs, TranslationBlock *tb,
894
+ int *max_insns, vaddr pc, void *host_pc)
895
{
896
DisasContext dc = {};
178
897
179
diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c
898
diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c
180
index XXXXXXX..XXXXXXX 100644
899
index XXXXXXX..XXXXXXX 100644
181
--- a/target/tricore/cpu.c
900
--- a/target/tricore/cpu.c
182
+++ b/target/tricore/cpu.c
901
+++ b/target/tricore/cpu.c
183
@@ -XXX,XX +XXX,XX @@ static void tricore_cpu_set_pc(CPUState *cs, vaddr value)
902
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps tricore_sysemu_ops = {
184
}
903
185
904
static const TCGCPUOps tricore_tcg_ops = {
186
static void tricore_cpu_synchronize_from_tb(CPUState *cs,
905
.initialize = tricore_tcg_init,
187
- TranslationBlock *tb)
906
+ .translate_code = tricore_translate_code,
188
+ const TranslationBlock *tb)
907
.synchronize_from_tb = tricore_cpu_synchronize_from_tb,
189
{
908
.restore_state_to_opc = tricore_restore_state_to_opc,
190
TriCoreCPU *cpu = TRICORE_CPU(cs);
909
.tlb_fill = tricore_cpu_tlb_fill,
191
CPUTriCoreState *env = &cpu->env;
910
diff --git a/target/tricore/translate.c b/target/tricore/translate.c
911
index XXXXXXX..XXXXXXX 100644
912
--- a/target/tricore/translate.c
913
+++ b/target/tricore/translate.c
914
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps tricore_tr_ops = {
915
.tb_stop = tricore_tr_tb_stop,
916
};
917
918
-
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)
923
{
924
DisasContext ctx;
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
938
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
939
index XXXXXXX..XXXXXXX 100644
940
--- a/target/xtensa/translate.c
941
+++ b/target/xtensa/translate.c
942
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps xtensa_translator_ops = {
943
.tb_stop = xtensa_tr_tb_stop,
944
};
945
946
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
947
- vaddr pc, void *host_pc)
948
+void xtensa_translate_code(CPUState *cpu, TranslationBlock *tb,
949
+ int *max_insns, vaddr pc, void *host_pc)
950
{
951
DisasContext dc = {};
952
translator_loop(cpu, tb, max_insns, pc, host_pc,
192
--
953
--
193
2.25.1
954
2.43.0
194
955
195
956
diff view generated by jsdifflib